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.
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
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
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