-- ############################################################################ -- # 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;