使用ncsim时,以下代码会引发错误:
声明边界的位选择或部分选择索引。
然而,完全相同的注释掉的代码却没有。我错过了什么或者编译器错了吗?
module pd__test;
genvar i, j;
reg [10-1:0] assign_from_reg;
reg [256:0] assign_to_reg;
generate
for (i=0; i<2; i=i+1) begin
for (j=0; j<13; j=j+1) begin
always @* begin
if (i+2*j < 25) begin
// gives me an index out of bounds error
assign_to_reg[10*(i+2*j)+9 : 10*(i+2*j)] = assign_from_reg;
// gives me no such error, however the indices are the same
// assign_to_reg[10*(i+2*j)+9 -: 10] = assign_from_reg;
end else begin
// do something else
end
end
end
end
endgenerate
endmodule
我运行了一个python脚本来打印indeces以进行双重检查:
for i in range(2):
for j in range(13):
if (i+(2*j) < 25):
print("[", 10*(i+(2*j))+9, ":", 10*(i+(2*j)), "]")
打印:
[ 9 : 0 ]
[ 29 : 20 ]
[ 49 : 40 ]
[ 69 : 60 ]
[ 89 : 80 ]
[ 109 : 100 ]
[ 129 : 120 ]
[ 149 : 140 ]
[ 169 : 160 ]
[ 189 : 180 ]
[ 209 : 200 ]
[ 229 : 220 ]
[ 249 : 240 ]
[ 19 : 10 ]
[ 39 : 30 ]
[ 59 : 50 ]
[ 79 : 70 ]
[ 99 : 90 ]
[ 119 : 110 ]
[ 139 : 130 ]
[ 159 : 150 ]
[ 179 : 170 ]
[ 199 : 190 ]
[ 219 : 210 ]
[ 239 : 230 ]
答案 0 :(得分:1)
将条件if (i+2*j < 25)
移到always
块之外:
module pd__test;
genvar i, j;
reg [10-1:0] assign_from_reg;
reg [256:0] assign_to_reg;
generate
for (i=0; i<2; i=i+1) begin
for (j=0; j<13; j=j+1) begin
if (i+2*j < 25) begin
always @* begin
//assign_to_reg[10*(i+2*j)+9 : 10*(i+2*j)] = assign_from_reg;
assign_to_reg[10*(i+2*j)+9 -: 10] = assign_from_reg;
end
end
end
end
endgenerate
endmodule
这两个作业都是在没有警告或错误的情况下编译的。
答案 1 :(得分:1)
你要求verilog编译器在always块
中编译这段代码assign_to_reg[10*(i+2*j)+9 -: 10]
生成块生成i == 1
和j == 12
的:
assign_to_reg[259 : 250]
以上显然超出了声明的界限[256:0]。
将'if'移动到generate块中,因为@toolic建议会导致verilog not 生成最后一个始终块,因此,它将不会被编译,也不会出现警告/错误生产。
因此, 生成块的其他解决方案是将assign_to_reg声明为[259:0]
。
然而,最好的解决方案是一起摆脱生成块,并在单个always块中移动 all 你的循环:
always @* begin
for (int i=0; i<2; i=i+1) begin
for (int j=0; j<13; j=j+1) begin
if (i+2*j < 25) begin
assign_to_reg[10*(i+2*j)+9 -: 10] = assign_from_reg;
end
end
end
end
这应该让编译器在运行时计算索引,也不会导致越界访问。