如何在 SystemVerilog 中实现可参数化的多路复用器? [英] How do I implement a Parametrizable Mux in SystemVerilog?

查看:61
本文介绍了如何在 SystemVerilog 中实现可参数化的多路复用器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am getting the following error in System Verilog with VCS synthesizer:

以下访问的索引数量无效.总线[i]

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

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

I am basically trying to do a parametrizable mux made of interfaces, with the select bus being one-hot:

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

我尝试了这里的答案(包括使用 |= )但我总是遇到相同的错误.使用genvar i"而不是 int 甚至无法编译.

I tried the different methods outlined in this answer here (including using |= ) but I always get the same error. Using a "genvar i" instead of an int does not even compile.

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

If I replace bus[i] with bus[0], then it compiles (but it is not what I want) . . . also, replacing WIDTH with a number in the for statement (ie i < 1) gives me the same error even though it is less than the value of WIDTH.

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

Any ideas? the code needs to be synthesizable.

推荐答案

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

Accessing an instances of an arrayed interface can only be accessed via a simulation constant (parameter, genvar, or hard-coded number). Data types and design elements both use dotted names to access there respected member or hierarchical-name, but the rules for accessing index arrays are different. Best description I can quickly find is in IEEE Std 1800-2012 § 23.6 Hierarchical names and § 23.7 Member selects and hierarchical names.

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

Here are two possible solutions:

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

Tri-state solution: floating if select is 0, x on the bit with multiple conflicting drivers.

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

优先级选择器:使用本地二维数组来映射界面实例.这个 map 可以在一个 always 块中访问.如果您使用 FPGA,这是更好的解决方案,因为它不需要三态.

Priority selector: using a local 2D array to map the interface instances. This map can be accessed in an always block. If you are on FPGA, this is the better solution as it doesn't need tri-state.

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

这篇关于如何在 SystemVerilog 中实现可参数化的多路复用器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆