VHDL coding tips and tricks: 2016

Monday, October 3, 2016

How to use multiple architectures within the same entity?

I want to answer this question, a reader asked me through a comment:

How to use component syntax if you want to use another architecture of (say) halfadder? Sometimes I have different architectures of the same entity (with slightly different implementations) for checking how it works. By default ISE uses the last one. Do you know how to do this without making a new entity?

Yes, this is possible. Its pretty simple, so I will show you the method with an example code. 

I have implemented a one bit full adder circuit, using two half adders. The half adder entity has two architectures. First architecture is implemented using logic gates such as XOR and AND. Second architecture is implemented in a behavioral way. Both these architectures are written under the same entity name, in the same vhdl file.

See these lines in the FA.vhd code,
    HA1 : entity work.HA(Gate_level)  port map(a,b,s1,c1); 
    HA2 : entity work.HA(Behavioral) port map(s1,c,sum,c2); 

You can see how we specify, which architecture to use, by mentioning the architecture name in brackets.


HA.vhd:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

--half adder entity
entity HA is
port(a,b : in std_logic;
            sum,carry : out std_logic
        );
end HA;

-------------------Architecture 1 starts here.
architecture Gate_level of HA is

begin

sum <= a xor b;
carry <= a and b;

end architecture Gate_level;
-------------------Architecture 1 ends here.

-------------------Architecture 2 starts here.
architecture Behavioral of HA is

begin

process(a,b)
begin
    if(= '0and b = '0') then
        sum <= '0';
        carry <= '0';
    elsif(= '0and b = '1') then
        sum <= '1';
        carry <= '0';
    elsif(= '1and b = '0') then
        sum <= '1';
        carry <= '0';
    else
        sum <= '0';
        carry <= '1';
    end if;
end process;    

end architecture Behavioral;
-------------------Architecture 2 ends here.

FA.vhd:


library IEEE;
use IEEE.std_logic_1164.all;

--full adder entity
entity FA is
port (  a,b,c : in std_logic;
            sum,carry : out std_logic
        );  
end FA;

architecture struct of FA is
    
    signal s1,c1,c2 : std_logic;    --intermediate signals

begin
    
    --direct/entity instantation method.
    HA1 : entity work.HA(Gate_level)  port map(a,b,s1,c1); --use architecture 1 of HA entity
    HA2 : entity work.HA(Behavioral) port map(s1,c,sum,c2); --use architecture 2 of HA entity
    
    carry <= c1 or c2;
    
end architecture struct;

testbench code,  tb.vhd:


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
ENTITY tb IS
END tb;
 
ARCHITECTURE behavior OF tb IS 
 
    signal a,b,c : std_logic := '0';
   signal sum,carry : std_logic;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: entity work.FA PORT MAP (a,b,c,sum,carry);

   -- Applying inputs to the entity under test
   stim_proc: process
   begin        
      a <= '0'; b <= '0';   c <= '0';   wait for 100 ns;
        a <= '0';   b <= '0';   c <= '1';   wait for 100 ns;
        a <= '0';   b <= '1';   c <= '0';   wait for 100 ns;
        a <= '0';   b <= '1';   c <= '1';   wait for 100 ns;
        a <= '1';   b <= '0';   c <= '0';   wait for 100 ns;
        a <= '1';   b <= '0';   c <= '1';   wait for 100 ns;
        a <= '1';   b <= '1';   c <= '0';   wait for 100 ns;
        a <= '1';   b <= '1';   c <= '1';   wait for 100 ns;
        wait;
   end process;

END;