将单个信号打包到数组中
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
我有一堆这样的信号:
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