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)¶
1689module \$bmux (A, S, Y); 1690 1691 parameter WIDTH = 0; 1692 parameter S_WIDTH = 0; 1693 1694 input [(WIDTH << S_WIDTH)-1:0] A; 1695 input [S_WIDTH-1:0] S; 1696 output [WIDTH-1:0] Y; 1697 1698 wire [WIDTH-1:0] bm0_out, bm1_out; 1699 1700 generate 1701 if (S_WIDTH > 1) begin:muxlogic 1702 \$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)); 1703 \$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)); 1704 assign Y = S[S_WIDTH-1] ? bm1_out : bm0_out; 1705 end else if (S_WIDTH == 1) begin:simple 1706 assign Y = S ? A[2*WIDTH-1:WIDTH] : A[WIDTH-1:0]; 1707 end else begin:passthru 1708 assign Y = A; 1709 end 1710 endgenerate 1711 1712endmodule
- yosys> help $bwmux¶
Bit-wise multiplexer
Equivalent to a series of 1-bit wide
$muxcells.- Properties:
- Simulation model (verilog)¶
2058module \$bwmux (A, B, S, Y); 2059 2060 parameter WIDTH = 0; 2061 2062 input [WIDTH-1:0] A, B; 2063 input [WIDTH-1:0] S; 2064 output [WIDTH-1:0] Y; 2065 2066 genvar i; 2067 generate 2068 for (i = 0; i < WIDTH; i = i + 1) begin:slices 2069 assign Y[i] = S[i] ? B[i] : A[i]; 2070 end 2071 endgenerate 2072 2073endmodule
- 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)¶
1764module \$demux (A, S, Y); 1765 1766 parameter WIDTH = 1; 1767 parameter S_WIDTH = 1; 1768 1769 input [WIDTH-1:0] A; 1770 input [S_WIDTH-1:0] S; 1771 output [(WIDTH << S_WIDTH)-1:0] Y; 1772 1773 genvar i; 1774 generate 1775 for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin:slices 1776 assign Y[i*WIDTH+:WIDTH] = (S == i) ? A : 0; 1777 end 1778 endgenerate 1779 1780endmodule
- yosys> help $mux¶
Multiplexer i.e selecting between two inputs based on select signal.
- Properties:
- Simulation model (verilog)¶
1670module \$mux (A, B, S, Y); 1671 1672 parameter WIDTH = 0; 1673 1674 input [WIDTH-1:0] A, B; 1675 input S; 1676 output [WIDTH-1:0] Y; 1677 1678 assign Y = S ? B : A; 1679 1680endmodule
- 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)¶
1722module \$pmux (A, B, S, Y); 1723 1724 parameter WIDTH = 0; 1725 parameter S_WIDTH = 0; 1726 1727 input [WIDTH-1:0] A; 1728 input [WIDTH*S_WIDTH-1:0] B; 1729 input [S_WIDTH-1:0] S; 1730 output reg [WIDTH-1:0] Y; 1731 1732 integer i; 1733 reg found_active_sel_bit; 1734 1735 always @* begin 1736 Y = A; 1737 found_active_sel_bit = 0; 1738 for (i = 0; i < S_WIDTH; i = i+1) 1739 case (S[i]) 1740 1'b1: begin 1741 Y = found_active_sel_bit ? 'bx : B >> (WIDTH*i); 1742 found_active_sel_bit = 1; 1743 end 1744 1'b0: ; 1745 1'bx: begin 1746 Y = 'bx; 1747 found_active_sel_bit = 'bx; 1748 end 1749 endcase 1750 end 1751 1752endmodule
- yosys> help $tribuf¶
A tri-state buffer. This buffer conditionally drives the output with the value of the input based on the enable signal.
- Simulation model (verilog)¶
1839module \$tribuf (A, EN, Y); 1840 1841 parameter WIDTH = 0; 1842 1843 input [WIDTH-1:0] A; 1844 input EN; 1845 output [WIDTH-1:0] Y; 1846 1847 assign Y = EN ? A : 'bz; 1848 1849endmodule