Easy way to define wire output multiplexers in Verilog

For the wire type in Verilog, I know that I can define a multiplexer as follows

wire a;

assign a = select ? 1'b0 : 1'b1;


And for reg's, I can do it as follows

reg a;
always @ (select)
begin
case(select)
1'b0: a = 1'b0;
1'b1: a = 1'b1;
endcase
end


Now my question arises - it's so easy to describe complex multiplexers using regs/always blocks/procedural statements. It seems so tedious to do the same with wires. What if I wanted to describe a very complex multiplexer driving a wire? Would my select? line be huge?

• AlfoJang, you should be declaring your variables as reg or wire depending how you assign to them, not choosing how to assign to them based on how they are declared. – The Photon Oct 8 '18 at 17:03

Just use the case and declare the signal as a reg. The distinction between wire and reg in Verilog is rather artificial anyway -- there's really no functional difference between them, just some (mostly historical) syntax rules.

You can do

assign a = somefunction(select);
function somefunction(input sel);
begin
case(sel)
1'b0: a = 1'b0;
1'b1: a = 1'b1;
endcase
end
endfunction


The only complication is every input to your block of logic has to be an input your function.

Using the variable form, you can use @* and not worry about it.