-------------------------------------------------------------- -- File: alu.vhd - MIPS ALU -- Author: <--- PUT your name here -- Creation: 10/2/00 -- Verified: <--- Make any necessary changes -- Version: 1.0 -------------------------------------------------------------- -- Requires: pkgmips.vhd LIBRARY IEEE; USE work.mips.all; USE IEEE.Std_Logic_1164.all; USE IEEE.std_logic_unsigned.all; --use ieee.std_logic_arith.all; -------------------------------------------------------------- -- FUNCTION: alu - Mips ALU as shown in Figure 4.19 of -- Hennessy and Patterson. The ALU must be -- implemented so that it can be used as -- a slice to build a wider ALU. -- INPUTS: Ain - A input to ALU -- Bin - B input to ALU -- Opertion - ALU operation -- "000" - and -- "001" - or -- "010" - add -- "110" - subtract -- "111" - set on less than -- Cin - Carry in -- Less - To least sig bit of Result when -- Operation = "111" -- Binvert - Invert B signal. -- OUTPUTS: Result - Otput of ALU -- Overflow - Overflow signal -- Set - Set = Sign bit of adder -- Zero - If Result = "0..0" then Zero = '1' else -- Zero = '0' -------------------------------------------------------------- ENTITY ALU IS GENERIC(Slice: Integer := DWordSize); PORT(Ain, Bin: IN std_logic_vector(Slice-1 downto 0); Cin: IN std_logic; Result: OUT std_logic_vector(Slice-1 downto 0); Cout: OUT std_logic; Operation: IN std_logic_vector(2 downto 0); Binvert: IN std_logic; Less: IN std_logic := '0'; Set: OUT std_logic := '0'; Overflow: OUT std_logic := '0'; Zero: OUT std_logic ); END ENTITY ALU; ARCHITECTURE behav OF ALU IS SIGNAL SUM: std_logic_vector(Slice downto 0); SIGNAL ANDout, ORout: std_logic_vector(Slice-1 downto 0); SIGNAL B: std_logic_vector(Slice-1 downto 0); SIGNAL ResTmp: std_logic_vector(Slice-1 DOWNTO 0); SIGNAL Fix: std_logic := '0'; BEGIN Fix <= (Ain(Slice-1) AND B(Slice-1) AND NOT SUM(Slice-1)) OR ((NOT Ain(Slice-1)) AND (NOT B(Slice-1)) AND SUM(Slice-1)); Overflow <= Fix; Set <= SUM(Slice - 1) XOR Fix; Result <= ResTmp; Z: PROCESS(ResTmp) IS VARIABLE I: INTEGER; VARIABLE Znot: std_logic; BEGIN Znot := '0'; FOR I IN 0 TO Slice - 1 LOOP Znot := Znot OR ResTmp(I); END LOOP; Zero <= NOT Znot; END PROCESS Z; ANDout <= Ain and Bin; ORout <= Ain or Bin; SUM <= '0'&Ain + B + Cin; WITH Binvert SELECT B <= Bin WHEN '0', (NOT Bin) WHEN '1', (others => 'U') WHEN OTHERS; MUX: PROCESS(ANDout, ORout, SUM, Operation, Less) is BEGIN CASE Operation is WHEN "000" => -- AND ResTmp <= ANDout; Cout <= '0'; WHEN "001" => -- OR ResTmp <= ORout; Cout <= '0'; WHEN "010" | "110" => -- Add or SUB ResTmp <= SUM(Slice - 1 downto 0); Cout <= SUM(Slice); WHEN "111" => -- Set on less than ResTmp(0) <= Less; ResTmp(Slice - 1 downto 1) <= (OTHERS => '0'); Cout <= SUM(Slice); WHEN others => ResTmp <= (others => 'U'); Cout <= SUM(Slice); END CASE; END PROCESS MUX; END ARCHITECTURE behav;