Created on: 31 December 2012
A decoder that has two inputs, an enable pin and four outputs is implemented in a CPLD using VHDL in this part of the VHDL course.
This 2 to 4 decoder will switch on one of the four active low outputs, depending on the binary value of the two inputs and if the enable input is high.
VHDL processes are introduced in this tutorial – processes allow sequential execution of VHDL code contained in them.
The block diagram of the two to four decoder is shown here.
When the EN pin is low, all the X output pins will be high. With the EN pin high, all the outputs on the X port will be high, except for the output selected by the A input port as follows:
The two to four decoder is implemented with the following VHDL code.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity decode_2to4_top is Port ( A : in STD_LOGIC_VECTOR (1 downto 0); -- 2-bit input X : out STD_LOGIC_VECTOR (3 downto 0); -- 4-bit output EN : in STD_LOGIC); -- enable input end decode_2to4_top; architecture Behavioral of decode_2to4_top is begin process (A, EN) begin X <= "1111"; -- default output value if (EN = '1') then -- active high enable pin case A is when "00" => X(0) <= '0'; when "01" => X(1) <= '0'; when "10" => X(2) <= '0'; when "11" => X(3) <= '0'; when others => X <= "1111"; end case; end if; end process; end Behavioral;
This code does the same thing as the previous code, but compensates for the inverting inputs of the home built CPLD board.
The inverting outputs are left as-is because they are active low and an LED will switch on, when one of the outputs becomes active.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity decode_2to4_top is Port ( A : in STD_LOGIC_VECTOR (1 downto 0); -- 2-bit input X : out STD_LOGIC_VECTOR (3 downto 0); -- 4-bit output EN : in STD_LOGIC); -- enable input end decode_2to4_top; architecture Behavioral of decode_2to4_top is signal B : STD_LOGIC_VECTOR(1 downto 0); begin B <= not A; process (B, EN) begin X <= "1111"; -- default output value if (EN = '1') then -- active high enable pin case B is when "00" => X(0) <= '0'; when "01" => X(1) <= '0'; when "10" => X(2) <= '0'; when "11" => X(3) <= '0'; when others => X <= "1111"; end case; end if; end process; end Behavioral;
The source code for the 2 to 4 decoder can be downloaded here. The UCF and JED files are configured for the home made CPLD board.
VHD, UCF and JED files: tut5-decoders.zip (6.1kB)
The decoder is implemented within a VHDL process. The code in a process runs sequentially, unlike the normal concurrent behaviour of VHDL.
A process in VHDL starts with the VHDL process keyword followed by parentheses: (). The parentheses contain a sensitivity list – the process is executed every time a signal in the sensitivity list changes.
The code that makes up the process is contained between begin and end process; as shown below:
process (A, EN) begin -- code that runs in the process is put here and runs sequentially end process;
The decoder uses the VHDL if keyword. An if statment is used in the process that allows one of the outputs of the decoder to be active only if the enable (EN) signal is high.
An if statement is constructed as follows:
if (EN = '1') then -- code places here will run only if the condition between parentheses is true end if;
An if statement is started with the if VHDL keyword followed by parentheses that contain the conditions being evaluated. Only if this condition is true, the code between the then keyword and the end if; statement is executed.
In the decoder, the value of the X output lines is set to a default value of "1111" (all high) using this line of code:
X <= "1111";
This is the first line of code that runs in the process. If EN is 0, then the code in the if construct will never run and the X outputs will always be high.
If EN becomes high (logic 1), then the code in the if construct will execute.
The case statement operates sequentially and can only be used inside a sequential block of code such as a process.
The case construct starts with the case keyword followed by an identifier (A in our example) and the is keyword. The case construct is terminated with end case;
One or more when statements are contained in the case construct.
In the decoder, the logic level of 0 is applied to the selected output (using X(?) <= '0';) when the A input matches one of the binary values in the when statements.
case A is when "00" => X(0) <= '0'; when "01" => X(1) <= '0'; when "10" => X(2) <= '0'; when "11" => X(3) <= '0'; when others => X <= "1111"; end case;
The default when others statement is necessary even if all the possible binary input combinations have been taken care of by when statements.