Multiplexer in Verilog

One-bit Four-channel MUX

method 1:

module mux1a(s, d, q);
 
input[1:0] s;
input[3:0] d;
output q;
 
assign q = 
            ( ~s[0] & ~s[1] & d[0]) |
            (s[0] & ~s[1] & d[1]) |
            (~s[0] & s[1] & d[2]) |
            (s[0] & s[1] & d[3]);
 
endmodule

method 2:

module mux1b(s, d, q);
 
input[1:0] s;
input[3:0] d;
output q;
 
assign q = (s == 0)? d[0] : (s == 1)? d[1] : (s == 2)? d[2] : d[3];
 
endmodule

Method 3:

module mux1c(s, d, q)
 
input[1:0] s;
input[3:0] d;
output q;
 
assign q = d[s];
 
endmodule

Three-bit Four-channel MUX

We can use any one of the above one-bit multiplexers. This code simply instantiates 3 of them:

module mux3a(s, d, q);
 
input[1:0] s;
input[11:0] d;
output[2:0] q;
 
mux1a mx0(s, d[11:8], q[2]);
mux1a mx1(s, d[7:4], q[1]);
mux1a mx2(s, d[3:0], q[0]);
 
endmodule

Using a generate loop will ease repeatitive instantiations:

module mux3b(s, d, q);
 
input[1:0] s;
input[11:0] d;
output[2:0] q;
genvar i;
 
generate 
    for (i=0; i<3; i=i+1) 
    begin
        mux1a mx(s, d[i*4+3: i*4], q[i]);
    end
endgenerate
 
endmodule

Note: You may have been tempted to use a 2-dimensional array for input channels. However, it is not a valid syntax and is not supported by most of the tools (including ModelSim):

module mux3c(s, d, q);
 
input[1:0] s;
input[3:0] d[0:2]; // not standard, most tools will give an error
output[7:0] q;
 
mux1a mx0(s, d[0], q[0]);
mux1a mx1(s, d[1], q[1]);
mux1a mx2(s, d[2], q[2]);
 
endmodule