.. role:: verilog(code)
   :language: Verilog

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 :verilog:`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 :math:`n`\
'th bit from ``S`` is set, the value :math:`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 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 :verilog:`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).

.. autocellgroup:: mux
   :members:
   :source:
   :linenos:
