SystemVerilog中的接口实例的数组,带有参数化的元素数

apr*_*ori 6 arrays verilog interface system-verilog

我正在使用SystemVerilog进行综合.我认为接口数组实际上并不是SystemVerilog中的数组,并且索引必须是一个常量值,但是使用大量的样板generate forassign语句来克服它实际上是语言限制(如果我可以模拟使用更多代码的效果,语言可以做正确的事(Tm)本身).

对于下面的伪代码,为了清楚起见,我遗漏了实际代码(modports,tasks等)中的大部分内容.我有一个界面:

interface i_triplex();
logic a;              // input wire
logic b;              // output wire
logic [127:0] data;   // output wires
endinterface
Run Code Online (Sandbox Code Playgroud)

我将这些接口的数组传递给一个看起来像的模块

module roundrobin_triplex#(
    parameter int NUNITS = 8
)
(
    input wire clk,
    input wire rst,
    i_triplex t[NUNITS]
);
always_ff @(posedge clk) begin
    if (rst) begin
      // insert code to initialize the "data" member
      // in all interface instances in the array.
    end
    else begin
      // ...
    end
end
endmodule
Run Code Online (Sandbox Code Playgroud)

您在网络中统一使用所有接口实例的首选方式是什么 - 无论其值是NUNITS多少?我有一些建议,但我很想知道其他工程师能想出什么.

建议1: 使用VHDL.

建议2: 废弃界面并使用oldschool Verilog风格,如同

module roundrobin_triplex#(
    parameter int NUNITS = 8
)
(
    input wire clk,
    input wire rst,
    // This was once a proud i_triplex array
    input wire i_triplex_a[NUNITS],
    input wire i_triplex_b[NUNITS],
    input wire [127:0] i_triplex_data[NUNITS],
);
always_ff @(posedge clk) begin
    if (rst) begin
        for (int i = 0; i < NUNITS; i++)
            i_triplex_data[i] <= '1;
    end
    else begin
        // ...
    end
end
endmodule
Run Code Online (Sandbox Code Playgroud)

建议3: 使用struct输入线和struct输出线代替接口.

建议4: 使用类似预处理器的系统来展开generate for进程内的循环(语言应该做什么!),因此生成的代码看起来像(使用NUNITS = 4预处理):

module roundrobin_triplex#(
    parameter int NUNITS = 8
)
(
    input wire clk,
    input wire rst,
    i_triplex t[NUNITS]
);
always_ff @(posedge clk) begin
    if (rst) begin
        i_triplex.data[0] <= '1;
        i_triplex.data[1] <= '1;
        i_triplex.data[2] <= '1;
        i_triplex.data[3] <= '1;
    end
    else begin
        // ...
    end
end
endmodule
Run Code Online (Sandbox Code Playgroud)

建议5: 使用generate for/ assignsolution:

module roundrobin_triplex#(
    parameter int NUNITS = 8
)
(
    input wire clk,
    input wire rst,
    i_triplex t[NUNITS]
);

wire i_triplex_a[NUNITS];
wire i_triplex_b[NUNITS];
wire [127:0] i_triplex_data[NUNITS];

generate
genvar i;
// The wires of the interface which are to be driven
// from this module are assigned here.
for (i = 0; i < NUNITS; i++) begin
    assign t[i].b = i_triplex_b[i];
    assign t[i].data = i_triplex_data[i];
end
endgenerate

always_ff @(posedge clk) begin
    if (rst) begin
        for (int i = 0; i < NUNITS; i++)
            i_triplex_data[i] <= '1;
    end
    else begin
        // ...
    end
end
endmodule
Run Code Online (Sandbox Code Playgroud)

小智 0

建议1:VHDL可能比较实用。然而,它似乎在工业中变得边缘化。

建议 2:在我看来,如果您打算广泛重用接口并在其中实现验证/协议,那么接口是相关的。如果您可以像这样解压您的界面,同时保持理智,那么我一开始就看不到界面的合理性。

建议3:我从未尝试过综合struct,这可能是个好主意。

建议 4:简单的解决方案,虽然相当冗长。

Suggestion 5: I used something similar for one of my project. However, I wrote a sort of adapter module to hide the assigns.
Actually, when I need something like that, I try to write an atomic module which operates on a fixed number of interfaces. Then, I use for generate structures to generalize it on an interface array.