How to define a parameterized multiplexer using SystemVerilog

♀尐吖头ヾ 提交于 2019-12-18 08:54:07

问题


I am trying to create a module which switches x input data packets to a single output packet according to a one hot input.

If x was a fixed value of 4, I would just create a case statement,

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

But with variable x, how do I define all cases?

Thanks.


回答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



回答2:


If you can assert that onehot is truly one-hot or 0, then you could use a 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



回答3:


Here's a fully parameterized synthesizable mux optimized for a one-hot input (i.e. no priority encoding) using an OR tree. Note that the output is driven to 0 instead of 'z' if no input is enabled:

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


来源:https://stackoverflow.com/questions/19875899/how-to-define-a-parameterized-multiplexer-using-systemverilog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!