Verilog:设置串联运算符内的表达式宽度

art*_*ter 1 verilog system-verilog

所以,问题是我需要在循环内用字节模式初始化一个 32 位字的数组,其中循环变量的尺寸非常糟糕(不是我的代码)。因为这是一个快速破解,所以我不想重构循环,只是为了尝试测试代码。因此,可行的解决方案是执行以下操作:

reg [15:0] index;
reg [31:0] data_word;
for (index = 0 ; index < buflen ; index = index+1) begin
  data_dword = (((index*4+'h13)&8'hFF) << 24) | (((index*4+'h14)&8'hFF) << 16) | (((index*4+'h15)&8'hFF) << 8) | (((index*4+'h16)&8'hFF) << 0);
  //I expect to get something like 32'h13141516, 32'h1718191a
end
Run Code Online (Sandbox Code Playgroud)

我想我也许可以使用串联运算符:

data_dword = {((index*4+'h13)&8'hFF), ((index*4+'h14)&8'hFF), ((index*4+'h15)&8'hFF), ((index*4+'h16)&8'hFF)};
Run Code Online (Sandbox Code Playgroud)

但这不能正常工作。我得到 32'h00000016、32'h0000001a 等。即只有最后一个字节可用,所有其他字节都被覆盖。为什么这样?我认为每个子表达式的长度:

((index*4+'h13)&8'hFF)
Run Code Online (Sandbox Code Playgroud)

未正确调整(由于某种原因是 32 位),因此整体串联被截断。

Mat*_*lor 5

这个表情

(index*4+'h14)&8'hFF
Run Code Online (Sandbox Code Playgroud)

是一个自定表达式的例子。名称自定名称是 Verilog 使用的两种方法之一,用于决定使用多少位来计算表达式。(另一个是上下文决定的。)这个表达式是自决定的,与表达式本身无关,而与它是串联的一个成员这一事实有关。

通过自行确定的表达式,Verilog 使用最宽的操作数。在这个表达式中,最宽的操作数是

'h14
Run Code Online (Sandbox Code Playgroud)

4
Run Code Online (Sandbox Code Playgroud)

它们是 32 位宽。因此,Verilog使用32位来计算表达式,结果是32位宽。

为了使您的示例正常工作,您需要类似的东西

(index[7:0]*8'd4+8'h14)
Run Code Online (Sandbox Code Playgroud)

您不需要&8'hFF,因为结果已经是 8 位宽。

Verilog 自由主义精神的一个缺点是,您必须熟悉它在引擎盖下的工作原理,否则它会咬您一口。你最好用谷歌搜索自己决定的上下文决定的表达方式。

  • SystemVerilog 允许类型转换。因此你可以使用: `8'(index*4+'h14)` (2认同)