如何在Verilog中编写端口数可变的模块

如何在Verilog中编写端口数可变的模块,verilog,system-verilog,Verilog,System Verilog,我想编写一个输入数量可变的模块,即根据某些参数,结果将是: module my_module #(LENGTH)( input clk, input rst_n, input [LENGTH-1:0] data_1 ); //... endmodule 或 是否可以在Verilog或Systemverilog中执行此操作,或者我必须编写一个脚本(比如说Python),以便为具有固定数量输入的特定模块生成代码?(可能有1000多个输入)SystemVerilog中没有可变

我想编写一个输入数量可变的模块,即根据某些参数,结果将是:

module my_module #(LENGTH)(
    input clk,
    input rst_n,
    input [LENGTH-1:0] data_1
);
//...
endmodule


是否可以在Verilog或Systemverilog中执行此操作,或者我必须编写一个脚本(比如说Python),以便为具有固定数量输入的特定模块生成代码?(可能有1000多个输入)

SystemVerilog中没有可变数量的端口,但您可以使用参数化阵列的端口

module my_module #(int LENGTH, DEPTH)(
    input clk,
    input rst_n,
    input [LENGTH-1:0] data[DEPTH]
);
//...
endmodule

否则,您将需要使用脚本来生成代码。

使用具有参数化大小的二维输入。添加了一个generate for循环,可用于单独设置信号。尽管许多操作可以通过智能阵列操作完成

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
模块我的模块(大小、长度)(
输入时钟,
输入rst\n,
在数组中输入[SIZE-1:0][LENGTH-1:0]数据,
输出[SIZE-1:0][LENGTH-1:0]数据\u out\u数组
);
genvar N;

generate for(N=0;N正如其他人所说,没有直接的方法可以做到这一点,但另一种解决方法是使用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
模块我的模块(长度)(
输入时钟;
输入rst\n;
输出o;
接口i_数据;
);
逻辑输出值;
生成
case(LENGTH)//根据LENGTH的值,使用相应的数据
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;
尾声
最终生成
始终@(posedge clk)开始
如果(~rst_n)

o我想在这些其他答案的基础上补充一点,即端口只是电线的分组。虽然名为a、b和c的3、1位电线可能更容易阅读和理解,但单个3位电线之间没有物理/逻辑上的区别,其中,
abc[0]
对应于
a
abc[1]
对应于
b
,而
abc[2]
对应于
c

因此,您始终可以只扩展或收缩一个(或多个)信号以获得所需的位数。它可能没有那么整洁,但可以工作。在接收模块中,您可以以任何方式部分选择总线。因此,您可以使用一条非常长的导线来收缩或扩展(
wire[(某些参数*8)-1:0]my_input_wire
),或使用SystemVerilog阵列(
wire[7:0]my_input_wire[0:SOME_PARAM-1]


如果这只是测试台/验证代码,您可以在SystemVerilog中做的另一件事是使用动态数组

请注意,此代码在verilog中不起作用,因为ModelSim中存在此错误:
不允许多个压缩维度。
在verilog中,必须使用一维输入,长度等于
(大小*长度)-1
。事实上,我只是避免这样做,因为这样做之后调试会不好。但是,你是对的,它会工作。这就是我的想法。还有一个问题,它不是输入[LENGTH-1:0]数据[0:DEPTH-1]?在SystemVerilog中,你可以将数组的维度(未打包的数组维度)指定为[DEPTH],而不是[DEPTH][0:DEPTH-1]。这与C/C++数组表示法相匹配。但是,您不能对长度(压缩数组维度)执行此操作。这是一种很酷的了解方法,但遗憾的是,无法解决输入数量可变的问题。无论如何,感谢与我们共享此信息:)是否可以使接口内的信号可选?即,如果某些参数设置为特定值,则不创建信号?
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