Multiplexers¶
Multiplexers are generated by the Verilog HDL frontend for ?:-expressions.
Multiplexers are also generated by the proc pass to map the decision trees from
RTLIL::Process objects to logic.
The simplest multiplexer cell type is $mux. Cells of this type have a
WITDH parameter and data inputs A and B and a data output Y, all
of the specified width. This cell also has a single bit control input S. If
S is 0 the value from the input A is sent to the output, if it is 1 the
value from the B input is sent to the output. So the $mux cell implements
the function Y = S ? B : A.
The $pmux cell is used to multiplex between many inputs using a one-hot select
signal. Cells of this type have a WIDTH and a S_WIDTH parameter and
inputs A, B, and S and an output Y. The S input is
S_WIDTH bits wide. The A input and the output are both WIDTH bits
wide and the B input is WIDTH*S_WIDTH bits wide. When all bits of S
are zero, the value from A input is sent to the output. If the \(n\)‘th bit from S is set, the value \(n\)‘th WIDTH bits wide slice of
the B input is sent to the output. When more than one bit from S is set
the output is undefined. Cells of this type are used to model “parallel cases”
(defined by using the parallel_case attribute, the unique or unique0
SystemVerilog keywords, or detected by an optimization).
The $tribuf cell is used to implement tristate logic. Cells of this type have
a WIDTH parameter and inputs A and EN and an output Y. The A
input and Y output are WIDTH bits wide, and the EN input is one bit
wide. When EN is 0, the output is not driven. When EN is 1, the value
from A input is sent to the Y output. Therefore, the $tribuf cell
implements the function Y = EN ? A : 'bz.
Behavioural code with cascaded if-then-else- and case-statements usually results
in trees of multiplexer cells. Many passes (from various optimizations to FSM
extraction) heavily depend on these multiplexer trees to understand dependencies
between signals. Therefore optimizations should not break these multiplexer
trees (e.g. by replacing a multiplexer between a calculated signal and a
constant zero with an $and gate).
- yosys> help $bmux¶
Binary-encoded multiplexer
Selects between ‘slices’ of A where each value of S corresponds to a unique slice.
- Properties:
- Simulation model (verilog)¶
1666module \$bmux (A, S, Y); 1667 1668 parameter WIDTH = 0; 1669 parameter S_WIDTH = 0; 1670 1671 input [(WIDTH << S_WIDTH)-1:0] A; 1672 input [S_WIDTH-1:0] S; 1673 output [WIDTH-1:0] Y; 1674 1675 wire [WIDTH-1:0] bm0_out, bm1_out; 1676 1677 generate 1678 if (S_WIDTH > 1) begin:muxlogic 1679 \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm0 (.A(A[(WIDTH << (S_WIDTH - 1))-1:0]), .S(S[S_WIDTH-2:0]), .Y(bm0_out)); 1680 \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm1 (.A(A[(WIDTH << S_WIDTH)-1:WIDTH << (S_WIDTH - 1)]), .S(S[S_WIDTH-2:0]), .Y(bm1_out)); 1681 assign Y = S[S_WIDTH-1] ? bm1_out : bm0_out; 1682 end else if (S_WIDTH == 1) begin:simple 1683 assign Y = S ? A[2*WIDTH-1:WIDTH] : A[WIDTH-1:0]; 1684 end else begin:passthru 1685 assign Y = A; 1686 end 1687 endgenerate 1688 1689endmodule
- yosys> help $bwmux¶
Bit-wise multiplexer
Equivalent to a series of 1-bit wide
$muxcells.- Properties:
- Simulation model (verilog)¶
2035module \$bwmux (A, B, S, Y); 2036 2037 parameter WIDTH = 0; 2038 2039 input [WIDTH-1:0] A, B; 2040 input [WIDTH-1:0] S; 2041 output [WIDTH-1:0] Y; 2042 2043 genvar i; 2044 generate 2045 for (i = 0; i < WIDTH; i = i + 1) begin:slices 2046 assign Y[i] = S[i] ? B[i] : A[i]; 2047 end 2048 endgenerate 2049 2050endmodule
- yosys> help $demux¶
Demultiplexer i.e routing single input to several outputs based on select signal. Unselected outputs are driven to zero.
- Properties:
- Simulation model (verilog)¶
1741module \$demux (A, S, Y); 1742 1743 parameter WIDTH = 1; 1744 parameter S_WIDTH = 1; 1745 1746 input [WIDTH-1:0] A; 1747 input [S_WIDTH-1:0] S; 1748 output [(WIDTH << S_WIDTH)-1:0] Y; 1749 1750 genvar i; 1751 generate 1752 for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin:slices 1753 assign Y[i*WIDTH+:WIDTH] = (S == i) ? A : 0; 1754 end 1755 endgenerate 1756 1757endmodule
- yosys> help $mux¶
Multiplexer i.e selecting between two inputs based on select signal.
- Properties:
- Simulation model (verilog)¶
1647module \$mux (A, B, S, Y); 1648 1649 parameter WIDTH = 0; 1650 1651 input [WIDTH-1:0] A, B; 1652 input S; 1653 output [WIDTH-1:0] Y; 1654 1655 assign Y = S ? B : A; 1656 1657endmodule
- yosys> help $pmux¶
Priority-encoded multiplexer
Selects between ‘slices’ of B where each slice corresponds to a single bit of S. Outputs A when all bits of S are low.
- Properties:
- Simulation model (verilog)¶
1699module \$pmux (A, B, S, Y); 1700 1701 parameter WIDTH = 0; 1702 parameter S_WIDTH = 0; 1703 1704 input [WIDTH-1:0] A; 1705 input [WIDTH*S_WIDTH-1:0] B; 1706 input [S_WIDTH-1:0] S; 1707 output reg [WIDTH-1:0] Y; 1708 1709 integer i; 1710 reg found_active_sel_bit; 1711 1712 always @* begin 1713 Y = A; 1714 found_active_sel_bit = 0; 1715 for (i = 0; i < S_WIDTH; i = i+1) 1716 case (S[i]) 1717 1'b1: begin 1718 Y = found_active_sel_bit ? 'bx : B >> (WIDTH*i); 1719 found_active_sel_bit = 1; 1720 end 1721 1'b0: ; 1722 1'bx: begin 1723 Y = 'bx; 1724 found_active_sel_bit = 'bx; 1725 end 1726 endcase 1727 end 1728 1729endmodule
- yosys> help $tribuf¶
A tri-state buffer. This buffer conditionally drives the output with the value of the input based on the enable signal.
- Properties:
- Simulation model (verilog)¶
1816module \$tribuf (A, EN, Y); 1817 1818 parameter WIDTH = 0; 1819 1820 input [WIDTH-1:0] A; 1821 input EN; 1822 output [WIDTH-1:0] Y; 1823 1824 assign Y = EN ? A : 'bz; 1825 1826endmodule