Logic implementation

Multiplexers are trivially implemented as a logic operation. This form may be compact if the select input is already one-hot encoded, but otherwise has no particular advantage over any other form.

The Verilog version, however, does propagate X's in the select input if the logic equality operator (==) is used, although the resulting X propagation differs from that produced by the conditional operator. The table below shows the output of a 2-to-1 mux, with a select input of X:

Input?: outputAND-OR output
11 1 X
10 X X
01 X X
00 0 0

The AND-OR output is arguably preferable to the ?: output, since this output should also be produced by a gate-level model, and so would allow the RTL and gate-level models to simulate identically (2).


module MUX8TO1(input [2:0] SEL, input [7:0] I, output O);
   assign O = 
          ((SEL == 0) & I[0]) |  // normally use brackets for clarity,
            SEL == 1  & I[1]  |  // but not required here (precedence
            SEL == 2  & I[2]  |  // is: == -> & -> |)
            SEL == 3  & I[3]  |
            SEL == 4  & I[4]  |
            SEL == 5  & I[5]  |
            SEL == 6  & I[6]  |
            SEL == 7  & I[7];

VHDL is strongly-typed (3), so it is not possible to directly compare the select input against an integer. The to_integer function is therefore used to convert SEL to an integer (S) before the comparison. It is, similarly, not possible to directly combine boolean and std_logic quantities in an expression without overloading the operators. Rather than overloading the AND operator, this code defines function to_sl to convert the boolean result of the comparison to a std_logic. The std_logic result can then be directly combined with the data inputs. In practice, the subtype definition and the to_sl function would normally be in a project-wide package.


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;               -- unsigned and to_integer

entity MUX8TO1 is
  port (
    SEL : in  unsigned(2 downto 0);
    I   : in  std_logic_vector(7 downto 0);
    O   : out std_logic);
end entity MUX8TO1;

architecture A of MUX8TO1 is
  subtype int3 is integer range 0 to 7;
  signal S : int3;
  function to_sl(inp : boolean) return std_logic is
    if inp then
      return '1';
      return '0';
    end if;
  end function to_sl;
  S <= to_integer(SEL);
  O <= (to_sl(S = 0) and I(0)) or      -- brackets required when...
       (to_sl(S = 1) and I(1)) or      -- mixing 'and' and 'or'
       (to_sl(S = 2) and I(2)) or
       (to_sl(S = 3) and I(3)) or
       (to_sl(S = 4) and I(4)) or
       (to_sl(S = 5) and I(5)) or
       (to_sl(S = 6) and I(6)) or
       (to_sl(S = 7) and I(7));
end architecture A;