synthesizeable_vhdl-model-library:patras:alus

ALUS library

The ALUS library consists of the following 4 generic components :

  • addN: N-bit adder
  • subN: N-bit subtractor
  • adsbN: N-bit adder / subtractor
  • aluNf: N-bit general purpose ALU with flags

The ALUS library can be verified with this testbench: test_alus

These particular components implements all the logical and arithmetic operations, such as addition and substraction, with a variable word length of the operands. In the next two tables, the general's ALU operations encoding is shown.

Arithmetic operations:

Operation Expression Mnemonic Op Code
Add A + B + CIN ADD 1001111
Subtract A + B~ + CIN SUB 1000111
Reverse Subtract B - A - CIN~  SBR 1001101
Negate A A~ + CIN NEGA 1000001
Negate B B~ + CIN NEGB 1000100
Increment A A + CIN INCA 1000011
Increment B B + CIN INCB 1001100
Decrement A A - CIN~ DECA 1001011
Decrement B B - CIN~ DECB 1001110
Negated Add A~ + B~ + CIN NADD 1000101
Decrement Not A A~ + CIN~ NDECA 1001001
Decrement Not B B~ + CIN~ NDECB 1000110

Logical Operations:

Operation Expression Mnemonic Op Code
Ones -1 ONES 0100000
Zeros 0 ZEROS 0100010
Pass A A EQUA 0100011
Pass B B EQUB 0101100
Not A A~ NOTA 0100001
Not B B~ NOTB 0100100
And A * B AND 1010101
And Complement A A~ * B ANDCA 1010111
And Complement B A * B~ ANDCB 1011110
Nand (A * B)~ NAND 0010101
Or A + B OR 0011111
Or Complement A A~ + B ORCA 0011101
Or Complement b A + B~ ORCB 0010111
Nor (A + B)~ NOR 1011111
Exclusive Or A ^ B XOR 0101111
Exclusive Nor (A ^ B)~ XNOR 1101111
alus.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    alus.vhd                                                 #
-- #                                                                          #
-- # Component  :    addN : N-Bit Adder                                       #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
-- addN Entity Description
entity addN is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN: in std_ulogic;
      COUT: out std_ulogic
   );
end addN;
 
-- addN Architecture Description
architecture rtl of addN is
   signal pre_D : std_ulogic_vector(N downto 0);
   signal pre_OV : std_ulogic;
begin
   ARITHMETIC_Process: process(A,B,CIN)
      variable fct_out : std_ulogic_vector(N downto 0);
      variable a_ext,b_ext : std_ulogic_vector(N downto 0);
      variable carry_ext : std_ulogic_vector(1 downto 0);
      variable msb : integer;
   begin
      -- zero extend inputs to include carry bit
      a_ext := '0' & A;
      b_ext := '0' & B;
      carry_ext := '0' & CIN;
 
      -- ADD
      fct_out := a_ext + b_ext + carry_ext;
 
      -- Assign to signal for use outside process
      pre_D <= fct_out;
 
      -- Calculate overflow bit
      if (a_ext(N-1) = b_ext(N-1) and fct_out(N-1) = not a_ext(N-1)) then 
         pre_OV <= '1';
      else
         pre_OV <= '0';
      end if;
   end process ARITHMETIC_Process;
 
   -- Assign the outputs
   D <= pre_D(N-1 downto 0);
 
   -- Assign flags
   COUT <= pre_D(N);
end rtl;
alus.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    alus.vhd                                                 #
-- #                                                                          #
-- # Component  :    subN : N-Bit Subtractor                                  #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
-- subN Entity Description
entity subN is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN: in std_ulogic;
      COUT: out std_ulogic
   );
end subN;
 
-- subN Architecture Description
architecture rtl of subN is
      signal pre_D : std_ulogic_vector(N downto 0);
   signal pre_OV : std_ulogic;
begin
   ARITHMETIC_Process: process(A,B,CIN)
      variable fct_out : std_ulogic_vector(N downto 0);
      variable a_ext,b_ext : std_ulogic_vector(N downto 0);
      variable carry_ext : std_ulogic_vector(1 downto 0);
      variable msb : integer;
   begin
      -- zero extend inputs to include carry bit
      a_ext := '0' & A;
      b_ext := '0' & not B;
      carry_ext := '0' & CIN;
 
      -- SUB
      fct_out := a_ext + b_ext + carry_ext;
 
      -- Assign to signal for use outside process
      pre_D <= fct_out;
 
      -- Calculate overflow bit
      if (a_ext(N-1) = b_ext(N-1) and fct_out(N-1) = not a_ext(N-1)) then 
         pre_OV <= '1';
      else
         pre_OV <= '0';
      end if;
   end process ARITHMETIC_Process;
 
   -- Assign the outputs
   D <= pre_D(N-1 downto 0);
 
   -- Assign flags
   COUT <= pre_D(N);
end rtl;
alus.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    alus.vhd                                                 #
-- #                                                                          #
-- # Component  :    adsbN : N-Bit Adder/Subtractor                           #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
-- adsbN Entity Description
entity adsbN is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN,SUB: in std_ulogic;
      COUT: out std_ulogic
   );
end adsbN;
 
-- adsbN Architecture Description
architecture rtl of adsbN is
      signal pre_D : std_ulogic_vector(N downto 0);
   signal pre_OV : std_ulogic;
begin
   ARITHMETIC_Process: process(A,B,CIN,SUB)
      variable fct_out : std_ulogic_vector(N downto 0);
      variable a_ext,b_ext : std_ulogic_vector(N downto 0);
      variable carry_ext : std_ulogic_vector(1 downto 0);
      variable msb : integer;
   begin
      -- zero extend inputs to include carry bit
      a_ext := '0' & A;
         if (SUB = '1') then
            b_ext := '0' & not B;
         else
            b_ext := '0' & B;
         end if;
      carry_ext := '0' & CIN;
 
      -- ADDSUB
      fct_out := a_ext + b_ext + carry_ext;
 
      -- Assign to signal for use outside process
      pre_D <= fct_out;
 
      -- Calculate overflow bit
      if (a_ext(N-1) = b_ext(N-1) and fct_out(N-1) = not a_ext(N-1)) then 
         pre_OV <= '1';
      else
         pre_OV <= '0';
      end if;
   end process ARITHMETIC_Process;
 
   -- Assign the outputs
   D <= pre_D(N-1 downto 0);
 
   -- Assign flags
   COUT <= pre_D(N);
end rtl;
alus.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    alus.vhd                                                 #
-- #                                                                          #
-- # Component  :    aluNf : N-Bit ALU with Flags                             #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
-- aluNf Entity Description
entity aluNf is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      OP: in std_ulogic_vector(6 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN: in std_ulogic;
      COUT,EQ,GT,LT,OV: out std_ulogic
   );
end aluNf;
 
-- aluNf Architecture Description
architecture rtl of aluNf is
      signal pre_D : std_ulogic_vector(N downto 0);
   signal pre_OV : std_ulogic;
   signal pre_EQ : std_ulogic;
   signal pre_LT : std_ulogic;
   constant minus_one: std_ulogic_vector(N-1 downto 0) := (OTHERS => '1');
 
   FUNCTION vector_eq_zero  (vect : std_ulogic_vector ) RETURN BOOLEAN IS
     VARIABLE len : integer := vect'LENGTH;
     VARIABLE vector : std_ulogic_vector(len-1 downto 0);
     VARIABLE equal_zero : BOOLEAN;
   BEGIN
     -- Check zero equality
     equal_zero := true;
     for i in len-1 DOWNTO 0 loop
       if vector(i) /= '0' then
         equal_zero := false;
         exit;
       end if;
     end loop;
     RETURN equal_zero;
   END vector_eq_zero;
 
begin
   ARITHMETIC_Process: process(A,B,CIN,OP)
      variable fct_out : std_ulogic_vector(N downto 0);
      variable a_ext,b_ext : std_ulogic_vector(N downto 0);
      variable minus_one_ext : std_ulogic_vector(N downto 0);
      variable not_a_ext,not_b_ext : std_ulogic_vector(N downto 0);
      variable carry_ext : std_ulogic_vector(1 downto 0);
      variable is_logical : integer range 0 to 1;
      variable msb : integer;
   begin
      -- zero extend inputs to include carry bit
      a_ext := '0' & A;
      b_ext := '0' & B;
      not_a_ext := '0' & not A;
      not_b_ext := '0' & not B;
      minus_one_ext := '0' & minus_one;
      is_logical := 0;
      carry_ext := '0' & CIN;
 
      -- ALU
      case OP is
         -----------------------
         -- Logical Functions --
         -----------------------
         -- Output constants
         when "0100010" => is_logical := 1;
             fct_out := (OTHERS => '1');
         when "0100000" => is_logical := 1;
             fct_out := (OTHERS => '0');
 
         -- Pass throughs and complements
         when "0100011" => is_logical := 1;
             fct_out := a_ext;
         when "0101100" => is_logical := 1;
             fct_out := b_ext;
         when "0100001" => is_logical := 1;
             fct_out := not a_ext;
         when "0100100" => is_logical := 1;
             fct_out := not b_ext;
 
         -- AND functions
         when "1010101" => is_logical := 1;
             fct_out := a_ext and b_ext;
         when "1010111" => is_logical := 1;
             fct_out := (not a_ext) and b_ext;
         when "1011110" => is_logical := 1;
             fct_out := a_ext and (not b_ext);
         when "0010101" => is_logical := 1;
             fct_out := not (a_ext and b_ext);
 
         -- OR functions
         when "0011111" => is_logical := 1;
             fct_out := a_ext or b_ext;
         when "0011101" => is_logical := 1;
             fct_out := (not a_ext) or b_ext;
         when "0010111" => is_logical := 1;
             fct_out := a_ext or (not b_ext);
         when "1011111" => is_logical := 1;
             fct_out := not (a_ext or b_ext);
 
         -- XOR functions
         when "0101111" => is_logical := 1;
             fct_out := a_ext xor b_ext;
         when "1101111" => is_logical := 1;
             fct_out := not (a_ext xor b_ext);
 
         --------------------------
         -- Arithmetic Functions --
         --------------------------
         -- Add/Subtract functions
         when "1001111" => fct_out := a_ext + b_ext + carry_ext;
         when "1000111" => fct_out := a_ext + not_b_ext + carry_ext;
         when "1001101" => fct_out := b_ext + not_a_ext + carry_ext;
         when "1000101" => fct_out := not_a_ext + not_b_ext + carry_ext;
 
         -- Negate functions
         when "1000001" => fct_out := not_a_ext + carry_ext;
         when "1000100" => fct_out := not_b_ext + carry_ext;
 
         -- Increment functions
         when "1000011" => fct_out := a_ext + carry_ext;
         when "1001100" => fct_out := b_ext + carry_ext;
 
         -- Decrement functions
         when "1001011" => fct_out := a_ext + minus_one_ext + carry_ext;
         when "1001110" => fct_out := b_ext + minus_one_ext + carry_ext;
         when "1001001" => fct_out := not_a_ext + minus_one_ext + carry_ext;
         when "1000110" => fct_out := not_b_ext + minus_one_ext + carry_ext;
 
         -- Unknown input
         when others => fct_out := (OTHERS => 'X');
      end case;
      if (is_logical = 0) then
          COUT <= fct_out(N);
      else
          COUT <= 'X';
      end if;
 
      -- Assign to signal for use outside process
      pre_D <= fct_out;
 
      -- Calculate overflow bit
      if (a_ext(N-1) = b_ext(N-1) and fct_out(N-1) = not a_ext(N-1)) then 
         pre_OV <= '1';
      else
         pre_OV <= '0';
      end if;
   end process ARITHMETIC_Process;
 
   -- Assign the outputs
   D <= pre_D(N-1 downto 0);
 
   -- Assign flags
   pre_EQ <= '1' when vector_eq_zero(pre_D(N-1 downto 0)) else '0';
   pre_LT <= (pre_OV xor pre_D(N-1));
   GT <= not pre_EQ and not pre_LT;
   LT <= pre_LT;
   EQ <= pre_EQ;
   OV <= pre_OV;
end rtl;
test_alus.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    test_alus.vhd                                            #
-- #                                                                          #
-- # Component  :    test_alus : Test Bench for various arithmetic components.#
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
entity test_alus IS
END test_alus;
 
ARCHITECTURE rtl OF test_alus IS
 
COMPONENT addN
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN: in std_ulogic;
      COUT: out std_ulogic
   );
end COMPONENT;
 
COMPONENT subN is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN: in std_ulogic;
      COUT: out std_ulogic
   );
end COMPONENT;
 
COMPONENT adsbN is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN,SUB: in std_ulogic;
      COUT: out std_ulogic
   );
END COMPONENT;
 
COMPONENT aluNf is
   generic(N: INTEGER := 4);
   port(
      A: in std_ulogic_vector(N-1 downto 0);
      B: in std_ulogic_vector(N-1 downto 0);
      OP: in std_ulogic_vector(6 downto 0);
      D: out std_ulogic_vector(N-1 downto 0);
      CIN: in std_ulogic;
      COUT,EQ,GT,LT,OV: out std_ulogic
   );
END COMPONENT;
 
 FOR ALL : addN USE ENTITY WORK.addN(rtl);
 FOR ALL : subN USE ENTITY WORK.subN(rtl);
 FOR ALL : adsbN USE ENTITY WORK.adsbN(rtl);
 FOR ALL : aluNf USE ENTITY WORK.aluNf(rtl);
 
 CONSTANT N : integer := 8;
 SIGNAL A,B,D1,D2,D3,D4 : std_ulogic_vector(N-1 downto 0);
 SIGNAL OP : std_ulogic_vector(6 downto 0);
 SIGNAL CIN,EQ,GT,LT,OV,SUB : std_ulogic;
 
 BEGIN
 
Adder : addN 
             GENERIC MAP (
                          N=>N
                         )
	     PORT MAP (
		       A=>A,
		       B=>B,
		       CIN=>CIN,
		       D=>D1,
		       COUT=>OPEN
		      );	 
 
Subtractor : subN 
             GENERIC MAP (
                          N=>N
                         )
	     PORT MAP (
		       A=>A,
		       B=>B,
		       CIN=>CIN,
		       D=>D2,
		       COUT=>OPEN
		      );			   
 
Adder_Subtractor : adsbN 
             GENERIC MAP (
                          N=>N
                         )
	     PORT MAP (
		       A=>A,
		       B=>B,
		       CIN=>CIN,
		       D=>D3,
		       SUB=>SUB,
		       COUT=>OPEN
		      );		
 
ALU : aluNf
             GENERIC MAP (
                          N=>N
                         )
	     PORT MAP (
		       A=>A,
		       B=>B,
		       CIN=>CIN,
		       OP=>OP,
		       D=>D4,
		       COUT=>OPEN,
		       EQ=>EQ,
		       GT=>GT,
		       LT=>LT,
		       OV=>OV
		      );		      
 
 
SUB <= 	'0','1' AFTER 200 ns;
CIN <= '0';
 
A <= "10101000",
     "01011001" AFTER 100 ns, 
     "11011011" AFTER 200 ns, 
     "01101001" AFTER 300 ns;
B <= "00111000",
     "01001011" AFTER 100 ns, 
     "01010001" AFTER 200 ns, 
     "11001001" AFTER 300 ns;
OP <= "1010101",
      "0011111" AFTER 100 ns,	
      "0101111" AFTER 200 ns,	
      "1000001" AFTER 300 ns;
 
END rtl;