Verilog中CASE语句的合成错误

Verilog中CASE语句的合成错误,verilog,synthesis,case-statement,register-transfer-level,cadence,Verilog,Synthesis,Case Statement,Register Transfer Level,Cadence,我是Verilog新手,我想知道您对我在尝试合成下面引用的代码部分时遇到的错误的看法: input [31:0] A; reg [31:0] X,Y; reg [15:0] width; input action; always@* begin width= A [31:16]; if (action==1) begin case (width) 16'b0: X=0; default:

我是Verilog新手,我想知道您对我在尝试合成下面引用的代码部分时遇到的错误的看法:

input [31:0] A;
reg [31:0] X,Y;
reg [15:0] width;
input action;       

always@*
begin

  width= A [31:16]; 
  if (action==1)    
  begin    
    case (width) 
      16'b0: X=0;
        default: 
          begin
            for (i=32; i>=width+1 ; i=i-1)
              X[i]=0;
            for (i=width; i>=0; i=i-1)
              X[i]=1;
          end 
    endcase 
    Y=X >> 1;
  end
end
我正在使用Cadence合成工具,我得到的错误在我代码的这一部分中说:

索引“X[-1]”不在声明的有效范围内[31:0]

我不理解这一点,因为即使
width=0
我也有一个特殊情况,不应该涉及for循环。我还尝试将限制增加到
宽度+2
宽度+1
,然后
将数量X移动2
。但也得到了相同的错误


提前谢谢你

我不知道
I
怎么可能是-1,但它有可能大于超出范围的31。有两个综合问题:

  • i=32
    已超出
    X[31:0]
    的范围。其MSB为31
  • i
    width>31
    时将超出范围
    width
    是一个16位无符号值,表示其最大值为65535(即216-1),最小值为0
  • 合成需要循环来静态展开。这意味着循环的数量必须是恒定的。诸如
    width
    之类的变量不能处于循环状态
  • 可用于循环的合成如下所示:

    for (i=31; i>=0; i=i-1)
      X[i] = (width>=i);
    


    我假设
    width=A[31:16]是一个复制过去的打字错误,因为它是非法语法。我还假设在always块之外的
    width
    X
    Y
    I
    上没有其他赋值。否则会出现其他错误。

    不清楚您为什么会遇到-1条件,但看起来您正在尝试创建宽度为“width”的遮罩,这将更容易实现,如下所示:

    always @*
      begin
        X = ((1 << width[4:0]) - 1)
      end
    
    始终@*
    开始
    
    X=((1)我不认为(I=width;I>=0;I=I-1)
    可以静态展开,我认为这也会导致合成问题。感谢您的贡献!第一个错误是我在更改代码时犯的。我也认为上限应该是个问题,但错误消息会误导。非常感谢!我也想到了这一点,但它合成为“怪物”和其他设计……甚至比X=2**width-1更糟糕。我只是想探索在面积方面优化设计的可能性。