计算循环生成块中的参数

时间:2014-11-06 19:30:33

标签: verilog system-verilog

我有一个参数数组WIDTHS,我需要根据生成块中RIGHT中的某些值计算另一个参数WIDTHS。这可能吗?如果没有,是否有另一种方式?

这是我想要做的一个例子。假设我们有一个预定义的寄存器模块REG,其输入为d, q, we (write enable), CLK and _RESET。我想创建一个名为GroupReg的新模块,它实例化N REG个实例。每个实例都有不同的宽度(因此WIDTH参数数组)。每个组的d, q, and we聚合在GroupReg中具有相同名称的数组中,需要为每个实例指定。指定we很简单(we[i]),因为它只有一位。但是,使用正确的dq值指定LEFTRIGHT是我遇到问题的地方,因为每个组的宽度都不同。

看起来为参数赋值的唯一方法是根据其定义,这会阻止在生成循环中为其赋值。

 module GroupReg(d, q, we, CLK, _RESET);
 parameter N = 4;               //Number of groups
 //INDICES has to have N+1 members. Last member should be 0
 parameter integer WIDTHS   [N:0]  = {40, 30, 20, 10, 0}; 
 parameter integer DW_TOTAL  = 128;

 input  logic [DW_TOTAL-1:0]        d;                  // Data Input
 input  logic [N-1:0]               we;                     // write enable
 input  logic                       CLK;                // Clock Input
 input  logic                       _RESET;           // Reset input (active low)
 output logic [DW_TOTAL-1:0]        q;            // Q output

 genvar i, j;
 for (i=N-1 ; i>=0 ; i--) begin:REGISTERS

  localparam WIDTH = WIDTHS[i];
  localparam LEFT  = RIGHT +  WIDTHS[i];;
  localparam RIGHT = 0;

  for (j = 0 ; j<i ; j++)        // <<----- Does not work
    RIGHT = RIGHT + WIDTH[j];  

  REG #(
             .DW              (WIDTH),
             ) 
  reg_i 
  ( 
   .d(d[LEFT:RIGHT]), 
   .q(q[LEFT:RIGHT]),
   .we(we[i]),
   .CLK(CLK),
  ._RESET(_RESET)  
  );
 end : REGISTERS
endmodule  

2 个答案:

答案 0 :(得分:1)

我尝试在sum()上使用WIDTHS数组缩减方法,它在Aldec Riviera PRO中有效:

module some_module;
  parameter N = 4;               //Number of groups
  parameter integer WIDTHS   [N:0]  = '{40, 30, 20, 10, 0};

  parameter integer DW_TOTAL  = WIDTHS.sum();

  initial begin
    $display("DW_TOTAL", DW_TOTAL);
  end
endmodule

如果你很幸运,它也会在你的模拟器中工作。

无论如何,我还没有真正得到你正在尝试制作N参数的内容,看看你是如何硬编码固定数量的宽度值的。 / p>

答案 1 :(得分:0)

这适用于Modelsim:

module some_module;
  parameter N = 4;               //Number of groups
  parameter integer WIDTHS   [N:0]  = '{40, 30, 20, 10, 0};


  genvar i;
  for (i=N-1 ; i>=0 ; i--) begin
    localparam integer FOO[i:0] = WIDTHS[i:0];
    //localparam RIGHT = FOO.sum();

    initial begin
      foreach (FOO[i])
        $display("FOO[%0d] = %h", i, FOO[i]);
    end
  end
endmodule

FOO参数仅存储来自WIDTH的相关条目以进行特定的循环迭代。如果sum()可行,那么你就可以在家中自由了。但是,切片语法在Riviera中不起作用。

这是供应商以不同方式解释标准的典型示例,主要是因为它不够具体。不过,如果您使用其他EDA公司的模拟器,请尝试将两个答案结合起来;也许你很幸运,而且很有效。