我想写一个具有可变数量输入的模块,即取决于某些参数,结果将是:
module my_module #(LENGTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data_1
);
//...
endmodule
或
module my_module #(LENGTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data_1,
input [LENGTH-1:0] data_2,
input [LENGTH-1:0] data_3
);
//...
endmodule
是否有可能在Verilog或Systemverilog中执行此操作,或者我是否必须编写脚本,例如在Python中,为了生成具有固定输入数量的特定模块的代码? (可能超过1000个输入)
答案 0 :(得分:3)
SystemVerilog中没有可变数量的端口,但您可以使用作为参数化数组的端口。
module my_module #(int LENGTH, DEPTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data[DEPTH]
);
//...
endmodule
否则,您需要使用脚本来生成代码。
答案 1 :(得分:3)
使用参数化大小的二维输入。添加了生成循环,可用于单独设置信号。虽然可以通过智能阵列操作完成许多操作。
module my_module #(SIZE, LENGTH)(
input clk,
input rst_n,
input [SIZE-1:0][LENGTH-1:0] data_in_array,
output [SIZE-1:0][LENGTH-1:0] data_out_array
);
genvar N;
generate for (N=0; N<SIZE; N++) begin :la_coolOps
//Do cool operations here. For example instantiate a module for every data_in
end
//...
endmodule
编辑:
正如Mehran Torki所指出的:上面的语法仅适用于SystemVerilog。 Verilog不允许使用多个打包数组。使用input [LENGTH*SIZE-1:0] data_in_array
。
答案 2 :(得分:2)
我想补充一下这些其他答案,即端口只是电线的分组。虽然具有名为a,b和c的3位,1位线可能更容易阅读和理解,但单个3位线abc
之间没有物理/逻辑差异,其中abc[0]
对应a
,abc[1]
对应b
,abc[2]
对应c
。
因此,您可以随时扩展或缩小单个(或多个)信号,以获得所需的多个位。它可能不那么整洁,但它会起作用。在接收模块中,您可以以任何您喜欢的方式选择总线。所以,你可以有一个非常长的线收缩或扩展(wire [(SOME_PARAM*8)-1:0] my_input_wire
),或者使用SystemVerilog一个数组(wire [7:0] my_input_wire[0:SOME_PARAM-1]
)
如果这只是测试平台/验证码,那么您在SystemVerilog中可以做的另一件事是使用动态数组
答案 3 :(得分:1)
正如其他人所说,没有直接的方法可以做到这一点,但另一种解决方法是使用SystemVerilog接口,您可以在接口定义中定义所需的所有输入,而模块内部仅使用与参数。以下是一个示例:
module my_module #(LENGTH)(
input clk;
input rst_n;
output o;
interface i_data;
);
logic outValue;
generate
case (LENGTH) //Based on the value of LENGTH, use corresponding data
1: outValue = i_data.data_1;
2: outValue = i_data.data_1 + i_data.data_2;
3: outValue = i_data.data_1 + i_data.data_2 + i_data.data_3;
endcase
endgenerate
always @(posedge clk) begin
if (~rst_n)
o <= '0;
else
begin
o <= outValue;
end
endmodule
如果输出相似,您仍然可以使用参数化数组作为数据和for-generate循环。