在 SystemVerilog 中,在 for 循环中索引参数数组是一个常量表达式
In SystemVerilog are indexing a parameter array in a for loop a constant expression
以下模块尝试以三种不同的方式使用解压缩的参数数组。
module works
#(parameter int num = 4,
parameter int width = 8,
parameter int bits [num] = '{4, 4})
(output logic [width-1:0] mask [num]);
genvar i;
generate
for(i=0; i<num; ++i) begin
always_comb mask[i] = {{(width-bits[i]){1'b0}},{bits[i]{1'b1}}};
end
endgenerate
endmodule
module also_works
#(parameter int num = 4,
parameter int width = 8,
parameter int bits [num] = '{4, 4})
(output logic [width-1:0] mask [num]);
always_comb begin
mask[0] = {{(width-bits[0]){1'b0}},{bits[0]{1'b1}}};
mask[1] = {{(width-bits[1]){1'b0}},{bits[1]{1'b1}}};
mask[2] = {{(width-bits[2]){1'b0}},{bits[2]{1'b1}}};
mask[3] = {{(width-bits[3]){1'b0}},{bits[3]{1'b1}}};
end
endmodule
module fails
#(parameter int num = 4,
parameter int width = 8,
parameter int bits [num] = '{4, 4})
(output logic [width-1:0] mask [num]);
always_comb begin
for(int i=0; i<num; ++i) begin
mask[i] = {{(width-bits[i]){1'b0}},{bits[i]{1'b1}}};
end
end
endmodule
前两个模块被我使用的模拟器认为是正确的。然而,最后一个被认为是不正确的,因为 i
不是常量表达式。但是,我可以在语义上解释始终块版本中的 for 循环的唯一方法与 also_works
.
相同
我在标准中找不到任何说明这种情况的内容,期待第 11.2.1 节中的说明
11.2.1 Constant expressions
Some statement constructs require an expression to be a constant
expression. The operands of a constant expression consist of constant
numbers, strings, parameters, constant bit-selects and part-selects of
parameters, constant function calls (see 13.4.3), and constant system
function calls only. Constant expressions can use any of the operators
defined in Table 11-1.
据我所知,它只讨论位和部分选择,而不是索引参数数组。
当使用 {repNum{val}}
语法复制时,repNum
需要是一个常量。 bits[i]
不是常量,因为索引在模拟中是动态的。 generate
起作用是因为循环在 compile/elaboration.
期间是静态展开的
您可以进行位分配以获得相同的功能:
always_comb begin
foreach(mask[i,j]) begin
mask[i][j] = (j<bits[i]);
end
end
以下模块尝试以三种不同的方式使用解压缩的参数数组。
module works
#(parameter int num = 4,
parameter int width = 8,
parameter int bits [num] = '{4, 4})
(output logic [width-1:0] mask [num]);
genvar i;
generate
for(i=0; i<num; ++i) begin
always_comb mask[i] = {{(width-bits[i]){1'b0}},{bits[i]{1'b1}}};
end
endgenerate
endmodule
module also_works
#(parameter int num = 4,
parameter int width = 8,
parameter int bits [num] = '{4, 4})
(output logic [width-1:0] mask [num]);
always_comb begin
mask[0] = {{(width-bits[0]){1'b0}},{bits[0]{1'b1}}};
mask[1] = {{(width-bits[1]){1'b0}},{bits[1]{1'b1}}};
mask[2] = {{(width-bits[2]){1'b0}},{bits[2]{1'b1}}};
mask[3] = {{(width-bits[3]){1'b0}},{bits[3]{1'b1}}};
end
endmodule
module fails
#(parameter int num = 4,
parameter int width = 8,
parameter int bits [num] = '{4, 4})
(output logic [width-1:0] mask [num]);
always_comb begin
for(int i=0; i<num; ++i) begin
mask[i] = {{(width-bits[i]){1'b0}},{bits[i]{1'b1}}};
end
end
endmodule
前两个模块被我使用的模拟器认为是正确的。然而,最后一个被认为是不正确的,因为 i
不是常量表达式。但是,我可以在语义上解释始终块版本中的 for 循环的唯一方法与 also_works
.
我在标准中找不到任何说明这种情况的内容,期待第 11.2.1 节中的说明
11.2.1 Constant expressions
Some statement constructs require an expression to be a constant expression. The operands of a constant expression consist of constant numbers, strings, parameters, constant bit-selects and part-selects of parameters, constant function calls (see 13.4.3), and constant system function calls only. Constant expressions can use any of the operators defined in Table 11-1.
据我所知,它只讨论位和部分选择,而不是索引参数数组。
当使用 {repNum{val}}
语法复制时,repNum
需要是一个常量。 bits[i]
不是常量,因为索引在模拟中是动态的。 generate
起作用是因为循环在 compile/elaboration.
您可以进行位分配以获得相同的功能:
always_comb begin
foreach(mask[i,j]) begin
mask[i][j] = (j<bits[i]);
end
end