Using Enable to switch between two Decoders

decoderfpgaquartus-iivhdl

I am trying to put an enable input in a 4-to-16 decoder so I can select between two decoder. Here is a schematic:
enter image description here

I am using two decoders to select two different addresses in a 16×16 SRAM. I am thinking about using an enable input to switch between the two decoders. For example, if enable is high, the top decoder selects an address. If enable is low, the bottom decoder selects an address.

This is the decoder vhdl but when I try putting an input enable in, and do if enable ='1' then , it doesn't work.

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity decode4to16 is
    port(
        enable: in std_logic;
        oct : in std_logic_vector(3 downto 0);
        dec : out std_logic_vector(15 downto 0));
end decode4to16;

architecture arch of decode4to16 is
begin
if enable = '1' then 
with oct select
dec <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
"0000000000000100" when "0010",
"0000000000001000" when "0011",
"0000000000010000" when "0100",
"0000000000100000" when "0101",
"0000000001000000" when "0110",
"0000000010000000" when "0111",
"0000000100000000" when "1000",
"0000001000000000" when "1001",
"0000010000000000" when "1010",
"0000100000000000" when "1011",
"0001000000000000" when "1100",
"0010000000000000" when "1101",
"0100000000000000" when "1110",
"1000000000000000" when "1111",
"0000000000000000" when others;

end arch;

Someone suggested:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity decode4to16 is
port(
oct : in std_logic_vector(3 downto 0);
e : in std_logic;
dec : out std_logic_vector(15 downto 0));
end decode4to16;
architecture arch of decode4to16 is
BEGIN
process(e, oct)
begin
if e = '1' then
case oct is
when "0000" => dec <= "0000000000000001";
when "0001" => dec <= "0000000000000010";
when "0010" => dec <= "0000000000000100";
when "0011" => dec <= "0000000000001000";
when "0100" => dec <= "0000000000010000";
when "0101" => dec <= "0000000000100000";
when "0110" => dec <= "0000000001000000";
when "0111" => dec <= "0000000010000000";
when "1000" => dec <= "0000000100000000";
when "1001" => dec <= "0000001000000000";
when "1010" => dec <= "0000010000000000";
when "1011" => dec <= "0000100000000000";
when "1100" => dec <= "0001000000000000";
when "1101" => dec <= "0010000000000000";
when "1110" => dec <= "0100000000000000";
when "1111" => dec <= "1000000000000000";
when others => dec <= "0000000000000000";
end case;
else null;
end if;
end process;
end arch;

But when I tested it, the output remains when e = '0', this will conflict with the other decoder if they share the same bus wire. Is there a way (like a else case) where if e ='0' then, output nothing?
enter image description here

Best Answer

What you describe would be to output 'Z' on the else branch, which translate to High-Impedance. If one driver outputs XYZ and all other drivers connected to it output 'Z', the result is XYZ.

The 'Z' translate to a tri-state buffer inside the FPGA. However, tri-state buffers don't exist anymore on modern FPGAs for anything else than output drivers (i.e. on a FPGA pin). You can achieve what you want by using a mux in the top level:

muxOut <= decTop when enable = '1' else
          decBot;

If you have several drivers, another popular scheme is to output zeros when a driver is not selected, and or'ing all the drivers together.

Otherwise, never connect several drivers to the same wire, it is a bad design practice and will likely won't work.