【问题标题】:How to define a parameterized multiplexer using SystemVerilog如何使用 SystemVerilog 定义参数化多路复用器
【发布时间】:2013-11-09 12:23:36
【问题描述】:

我正在尝试创建一个模块,该模块根据一个热输入将 x 个输入数据包切换为单个输出包。

如果 x 是固定值 4,我会创建一个 case 语句,

case (onehot)
  4'b0001  : o_data = i_data[0];
  4'b0010  : o_data = i_data[1];
  4'b0100  : o_data = i_data[2];
  4'b1000  : o_data = i_data[3];
  default  : o_data = 'z;
endcase

但是对于变量 x,我如何定义所有情况?

谢谢。

【问题讨论】:

    标签: verilog system-verilog


    【解决方案1】:
    parameter X = 4;  
    
    input [X-1:0] onehot;
    input i_data [X];
    output reg o_data;
    
    always_comb 
    begin
       o_data = 'z;
       for(int i = 0; i < X; i++) begin
          if (onehot == (1 << i))
             o_data = i_data[i];
       end
    end
    

    【讨论】:

    • 是的,我的意思是谢谢,我会编辑 q。尽管有两个问题,为什么o_data = 'z 行与o_data = i_data[i]; 不冲突,if(oneshot == (1 &lt;&lt; i)) 行是否等同于if(oneshot[i] == 1)
    • for 循环之前的赋值就像一个默认值。最后一个任务应该获胜。这两个比较是不等价的,因为oneshot[i] == 1 将仅基于那一位进行匹配。如果多个位高,那么您将获得多个匹配项。
    • 例如,如果oneshot == 4'b1001oneshot[0] == 1 为真,而oneshot == (1&lt;&lt;0) 为假。
    • 好的,谢谢,我得到了第一个 q。对于第二个, (1
    • &lt;&lt; 进行左移,所以4'b0001&lt;&lt;04'b00014'b0001&lt;&lt;14'b0010,等等...
    【解决方案2】:

    如果您可以断言 onehot 确实是 one-hot 或 0,那么您可以使用 generate

    package mytypes;
    typedef logic [7:0] packet_t;
    endpackage 
    
    module mux #(int X) (
          input logic [X-1:0] onehot,
          input mytypes::packet_t i_data[X],
          output wire mytypes::packet_t o_data
          );
    for(genvar i=0;i<X;i++) begin
       assign o_data = onehot[i] ? i_data[i] : 'z;
    end
    endmodule
    

    【讨论】:

    • 我以前在 Xilinx 工具中使用过这种技术,但现在我使用 Altera 工具时,我收到一条警告,不允许使用内部三态缓冲器。我可能会检查原理图,看看它是如何实现的,但如果有机会,你知道这种技术是否仍然适用于 Altera 工具?
    【解决方案3】:

    这是一个完全参数化的可合成多路复用器,使用 OR 树针对单热输入(即无优先级编码)进行了优化。请注意,如果未启用任何输入,则输出将驱动为 0 而不是“z”:

    module mux
     #( parameter int unsigned inputs = 4,
        parameter int unsigned width = 8 )
      ( output logic [width-1:0] out,
        input logic sel[inputs],
        input logic [width-1:0] in[inputs] );
    
        always_comb
        begin
            out = {width{1'b0}};
            for (int unsigned index = 0; index < inputs; index++)
            begin
                out |= {width{sel[index]}} & in[index];
            end
        end
    endmodule
    

    【讨论】:

      【解决方案4】:

      我认为“wor”数据类型是这里真正的救星。 请查找示例代码:

      module cnt64_shared
         #(
         parameter INSTANCES          = 6 // Number of shared istances
         )
      (
          input        [INSTANCES-1:0][31:0]  in_L_f      , // i - input
          input        [INSTANCES-1:0]        in_sel_1hot , // i - input selection        
      
              // clk and reset - add new signals before   
         input                        clk                     , // i - clock
         input                        rst_n                     // i - reset
      
      );
      
          wor [31:0]  in_L_mux; 
      
          genvar i;
              
      generate
          for (i=0;i<INSTANCES;i=i+1) begin
              assign in_L_mux = in_sel_1hot[i]    ?   in_L_f[i]   :   32'h0   ;  
          end
      endgenerate
      
      endmodule
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-01
        • 1970-01-01
        相关资源
        最近更新 更多