如何在 SystemVerilog 中实现可参数化多路复用器?

How do I implement a Parametrizable Mux in SystemVerilog?

我在带有 VCS 合成器的 System Verilog 中收到以下错误:

The following access has an invalid number of indices. bus[i]

我基本上是在尝试做一个由接口组成的可参数化多路复用器,select 总线是单热的:

module myMux
    #(int unsigned WIDTH=3)
    (
        my_interface              bus[WIDTH-1:0],
        input  logic [WIDTH-1:0]  select,
        output logic [31:0]       out_data
    )
    always_comb begin
        out_data = 'x;
        for (int unsigned i=0; i < WIDTH; i++) begin
            if (select[i]) out_data = bus[i].in_data;
        end
    end
endmodule

我尝试了 this answer here 中概述的不同方法(包括使用 |= ),但我总是遇到相同的错误。使用 "genvar i" 而不是 int 甚至无法编译。

如果我将 bus[i] 替换为 bus[0],则它会编译(但这不是我想要的)。 . .另外,用 for 语句中的数字替换 WIDTH(即 i < 1)会给我同样的错误,即使它小于 WIDTH 的值。

有什么想法吗?代码需要可综合。

访问阵列接口的实例只能通过模拟常量(参数、genvar 或硬编码数字)进行访问。数据类型和设计元素都使用带点的名称来访问相关成员或层次结构名称,但访问索引数组的规则不同。我能很快找到的最佳描述是 IEEE Std 1800-2012 § 23.6 层次名称 和 § 23.7 成员 select 和层次名称 .

这里有两种可能的解决方案:

三态解决方案:如果select为0,则浮动,x在具有多个冲突驱动程序的位上。

module myMux
    #(int unsigned WIDTH=3)
    (
        my_interface              bus[WIDTH-1:0],
        input  logic [WIDTH-1:0]  select,
        output wire  [31:0]       out_data
    );
  for (genvar i=0; i < WIDTH; i++) begin : loop
    assign out_data = select[i] ? bus[i].in_data : 'z;
  end
endmodule

优先级select或:使用局部二维数组映射接口实例。这个 map 可以在 always 块中访问。如果您在 FPGA 上,这是更好的解决方案,因为它不需要三态。

module myMux
    #(int unsigned WIDTH=3)
    (
        my_interface              bus[WIDTH-1:0],
        input  logic [WIDTH-1:0]  select,
        output logic [31:0]       out_data
    );
  logic [31:0] map [WIDTH];
  for (genvar i=0; i < WIDTH; i++) begin : loop
    assign map[i] = bus[i].in_data;
  end
  always_comb begin
    out_data = 'x;
    for(int unsigned i=0; i<WIDTH; i++) begin
      if (select[i]) out_data = map[i];
    end
  end
endmodule