将单个信号打包到数组中

Pack individual signal into an array

我有一堆这样的信号:

logic [7:0] in0;
logic [7:0] in1;
logic [7:0] in2;
logic [7:0] in3;

我想分配给一个数组:

logic [7:0] in_array [4];
assign in_array[0] = in0;
assign in_array[1] = in1;
assign in_array[2] = in2;
assign in_array[3] = in3;

很简单,但是如果我有 128 个而不是 4 个项目,这会很烦人。我确信有定义和生成的组合可以在循环中执行此操作。类似于:

`define IN(x) inx
genvar i;
generate
   for(i = 0; i<4; i++) begin
      assign in_array[i] = `IN(i);
   end 
endgenerate 

上面的代码不起作用,但我想我以前做过这样的事情。

使用 `` 将文本与参数分开。

`define IN(x) in``x

但是在评估宏时变量 i 没有被声明还有另一个问题。因此整个生成循环只连接到 ini,因为 i 只是另一个字母。因为这个宏不能由动态分配的值分配。

您的模块环境已经必须显式连接到每个输入 assign in0 = out0; ... assign in127 = out127。因此,最简单的解决方案是将 in_array 作为模块输入并让环境连接到它 assign array_in[0] = out0.

像这样:

module parent_module();

/*some other stuff that has outputs out0, out1 etc.*/

logic [7:0] array_in[4]; 

assign array_in[0] = out0;    
assign array_in[1] = out1;
assign array_in[2] = out2;
assign array_in[3] = out3;

my_module(.array_in(array_in));
endmodule

简化代码是 SystemVerilog 无法做到的。您可以通过创建如下所示的宏来减少输入(注意双反引号 ``),但您仍然需要手动编写每个索引。宏在生成循环之前解析,宏的输入变量被视为文字。

// short named macro for reduced typing
//   Note: using short named macro is typically a bad practice,
//         but will be removed latter with an undef
`define A(idx) assign array_in[idx] = out``idx
//This works
`A(0);
`A(1);
`A(2);
`A(3);

// doesn't work. For example @ gidx==0 will eval to 'assign array_in[0] = outgidx;'.
// There is not outgidx
genvar gidx;
generate
  for(gidx=0; gidx<4; gidx++) begin
    `A(gidx); 
  end
endgenerate

`undef A // prevent macro from from being used latter on

如果只是少量条目,最好手动完成。如果是大量条目,那么你需要考虑一种为你生成的方法,比如嵌入编码。

还有各种内嵌代码(比如Perl的EP3, Ruby's eRuby/ruby_it, Python's prepro, etc.) that can generate the desired code. Pick your preference. You will need to per-process these files before giving to the compiler. Example with EP3生成400个赋值:

@perl_begin
  foreach my $idx (0..400) {
    printf "assign array_in[%0d] = out%0d;", $idx, $idx;
  }
@perl_end