Indexing 为什么这两种索引模式中的一种会给我一个“;“索引超出范围”;错误?

Indexing 为什么这两种索引模式中的一种会给我一个“;“索引超出范围”;错误?,indexing,verilog,bus,Indexing,Verilog,Bus,对于ncsim,以下代码引发错误: 位选择或部分选择索引超出声明的界限 然而,注释掉的代码做了完全相同的事情,却没有。我是遗漏了什么还是编译器弄错了 模块局部放电测试; genvar i,j; 注册表[10-1:0]从注册表中分配\u; reg[256:0]将\分配给\ reg; 生成 对于(i=0;i将条件if(i+2*j

对于ncsim,以下代码引发错误:

位选择或部分选择索引超出声明的界限

然而,注释掉的代码做了完全相同的事情,却没有。我是遗漏了什么还是编译器弄错了

模块局部放电测试;
genvar i,j;
注册表[10-1:0]从注册表中分配\u;
reg[256:0]将\分配给\ reg;
生成

对于(i=0;i将条件
if(i+2*j<25)
移动到
始终
块之外:

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
模块局部放电测试;
genvar i,j;
注册表[10-1:0]从注册表中分配\u;
reg[256:0]将\分配给\ reg;
生成

对于(i=0;i您要求verilog编译器在always块中编译此代码

assign_to_reg[10*(i+2*j)+9 -: 10]
对于
i==1
j==12
,由生成块生成,如下所示:

 assign_to_reg[259 : 250]
上述内容显然超出了声明的界限[256:0]

按照@toolic的建议,将“if”移动到generate块中会导致verilognot生成最后一个always块,因此不会编译它,也不会产生警告/错误

因此,使用生成块的另一个解决方案是将您的assign_to_reg声明为
[259:0]

然而,最好的解决方案是将generate块全部去掉,并将all循环移动到单个always块中:

  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
始终@*开始

对于(int i=0;iHmm,您是对的,将
始终
向上移动在某种程度上解决了示例中的错误。不幸的是,我不能在完整的设计中真正做到这一点,因为有一个
else
if
关联,这意味着我在单独的
始终
块中分配相同的
reg
,这将“不合成。奇怪的是,ncsim被这个问题噎住了。我的问题是,它为什么会生成警告,这并不能真正回答这个问题。我已经证明,我可以通过
-:10
索引绕过警告,而不必移动
始终
块。不过,我没有要求它编译它,因为当
I==1
a时nd
j==12
,然后
(i+2*j==1+12*2)==25
。所以
如果(i+2*j<25)
不满意,也不应该生成它。这就是为什么我使用
-:
时它可以工作的原因。你可以把
generate
块看作一个预处理器。
generate
语句评估所有的genvar表达式并生成具有常量值的always块。因此,它生成24个不同的always块,并且最后一个是这样的:
总是如果(25<25)赋值给[259:250]=asiign\u fom\u reg;
编译器会根据这个代码视图给你一个警告。哦,我明白了,谢谢。这更有意义!但奇怪的是它会生成
[259-:10]
,并且不会对代码发出警告。
  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