I started learning VHDL and I'm current following a book instructions that suggested a 4 to 8 multiplexer with buffer. So I decided to build a 4x1 MUX. But I can't figure out how to set an individual output as high impedance.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY buffered_mux_4x1 IS
PORT (a, b, c, d: IN BIT;
sel: IN NATURAL RANGE 0 TO 3;
ena: IN BIT;
y: OUT BIT);
END buffered_mux_4x1;
ARCHITECTURE myarch OF buffered_mux_4x1 IS
SIGNAL x: BIT;
BEGIN
x <= a WHEN sel=0 ELSE --MUX
b WHEN sel=1 ELSE
c WHEN sel=2 ELSE
d;
y <= x WHEN ena='1' ELSE -- Tristate buffer
???
END myarch;
Here's the original code to set the output at high impedance when the enable was set in '0':
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY buffered_mux IS
PORT (a, b, c, d: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
sel: IN NATURAL RANGE 0 TO 3;
ena: IN STD_LOGIC;
y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END buffered_mux;
ARCHITECTURE myarch OF buffered_mux IS
SIGNAL x: STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
x <= a WHEN sel=0 ELSE --MUX
b WHEN sel=1 ELSE
c WHEN sel=2 ELSE
d;
y <= x WHEN ena='1' ELSE -- Tristate buffer
(OTHERS => 'Z');
END myarch;
with
y: OUT std_logic);
you can use
y <= x WHEN ena='1' ELSE 'z';
EDITS:
As commented by me and another user, the high impedance is not supported inside (most, if not all) FPGAs, even if the syntax is correct. It should rather be implemented with a vendor specific block at the pad.
You should forget about the BIT type, and never use it. std_logic(_vector), signed and unsigned are the normal logical values to use for synthesis. And a few other type like integer for bus sizes.
So indeed a, b, c, d, ena and x should also be std_logic(_vector). Depending where it comes from (is it an internal signal only?), sel too, even if a natural there might be interpreted correctly by some tools.