如何在SystemVerilog中实现Parametrizable Mux?

时间:2015-11-07 07:50:44

标签: system-verilog

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

  

以下访问的索引数无效。    总线[I]

我基本上是尝试用接口构建一个可参数化的多路复用器,而选择总线是一个热点:

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甚至不编译。

如果我用总线[0]替换总线[i],那么它会编译(但它不是我想要的)。 。 。另外,用for语句中的数字替换WIDTH(即i&lt; 1),即使它小于WIDTH的值,也会给出相同的错误。

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

1 个答案:

答案 0 :(得分:3)

访问阵列接口的实例只能通过模拟常量(参数,genvar或硬编码的数字)访问。数据类型和设计元素都使用点名称来访问那些受尊重的成员或层次名称,但访问索引数组的规则是不同的。我可以快速找到的最佳描述是IEEE Std 1800-2012§23.6分层名称和§23.7成员选择和分层名称

以下是两种可能的解决方案:

三态解决方案:如果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

优先级选择器:使用本地2D数组映射接口实例。可以在always块中访问此map。如果您使用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