Variable input MUX in Verilog

What's the best way to make an N:1 multiplexer in Verilog (NOT SystemVerilog), where the maximum N is 64? Each input is 32-bits wide and there are N such inputs. Verilog doesn't allow two-dimensional arrays as port arguments, so I figure the input has to be taken in as a single-dimensional 'rolled-out' array. Here's two ideas I've had so far:

// Option 1
// Synthesizes to a multiplier and a BSEL block
module mux #(parameter N = 4)
(
output [31:0] y,
input [N*32-1:0] x,
input [5:0] s
);

assign y = (s < N) ? x[s*32 +: 32] : 0;

endmodule

// Option 2
// Synthesizes to a pipeline of N 2-input MUXes
module mux #(parameter N = 4)
(
output reg [31:0] y,
input [N*32-1:0] x,
input [5:0] s
);

integer i;

always @(s, x) begin
y = 0;
for (i = 0; i < N; i = i + 1)
if (s == i)
y = x[i*32 +: 32];
end

endmodule


The first option elaborates to a circuit with a multiplier (in Vivado) because of the multiplication on s. The second option yields a pipeline of N 2-input muxes, which would produce large propagation delay for large N. Is there a better way?

• If you want to be very crude, just make a 32-input 32-bit mux, and let optimization trim the unused inputs. – The Photon Nov 1 '18 at 21:40
• The maximum number of inputs is 64 so it would actually be twice as crude as that :) – pr871 Nov 1 '18 at 21:41
• "The first option elaborates to a circuit with a multiplier " I doubt that. Did you see a multiplier appear in your gates? It would be at most a shift but I think it will just optimize to a lot of muxes. – Oldfart Nov 1 '18 at 21:42
• I saw a multiplier block in Vivado's elaborated design that took in signal 's' and a constant and whose output was connected to a BSEL block. – pr871 Nov 1 '18 at 21:44
• Your synthesizer shouldn’t create a multiplayer. Try changing s*32 to s<<5 or {s,5'b00000} – Greg Nov 2 '18 at 0:19