VHDL programming

VHDL(very high speed integrated circuit Hardware Descriptive Language)  was originally developed at the behest of the U.S Department of Defense in order to document the behavior of the ASICs that supplier companies were including in equipment. That is to say, VHDL was developed as an alternative to huge, complex manuals which were subject to implementation-specific details

VHDL program is used to implement the hardware modules(like multipliers, ALUs etc.,) on FPGAs   and ASICs etc.,


To simulate the VHDL programs we can use ModelSim software, Active HDL, xilinx etc., but i use   ModelSim.

to see how to use Modelsim follow this link
http://www.youtube.com/watch?v=VTMelKXXmho

A vhdl program has the following syntax. this is just basic syntax 


library ieee;

use ieee.std_logic_1164.all;

ENTITY <entity_name> IS

PORT(INPUTS:IN STD_LOGIC;
           OUPUTS:OUT STD_LOGIC
           ------------------------------------
           ---------- etc.,
           );
END <entity_name>;

ARCHITECTURE <architecture_name> OF <entity_name> IS

COMPONENT DECLARATION;
SIGNAL <signal_name>:<signal_type>;
BEGIN
         ---design flow---
END <architecture_name>;

---------------------------------------------------------------------------------------------------------------

1).A simple Full Adder progam as follows:-


library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

entity fulladder is
  port(a,b,c:in std_logic;
         sum,carry:out std_logic
         );
end fulladder;

architecture fulladder of fulladder is
begin
  sum<= a xor b xor c;
  carry<=( a and b) or (b and c)or(c and a);
end fulladder;




-------------------------------------------------------------------------------------------------------------


To test the functionality we can give signal in the run time or by writing TEST_BENCH code..

always writing test bench code is more appreciable 

the TEST_BENCH code for the above full adder is shown here


------------------------------------------------------------------------------------------------------------


library IEEE;

USE IEEE.STD_LOGIC_1164.ALL;
entity fulladder is
  port(a,b,c:inout std_logic;
  sum,carry:out std_logic);
end fulladder;
architecture fulladder of fulladder is
begin
  sum<= a xor b xor c;
  carry<=( a and b) or (b and c)or(c and a);
DUT:process
begin
  wait for 3 ns;
  a<='1';
  b<='1';
  c<='0';wait for 10 ns;
  
  end process; 
end fulladder;




-------------------------------------------------------------------------------------------------------------------

Full Subtracter programming:-


library ieee;

use ieee.std_logic_1164.all;

entity full_subtractor is

  port(A,B,Bin:in std_logic;
       D,Bout:out std_logic
       );
end full_subtractor;

architecture full_sub of full_subtractor is

begin
  D<= A xor B xor Bin;
  Bout<=(B and (not A)) or ((A xnor B) and Bin);
end full_sub;




  TEST_BENCH CODE


-- full subtractor

library ieee;
use ieee.std_logic_1164.all;

entity full_subtractor is

  port(A,B,Bin:inout std_logic;
       D,Bout:out std_logic
       );
end full_subtractor;

architecture full_sub of full_subtractor is

begin
  D<= A xor B xor Bin;
  Bout<=(B and (not A)) or ((A xnor B) and Bin);
DUT:process
    begin
       wait for 3 ns;
       A<='0';
       B<='1';
       Bin<='1';wait for 10 ns;
       end process;
end full_sub;
-------------------------------------------------------------------------------------------------------------


D Flip Flop:-


library ieee;

use ieee.std_logic_1164.all;
  
  entity dff_async_reset is
      port (
          data  :inout  std_logic;-- Data input
          clk   :inout  std_logic;-- Clock input
          reset :inout  std_logic;-- Reset input
          q     :out std_logic -- Q output   
           );
  end entity;
  
  architecture rtl of dff_async_reset is
  begin
      process (clk, reset) begin
          if (reset = '0') then
              q <= '0';
          elsif (rising_edge(clk)) then
              q <= data;
          end if;
      end process;
  end architecture;

Symbol:-




Result:-



-----------------------------------------------------------------------------------------------------------

T_Flip_Flop:-



library ieee;

    use ieee.std_logic_1164.all;

entity tff_async_reset is

    port (
        data  :in  std_logic; -- Data input
        clk   :in  std_logic; -- Clock input
        reset :in  std_logic; -- Reset input
        q     :out std_logic  -- Q output

    );

end entity;

architecture rtl of tff_async_reset is

    signal t :std_logic;
begin
    process (clk, reset,data) begin
        if (reset = '0') then
            t <= '0';
        elsif (rising_edge(clk)) then
            t <= not data;
        end if;
    end process;
    q <= t;
end architecture;



Symbol:-




Result:-





----------------------------------------------------------------------------------------------------------------------

3-bit UP-Counter:-


----------------------------------------
----------- 3-bit counter---------------
-----------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter_3bit is

  port(
       clk:in std_logic;
       reset:in std_logic;
       cout:out std_logic_vector(2 downto 0)
       );
end counter_3bit;

architecture counter_3bit of counter_3bit is

begin
  process(clk)
    variable count:std_logic_vector(2 downto 0);
   begin
     if reset='0' then
      count := "000";
    elsif rising_edge(clk) then
      count := count+1;
    end if;

 cout<=count;


end process;


 end counter_3bit;


Circuit connections:-





  

Result:-




-------------------------------------------------------------------------------------------------------------------
4x1 Multiplexer:-


-- 4x1 mux


library ieee;

use ieee.std_logic_1164.all;

entity mux_4 is

   port(I:inout std_logic_vector(3 downto 0);
        s0,S1:inout std_logic;
        y:out std_logic
        );
  end mux_4;
  
  architecture mux_4 of mux_4 is
  signal x:integer;
  begin
    
        x <= 0 when s0 = '0' and s1 = '0' else
             1 when s0 = '1' and s1 = '0' else
             2 when s0 = '0' and s1 = '1' else
             3 when s0 = '1' and s1 = '1' else
             4;
       
      
        y <= I(0) when x = 0 else
             I(1) when x = 1 else
             I(2) when x = 2 else
             I(3) when x = 3 else
             'Z';
     DUT:process  -- test bench code
     begin
        I(0) <= '0','0' after 5 ns, '0' after 10 ns, '1' after 15 ns, '0' after 20 ns;
        I(1) <= '0','1' after 5 ns, '0' after 10 ns, '0' after 15 ns, '1' after 20 ns;
        I(2) <= '1','0' after 5 ns, '1' after 10 ns, '1' after 15 ns, '0' after 20 ns;
        I(3) <= '1','1' after 5 ns, '1' after 10 ns, '0' after 15 ns, '1' after 20 ns;
        s0 <= '0';
        s1 <= '0'; wait for 5 ns;
        s0 <= '1';
        s1 <= '0'; wait for 5 ns;
        s0 <= '0';
        s1 <= '1'; wait for 5 ns;
        s0 <= '1';
        s1 <= '1'; wait for 5 ns;
         
        wait;
      end process;
  end mux_4;  
        
Symbol:-





Result:-


-----------------------------------------------------------------------------------------------------------------------
8-bit UP Counter:-


library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;
  entity up_counter_8bit is
      port (
          cout   :out std_logic_vector (7 downto 0);
          enable :in  std_logic;                    
          clk    :in  std_logic;                    
          reset  :in  std_logic     );
  end entity;
    architecture rtl of up_counter_8bit is
   signal count :std_logic_vector (7 downto 0);
  begin
      process (clk, reset) begin
          if (reset = '1') then
              count <= (others=>'0');
          elsif (rising_edge(clk)) then
              if (enable = '1') then
                  count <= count + 1;
              end if;
          end if;
      end process;
 cout <= count;
  end architecture;

Result:-


-----------------------------------------------------------------------------------------------------------------------

16-bit Addition:-



library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use work.processor_package.all;

entity addition_of_16bit is
     generic(n:natural:=16);
     port(A:inout std_logic_vector(15 downto 0);
          B:inout std_logic_vector(15 downto 0);
          --cin:in std_logic;
          sum:inout std_logic_vector(15 downto 0);
          carry:out std_logic;
          s:inout std_logic
          );
end addition_of_16bit;
architecture addition_of_16bit of addition_of_16bit is
begin
      addition:process(A,B)
           variable tempsum:std_logic_vector(15 downto 0);
           variable tempcarry:std_logic;
          begin
             if s='1' then         
                tempcarry:='0';
                for i in 0 to (n-1) loop
                   tempsum(i):=A(i) xor B(i) xor tempcarry;
                   tempcarry:=(A(i) and B(i)) or (B(i) and tempcarry) or (tempcarry and A(i));
                end loop;
                sum<=tempsum;
                carry<=tempcarry;
            end if;
            end process addition;  
            DUT:process
            begin
              wait for 3 ns;
              s<='1' ; wait for 10 ns;
              A<="1010101010101010"; wait for 10 ns;
              B<="0101010101010101"; wait for 1 ns;          
              s<='1'; wait for 20 ns;
              A<="0001000100010001"; wait for 10 ns;
              B<="1001100110011001"; wait for 1 ns;
              wait;
            end process DUT;    
end addition_of_16bit;


Result:-



-----------------------------------------------------------------------------------------------------------------------


2's complement :-  16-bit



library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity twoscomplement is
        port(A:inout std_logic_vector(15 downto 0);
             B:out std_logic_vector(15 downto 0)
             );
  end twoscomplement;
architecture twoscomplement of twoscomplement is
begin
  process(A)
    variable inv:unsigned (15 downto 0);
    begin
      inv := unsigned (not A);
      inv := inv+1;
      B<= std_logic_vector(inv);
    end process;
      
end twoscomplement;

Result:-



-----------------------------------------------------------------------------------------------------------------------

16-bit subtractor:-



library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;

entity subtraction_of_16bit is
  generic(n:natural:=16);
  port(A:inout std_logic_vector((n-1) downto 0);
       B:inout std_logic_vector((n-1) downto 0);
       s:inout std_logic;
       sum:out std_logic_vector((n-1) downto 0);
       carry:out std_logic      
       );
end subtraction_of_16bit;

architecture subtraction_of_16bit of subtraction_of_16bit is
signal tempB:std_logic_vector((n-1) downto 0);
signal tempcarry:std_logic;
signal tempsum,sum1:std_logic_vector((n-1) downto 0);
begin
         U1:entity work.twoscomplement port map(B,tempB);
subtraction:process(A,tempB)
                     variable tempsum1:std_logic_vector((n-1) downto 0);
                     variable tempcarry1:std_logic;
                     begin
                      if s='0' then
                        tempcarry1:='0';
                        for i in 0 to (n-1) loop
                         tempsum1(i):=A(i) xor tempB(i) xor tempcarry1;
                         tempcarry1:=(A(i) and tempB(i)) or (tempB(i) and tempcarry1) or (tempcarry1 and A(i));
                        end loop;                
                        tempcarry<=tempcarry1;
                        tempsum<=tempsum1;
                      end if;
         end process subtraction;
       U2:entity work.twoscomplement port map(tempsum,sum1);
        carrycheck:process(tempcarry,tempsum,sum1)
            begin                   
            if(tempcarry='0') then
               sum<=sum1;
               carry<=tempcarry;
            else
             sum<=tempsum;
carry<=tempcarry;
            end if;
      end process carrycheck; 
end subtraction_of_16bit;

----------------------------------------------------------------------------------------------------------------------

16-bit Registers:-

library ieee;
use ieee.std_logic_1164.all;
package reg is
  type bit16 is array (15 downto 0) of std_logic;
  type reg8_16 is array (7 downto 0) of bit16;
-- type sel is array (2 downto 0) of std_logic;
end package;

library ieee;
use ieee.std_logic_1164.all;
use work.reg.all;
--use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
--use ieee.std_logic_textio.all ;

entity registers is
  generic(n:natural:=16);
  port(Reg_in:inout bit16;
       Reg_out:out bit16;
     --  s:in std_logic_vector(2 downto 0);
       en:inout std_logic;
       clk:inout std_logic;
       rw:inout std_logic
       );
  end registers;
  architecture registers of registers is
signal tempreg:bit16;
begin
  process
  begin
    for i in  1 to 1000 loop
    clk<='1'; wait for 5 ns;
    clk<='0';wait for 5 ns;
  end loop;
  wait;
end process;
 ReadWrite:process(clk,Reg_in,rw)
    variable Reg:bit16;
    variable x:bit16;
    begin
      --- writing data to the corresponding register
    if clk'event and clk='1' then
          if rw='0' then
             Reg := Reg_in;
          elsif rw='1' then
             tempreg <= Reg;
          end if;
        end if;
    end process ReadWrite;
    Reg_out <= tempreg;
    DUT:process
    begin
      en<='1';
      rw<='0' after 10 ns, '1' after 20 ns;
      Reg_in<="0101010100000000" after 10 ns;
   wait;
   end process DUT;
end registers;

Result:-




----------------------------------------------------------------------------------------------------------------------

4-bit parallel adder Package Creation:-

library ieee;
use ieee.std_logic_1164.all;

package p4bitadder is
  function adder(a,b:in std_logic_vector;cin:in std_logic) return std_logic_vector;
  end;

package body p4bitadder is
 function adder(a,b:in std_logic_vector;cin:in std_logic) return std_logic_vector is
 variable x,s:std_logic_vector(4 downto 0);
begin
  s(0):=a(0) xor b(0) xor cin;
  x(0):=((a(0) and b(0)) or (b(0) and cin ) or (cin and a(0)));
  s(1):=a(1) xor b(1) xor x(0);
  x(1):=((a(1) and b(1)) or (b(1) and x(0) ) or (x(0) and a(1)));
  s(2):=a(2) xor b(2) xor x(1);
  x(2):=((a(2) and b(2)) or (b(2) and x(1) ) or (x(1) and a(2)));
  s(3):=a(3) xor b(3) xor x(2);
  x(3):=((a(3) and b(3)) or (b(3) and x(2) ) or (x(2) and a(3)));
  s(4):=x(3);
   return s;
         end  function;
    end package body;
--use the package
    library ieee;
use ieee.std_logic_1164.all;
use work.p4bitadder.all;
entity fulladder_altera is
  port(a,b:in std_logic_vector(3 downto 0);
                            cin:in std_logic;
        s:out std_logic_vector(3 downto 0);
        cout:out std_logic
                        );
      end fulladder_altera;    
architecture fulladder_altera of fulladder_altera is
    signal x:std_logic_vector(4 downto 0);
     begin
      process(a,b,cin)
      begin
         x<=adder(a,b,cin);
      end process;
     s<=x(3 downto 0);
     cout<=x(4);
end fulladder_altera;

Result:-






---------------------------------------------------------------------------------------------------------------------

16x1 multiplexer:-

library ieee;
use ieee.std_logic_1164.all;

entity mux_16 is
  generic(n:integer:=16);
  port(I:in std_logic_vector((n-1) downto 0);
       y:out std_logic;
       s:in std_logic_vector(3 downto 0)
       );
end mux_16;

architecture mux_16 of mux_16 is
begin
        y <= I(0) when s="0000" else
           I(1) when s="0001" else
           I(2) when s="0010" else
           I(3) when s="0011" else
           I(4) when s="0100" else
           I(5) when s="0101" else
           I(6) when s="0110" else
           I(7) when s="0111" else
           I(8) when s="1000" else
           I(9) when s="1001" else
           I(10) when s="1010" else
           I(11) when s="1011" else
           I(12) when s="1100" else
           I(13) when s="1101" else
           I(14) when s="1110" else
           I(15) when s="1111"  ;
     
end mux_16;

Symbol:-






Result:-




-----------------------------------------------------------------------------------------------------------------------

3 to 8 Decoder:-

library ieee;
use ieee.std_logic_1164.all;                                         

entity decoder_3to8 is
  port(A,B,C: in std_logic;
        en: in std_logic;
       y: out std_logic_vector(7 downto 0)
       );
end decoder_3to8;

architecture decoder of decoder_3to8 is
signal x:integer;
begin
   x <= 0 when A='0' and B='0' and C='0' else
       1 when A='1' and B='0' and C='1' else
       2 when A='0' and B='1' and C='0' else
       3 when A='1' and B='1' and C='0' else
       4 when A='0' and B='0' and C='1' else
       5 when A='1' and B='0' and C='1' else
       6 when A='0' and B='1' and C='1' else
       7 when A='1' and B='1' and C='1' else
       8;
  process(en,x)
  begin    
    if en='1' then
   case x is
    when 0 => y <="00000001";
    when 1 => y <="00000010";
    when 2 => y <="00000100";
    when 3 => y <="00001000";
    when 4 => y <="00010000";
    when 5 => y <="00100000";
    when 6 => y <="01000000";
    when 7 => y <="10000000";
    when others => y <="00000000";
    end case;
  end if;
  end process;
end decoder;

Symbol:-





Result:-





--------------------------------------------------------------------------------------------------------------------

8 to 3 Encoder:-



library ieee;
use ieee.std_logic_1164.all;
entity encoder_8to3 is
  port(I: in std_logic_vector(7 downto 0);
       en:in std_logic;
       y:out std_logic_vector(2 downto 0)
       );
end encoder_8to3;

architecture encoder of encoder_8to3 is
begin
  process(en,I)
    begin
  if en='1' then
    case I is
      when "00000001" => y <= "000";
      when "00000010" => y <= "001";
      when "00000100" => y <= "010";
      when "00001000" => y <= "011";
      when "00010000" => y <= "100";
      when "00100000" => y <= "101";
      when "01000000" => y <= "110";
      when "10000000" => y <= "111";
      when others => y <= "ZZZ";
      end case;
    end if;
  end process;
  end encoder;

Symbol:-





Result:-





-----------------------------------------------------------------------------------------------------------------------

 8x4 multiplier:-



library ieee;
use ieee.std_logic_1164.all;
entity and2 is
  port(a,b:in std_logic;
        c:out std_logic
        );
end and2;

architecture and2 of and2 is
begin
   c<= a and b;
end and2;
-- designing gate level binary full adder
library ieee;
use ieee.std_logic_1164.all;
entity f_adder is
  port(A,B,Cin,M_gate:in std_logic;
        x:inout std_logic;
        Cout,sum:out std_logic
        );
  end f_adder;
  architecture fa of f_adder is
  component and2 is
    port(a,b:in std_logic;
          c:out std_logic
          );
   end component;
   begin
       u: and2 PORT MAP(A,M_gate,x);
       sum<=x xor B xor Cin;
       Cout<=(x and B) or (B and cin) or (cin and x);
       end fa;
      -- designing gate level 8-bit binary full adder
      library ieee;
   use ieee.std_logic_1164.all;
      entity fa8 IS
    GENERIC(set:integer:=7);
    port(A,B:in std_logic_vector(set downto 0);
         Cin:in std_logic;
         M_gate:in std_logic;
         carry:out std_logic;
         sum:out std_logic_vector(set downto 0)
         );
    end fa8;
architecture fa8 of fa8 is
    component f_adder is
      port(A,B,Cin,M_gate:in std_logic;
            Cout,sum:out std_logic
            );
      end component;
      signal c:std_logic_vector(7 downto 0);
      signal cary:std_logic;
      begin
          cary<= cin;
          u1: f_adder PORT MAP (A(0),B(0),cary,M_gate,c(0),sum(0));
          u2: f_adder PORT MAP (A(1),B(1),c(0),M_gate,c(1),sum(1));
          u3: f_adder PORT MAP (A(2),B(2),c(1),M_gate,c(2),sum(2));
          u4: f_adder PORT MAP (A(3),B(3),c(2),M_gate,c(3),sum(3));
          u5: f_adder PORT MAP (A(4),B(4),c(3),M_gate,c(4),sum(4));
          u6: f_adder PORT MAP (A(5),B(5),c(4),M_gate,c(5),sum(5));
          u7: f_adder PORT MAP (A(6),B(6),c(5),M_gate,c(6),sum(6));
          u8: f_adder PORT MAP (A(7),B(7),c(6),M_gate,c(7),sum(7));
             carry <= c(7);      
      end fa8;

-- designing 8x4 multiplier from 8-bit gate level binary full adder
    --package creatrion
    library ieee;
    use ieee.std_logic_1164.all;
    package length is
    TYPE sum_length1 is array(7 downto 0) of std_logic;
    TYPE sum_length is array(3 downto 0) of sum_length1;
    end length;
   
    library ieee;
    use ieee.std_logic_1164.all;
    use WORK.length.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all;
   
    entity mul is
      port(A:in std_logic_vector(7 downto 0);
           B:in std_logic_vector(3 downto 0);
          -- cin:in std_logic;
           output:out std_logic_vector(11 downto 0)
           );
     end mul;
    
     architecture mul of mul is
     component fa8 is
port(A,B:in std_logic_vector(7 downto 0);
            cin:in std_logic;
            M_gate:in std_logic;
            carry:out std_logic;
            sum:out std_logic_vector(7 downto 0)
            );
          end component;
     signal cout:std_logic_vector(3 downto 0);
     signal x1,x2,x3,x4,t1,t2,t3:std_logic_vector(7 downto 0);
     begin
     
       U1: fa8 PORT MAP(A,"00000000",'0',B(0),cout(0),x1);
       t1<=cout(0) & x1(7 downto 1);
       U2: fa8 PORT MAP(A,t1,'0',B(1),cout(1),x2);
       t2<=cout(1) & x2(7 downto 1);
       U3: fa8 PORT MAP(A,t2,'0',B(2),cout(2),x3);
        t3<= cout(2) & x3(7 downto 1);
       U4: fa8 PORT MAP(A,t3,'0',B(3),cout(3),x4);
       output<=cout(3) & x4 & x3(0) & x2(0) & x1(0);
    end mul;

Symbol:-




Result:-




--------------------------------------------------------------------------------------------------------------------

 2-point FFT-DFT using VHDL Programming:


Click here to view and download FFT using VHDL



MORE STUFF is coming soon......