What is a Multiplexer?
A multiplexer (MUX) is a data selector — it picks one of 2ⁿ input lines and forwards it to a single output based on n select lines. Think of it as a programmable wire: the select lines tell the circuit which input to connect to the output.
An n-to-1 MUX needs: n data inputs, log₂(n) select lines, and 1 output. The Boolean output is: Y = Σ mᵢ · Iᵢ (sum of each minterm times its corresponding data input).
2:1 MUX
S0
4:1 MUX
S1,S0
8:1 MUX
S2,S1,S0
1:4 DEMUX
S1,S0
Interactive MUX Simulator
4:1 MUX Truth Table
| S1 | S0 | Output Y |
|---|---|---|
| 0 | 0 | I0 |
| 0 | 1 | I1 |
| 1 | 0 | I2 |
| 1 | 1 | I3 |
Verilog Implementations
2:1 MUX — gate level
module mux2to1 ( input wire i0, i1, sel, output wire y ); assign y = sel ? i1 : i0; endmodule
4:1 MUX — behavioral (synthesizes to MUX tree)
module mux4to1 ( input wire [3:0] d, input wire [1:0] sel, output wire y ); assign y = d[sel]; // concise — synthesizer handles the MUX tree endmodule
8:1 MUX — case statement (explicit, readable)
module mux8to1 (
input wire [7:0] d,
input wire [2:0] sel,
output reg y
);
always_comb
case (sel)
3'd0: y = d[0]; 3'd1: y = d[1];
3'd2: y = d[2]; 3'd3: y = d[3];
3'd4: y = d[4]; 3'd5: y = d[5];
3'd6: y = d[6]; default: y = d[7];
endcase
endmodule
1:4 DEMUX
module demux1to4 (
input wire d,
input wire [1:0] sel,
output reg [3:0] y
);
always_comb begin
y = 4'b0;
y[sel] = d; // only the selected output carries D; rest are 0
end
endmodule
Wide MUX — parameterized (VLSI-ready)
// W-bit wide N:1 MUX module mux_wide #( parameter N = 4, // number of inputs (must be power of 2) parameter W = 32, // data width parameter S = $clog2(N) // select width auto-computed )( input wire [W-1:0] d [N-1:0], input wire [S-1:0] sel, output wire [W-1:0] y ); assign y = d[sel]; endmodule
MUX as Universal Logic Element
A 2ⁿ:1 MUX can implement any n-variable Boolean function without any additional gates. Connect the n Boolean variables to the select lines. Then set each data input to 0 or 1 to match the truth table.
Example: Implement F(A,B) = A⊕B using a 4:1 MUX
Connect A → S1, B → S0. Fill data inputs from the XOR truth table:
| A (S1) | B (S0) | F = A⊕B | MUX Input |
|---|---|---|---|
| 0 | 0 | 0 | I0 = 0 |
| 0 | 1 | 1 | I1 = 1 |
| 1 | 0 | 1 | I2 = 1 |
| 1 | 1 | 0 | I3 = 0 |
Result: Wire I0=0, I1=1, I2=1, I3=0 — done. No logic minimization, no Karnaugh map. The same technique applies to any 3-variable function using an 8:1 MUX.
Building Larger MUXes from Smaller Ones
A 16:1 MUX from 4:1 MUXes — use five 4:1 MUXes in a 2-level tree:
// 16:1 MUX from five 4:1 MUXes
module mux16to1 (
input wire [15:0] d,
input wire [3:0] sel,
output wire y
);
wire [3:0] mid;
// Level 1: four 4:1 MUXes, each handling 4 inputs
assign mid[0] = d[{2'b00, sel[1:0]}]; // shorthand — see below
mux4to1 m0(.d(d[3:0]), .sel(sel[1:0]), .y(mid[0]));
mux4to1 m1(.d(d[7:4]), .sel(sel[1:0]), .y(mid[1]));
mux4to1 m2(.d(d[11:8]), .sel(sel[1:0]), .y(mid[2]));
mux4to1 m3(.d(d[15:12]), .sel(sel[1:0]), .y(mid[3]));
// Level 2: one 4:1 MUX selects which group wins
mux4to1 m4(.d(mid), .sel(sel[3:2]), .y(y));
endmodule
Demultiplexer (DEMUX)
A DEMUX is the inverse of a MUX — one input, many outputs. The select lines route the input data to exactly one output; all others go to 0. A 1:4 DEMUX is equivalent to a 2-to-4 decoder with a data enable: Yᵢ = D · (minterm i of select lines).
| S1 | S0 | Y0 | Y1 | Y2 | Y3 |
|---|---|---|---|---|---|
| 0 | 0 | D | 0 | 0 | 0 |
| 0 | 1 | 0 | D | 0 | 0 |
| 1 | 0 | 0 | 0 | D | 0 |
| 1 | 1 | 0 | 0 | 0 | D |
VLSI Applications
Pipeline Forwarding MUX
In a 5-stage CPU pipeline, the ALU input MUX selects between: the register file output, a value forwarded from the EX/MEM stage, or a value forwarded from the MEM/WB stage. This 3:1 MUX (implemented as a 4:1 with one unused entry) prevents data hazards without pipeline stalls.
Clock MUX (Glitch-Free)
Clock muxes switch between two clock sources (e.g., PLL clock vs. test clock). Unlike data MUXes, a clock MUX must be glitch-free — a glitch on the clock line would fire flip-flops at the wrong time. The standard implementation adds synchronization flip-flops and OR-based handshaking to ensure a clean transition.
Memory Address MUX
DRAM requires row and column addresses multiplexed over the same pins (RAS/CAS protocol). A MUX on the address bus shares pins, saving package cost at the expense of two-phase access — exactly the trade-off that motivated the DRAM burst protocol.
MUX vs Decoder vs Encoder
| Feature | MUX | Decoder | Encoder |
|---|---|---|---|
| Inputs → Outputs | 2ⁿ data + n sel → 1 | n → 2ⁿ | 2ⁿ → n |
| Select / Enable | n select lines | Enable pin optional | Priority or plain |
| Primary function | Route data | Activate one line | Compress to binary code |
| Implements Boolean | Yes — any n-var function | Yes — as minterm generator | Inverse only |
| VLSI example | ALU input, clock select | Address decode, chip select | Priority interrupt encode |