【问题标题】:Correct way of Initializing a Vector in VerilogVerilog中初始化向量的正确方法
【发布时间】:2020-06-28 09:13:24
【问题描述】:

这些方式在 Verilog 中初始化向量有什么区别?

reg [3:0] vector = 4'b0000;

reg [3:0] vector = 0;

我在第一次初始化中看到的唯一优势是直接设置每一位。但是在这个例子中将向量设置为零,有区别吗?一种方式比另一种更好吗?

编辑:

我稍微扩展了 mcleod_ideafix 的测试程序来检查一些其他的东西:

module tb;
  reg [15:0] v5, v6, v7, v8, v9, v10;

  initial begin        
    v6 = 1'b0;
    v7 = 1'b1;
    v8 = 2'b1111;
    v9 = 'b1;
    v10 = 6'b11;
    
    $display ("v5(=/)       = %b\nv6(=1'b0)    = %b\nv7(=1'b1)    = %b\nv8(=2'b1111) = %b\nv9(='b1)     = %b\nv10(=6'b11)  = %b", v5, v6, v7, v8, v9, v10);
    $finish;
  end
endmodule

结果:

v5(=/)       = xxxxxxxxxxxxxxxx
v6(=1'b0)    = 0000000000000000
v7(=1'b1)    = 0000000000000001
v8(=2'b1111) = 0000000000000011
v9(='b1)     = 0000000000000001
v10(=6'b11)  = 0000000000000011
  • v5 表明,一个未初始化的变量是 x,因此如预期的那样未定义。

  • v6 设置为 1'b0,因此只有一位应设置为 0,但所有位都设置为 0。

  • 另一方面,v7 设置为 1'b1,只有最低有效位设置为 1。在我看来,只要将变量设置为一个值,所有未给定的前导位都将设置为零。

  • v8 显示,' 之前的数字限制了 'b' 之后给定数字的大小。 设置 v8 给了我一些警告:

    test.v:7:警告:为大小的二进制常量提供了额外的数字。 test.v:7:警告:数字常量被截断为 2 位。

根据给定的警告,我不认为,这个“功能”是有意的,所以我总是更喜欢:

reg [3:0] vector = 2'b10
  • 我认为删除数字的长度 (v9) 更省钱,因为在更改数字的值时不可能忘记更新长度。将长度写在数字中的唯一好处是对长度进行交叉检查。因此,如果将长度设置为较小的值的实际长度,我会收到警告。另一方面,将长度设置为长于实际值不会发出警告(v10)。所以交叉检查似乎也不是本意?

回到我的开始问题:这些方式设置矢量并没有真正的区别,不是吗?所以我会使用“长”形式:

reg [3:0] vector = 'b1011;

仅将 reg 设置为二进制或十六进制的特定值。设置为小数或为零:

reg [3:0] vector = 0;

更短、更直观、更省钱,因为我不能忘记改变长度。

只有美学才能让人们写出 1'b0。

【问题讨论】:

  • 在 rtl 代码中以这种方式初始化向量。它在一般情况下是不可合成的(不包括一些 fpga)。除此之外,这两种情况之间没有太大区别。如果您没有使用2 而不是4,第一个会更好。

标签: vector initialization verilog


【解决方案1】:

没有基数或大小的数字文字被视为带符号的 32 位值。 Verilog 允许从任何大小到任何其他大小的赋值,并且会隐式地截断或扩展值。这被称为弱类型

当您写2'b0000 时,您指定的是一个 2 位无符号二进制数,但您写出了 4 位数字。该数字将被截断为 2 位。但是由于您正在对 4 位变量进行赋值,因此值 hets 扩展回 4 位。

因此,每种初始化类型的最终结果都是相同的。

编辑:

您的编辑略微更改了问题主题,但您示例中的代码的答案仍然相同 - 结果是相同的。但在表达式中使用文字时,情况并非总是如此。大小很重要。

【讨论】:

  • 是的,这不是预期的主题,所以我将其更正为 4'b0000!
  • 那改变了原来的问题。
【解决方案2】:

第二个会把0当作32位整数,所以相当于

reg [3:0] vector = 32'b0000_0000_0000_0000_0000_0000_0000_0000;

对于模拟:只要向量大小不超过 32 位,就可以了。您可能会收到有关操作数被截断以适应的警告。但如果向量大于 32 位,则从 32 开始的位将在您的模拟中为 x。

编辑:好像不是这样的,0可以用来初始化任何大小。请参阅下面的示例

合成器/编译器将扩​​展操作数以适应 L 值:

reg [3:0] vector = 'b0;

对于 FPGA 合成,未初始化的向量将被初始化为在合成器/比特流生成过程中配置的默认值,通常为 0。

module tb;
  reg [3:0] v1, v2, v3;
  reg [127:0] v4;

  initial begin
    v1 = 0;
    v2 = 4'b0000;
    v3 = 'b0;
    v4 = 0;
    
    $display ("%b %b %b %b", v1, v2, v3, v4);
    $finish;
  end
endmodule

[2020-06-28 09:49:37 EDT] iverilog '-Wall' design.sv testbench.sv  && unbuffer vvp a.out  
0000 0000 0000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Done

【讨论】:

  • 感谢您的回复!我带你 testprogram 并用我开始问题中写的一些其他值扩展它。
【解决方案3】:

原来的问题贴出了这行代码:

reg [3:0] vector = 2'b0000;

您可能会在使用某些模拟器的第一条语句中收到编译警告,因为您使用2 作为数字文字值的大小。您可能打算使用4

reg [3:0] vector = 4'b0000;

除此之外,您应该看到您的 2 个语句将以相同的方式进行模拟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 2019-10-24
    • 2019-10-03
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多