-- TITLE: ----------------------------------------------------------------- -- VHDL code for the ALU:(leaf cell, lowest hierarchy) -- ----------------------------------------------------------------- -- Description: Currently the case statements depend on the -- -- opcode and subOP values the controller encoding -- -- will change these when it is seriously -- implemented. -- -- -- -- -- ----------------------------------------------------------------- -- Course: Computer Architecture Project #2 -- ----------------------------------------------------------------- -- Date | Begin: 12.05.2001 -- -- | End : 12.05.2001 -- ----------------------------------------------------------------- -- Additional Comments: -- -- -- ----------------------------------------------------------------- -- ACCESSING DESIGN LIBRARIES and PACKAGES: ------------------------------------------- ---Library Clause: (Makes the written libraries visible to the design unit) library ieee,work; --library arithmetic ???? doesn't exist??? ----ieee & arithmetic are predefined resource libraries ----none are user defined resource libraries ----work is working(design) library (there can be only 1!!) ---use clause: ( Specifies Which packages/declarations within a package are --- required by the design unit --use arithmetic.std_logic_arith.ALL; use ieee.std_logic_1164.all; --use ieee.std_logic_arith.all; use ieee.numeric_std.all; --> library.package.contents of package(constants,components,etc.) ------------------------------------------------------------------------------ --ENTITY DECLARATION and PORT MAP: (Interface of design unit to external env.) ---------------------------------- entity ALU64 is -- ALU64: name of entity -- entity name must be unique in the design library!! port (Op1 : in std_logic_vector(63 downto 0); -- Op1 i/p of ALU Op2 : in std_logic_vector(63 downto 0); -- Op2 i/p of ALU SubOP : in std_logic_vector(7 downto 0); -- SubOP portion (7:0) of 32 bit instr. Opcode : in std_logic_vector(5 downto 0); -- comes from controller, BITWIDTH arbitrarily assigned for now!! ALUout : out std_logic_vector(63 downto 0)); -- ALU64 o/p end ALU64; ------------------------------------------------------------------------------ --ARCHITECTURE BODY: (Internal details, function of block) -------------------- architecture behav of ALU64 is -- behav: Architecture name, -- ALU64 : entity name, --Architecture name must be unique among architectures sharing same entity!! ---[0]Architecture Declarations (type definitions, ---[1]Object Declarations: (INternal signals & Set of interconnected components - for structural) ----------------------------------------------------------------------------------------------------- --OPCODE definitions/controller encoding def-s (will change when controller comes to play ----------------------------------------------------------------------------------------------------- constant add: std_logic_vector(5 downto 0) := "110000"; -- for packed add signed wrapping --and packed add unsigned saturation --and for lotsa other things!!!!@@@@@ constant cmp: std_logic_vector(5 downto 0) := "001000"; -- for cmp -- constant loadi.lo anf loadi.hi constant loadi_lo: std_logic_vector(5 downto 0) := "000101"; constant loadi_hi: std_logic_vector(5 downto 0) := "000100"; -- for the unimplemented mux.2.brcst constant mux_2_brcst: std_logic_vector(5 downto 0) := "110011"; -- for load.8.update, load.8 and store.8.update constant load_8_upd: std_logic_vector(5 downto 0) := "010111"; constant load_8: std_logic_vector(5 downto 0) := "010011"; constant store_8_upd: std_logic_vector(5 downto 0) := "011111"; ----------------------------------------------------------------------------------------------------- --SubOP definitions {instr(7:2)} - w/o sw (without last 2 bits that define subword size) ----------------------------------------------------------------------------------------------------- constant add_s_w: std_logic_vector(7 downto 2) := "000000"; -- add_signed_wrapping arithmetic constant add_u_s: std_logic_vector(7 downto 2) := "000001"; -- add_unsigned_saturation arithmetic constant add_s_s: std_logic_vector(7 downto 2) := "000010"; -- add_signed_saturation arithmetic constant add_inc: std_logic_vector(7 downto 2) := "000011"; -- add_increment ----------------------------------------------------------------------------------------------------- --Subword size definitions {instr(1:0)} - last 2 bits that define subword size ----------------------------------------------------------------------------------------------------- constant sw1: std_logic_vector(1 downto 0) := "00"; -- sw size 1 byte constant sw2: std_logic_vector(1 downto 0) := "01"; -- sw size 2 bytes constant sw4: std_logic_vector(1 downto 0) := "10"; -- sw size 4 bytes constant sw8: std_logic_vector(1 downto 0) := "11"; -- sw size 8 bytes begin -- of architecture ---[2]Concurrent Assignment Statements: (For Dataflow) ---[3]Processes: (Set of sequential assignments - for behavioral) DoOperation: process (Op1,Op2,Opcode,SubOP) --- Process Declarations: begin --of process --- sequential statements: case Opcode is when add => case SubOP(7 downto 2) is when add_s_w => -- burda super for loop ayari yapilir!! for i in 1 to sw gibi if SubOP(1 downto 0)=sw8 then ALUout <= std_logic_vector(signed(Op1) + signed(Op2)); -- we can do this arithmetic in in std_logic elsif SubOP(1 downto 0)=sw4 then ALUout(63 downto 32) <= std_logic_vector(signed(Op1(63 downto 32)) + signed(Op2(63 downto 32))); ALUout(31 downto 0) <= std_logic_vector(signed(Op1(31 downto 0)) + signed(Op2(31 downto 0))); elsif SubOP(1 downto 0)=sw2 then ALUout(63 downto 48) <= std_logic_vector(signed(Op1(63 downto 48)) + signed(Op2(63 downto 48))); ALUout(47 downto 32) <= std_logic_vector(signed(Op1(47 downto 32)) + signed(Op2(47 downto 32))); ALUout(31 downto 16) <= std_logic_vector(signed(Op1(31 downto 16)) + signed(Op2(31 downto 16))); ALUout(15 downto 0) <= std_logic_vector(signed(Op1(15 downto 0)) + signed(Op2(15 downto 0))); elsif SubOP(1 downto 0)=sw1 then ALUout(63 downto 56) <= std_logic_vector(signed(Op1(63 downto 56)) + signed(Op2(63 downto 56))); ALUout(55 downto 48) <= std_logic_vector(signed(Op1(55 downto 48)) + signed(Op2(55 downto 48))); ALUout(47 downto 40) <= std_logic_vector(signed(Op1(47 downto 40)) + signed(Op2(47 downto 40))); ALUout(39 downto 32) <= std_logic_vector(signed(Op1(39 downto 32)) + signed(Op2(39 downto 32))); ALUout(31 downto 24) <= std_logic_vector(signed(Op1(31 downto 24)) + signed(Op2(31 downto 24))); ALUout(23 downto 16) <= std_logic_vector(signed(Op1(23 downto 16)) + signed(Op2(23 downto 16))); ALUout(15 downto 8) <= std_logic_vector(signed(Op1(15 downto 8)) + signed(Op2(15 downto 8))); ALUout(7 downto 0) <= std_logic_vector(signed(Op1(7 downto 0)) + signed(Op2(7 downto 0))); else assert (false) -- assert always report "Invalid subword size in add_signed_wrap Instruction!" severity WARNING; end if; when add_u_s => -- BURDAN SOORASINI YAZMADIM!!!!!!!!!!!!!!!!!!!!!1 assert (false) -- assert always report "add_UNsigned_SAT Instruction!" severity WARNING; when others => assert (false) -- assert always report "Invalid SubOP for add instruction!!" severity WARNING; end case; when cmp => case SubOP(3 downto 0) is when "0000" | "0001" => -- EQ or NEQ ALUout <= std_logic_vector(signed(Op1) - signed(Op2)); -- subtract the operands for compare logic when "0010" | "0011" | "0100" | "0101" => -- LT or LE or GT or GE ALUout <= std_logic_vector(signed(Op1) - signed(Op2)); -- subtract the operands for compare logic when "0110" | "0111" | "1000" | "1001" => -- LTU or LEU or GTU or GEU -- ALUout <= std_logic_vector(UNsigned(Op1) - UNsigned(Op2)); -- subtract the operands for compare logic -- ALUout <= std_logic_vector(to_signed(to_integer(unsigned(Op1))-to_integer(unsigned(Op2)),64)); if signed(Op1)>=0 and signed(Op2)>=0 then ALUout <= std_logic_vector(UNsigned(Op1) - UNsigned(Op2)); elsif signed(Op1)>=0 and signed(Op2)<0 then ALUout <= std_logic_vector(to_signed(-1,64)); -- give -1 as Op2 is bigger as unsigned elsif signed(Op1)<0 and signed(Op2)>=0 then ALUout <= std_logic_vector(to_signed(1,64)); -- give 1 as Op1 is bigger as unsigned elsif signed(Op1)<0 and signed(Op2)<0 then ALUout <= std_logic_vector(UNsigned(Op1) - UNsigned(Op2)); end if; when others => assert (false) -- assert always report "Invalid SubOP for CMP instruction!!" severity WARNING; end case; when loadi_lo => ALUout(63 downto 32) <= x"00000000"; ALUout(15 downto 0) <= Op2(15 downto 0); ALUout(31 downto 16) <= x"0000"; when loadi_hi => ALUout(63 downto 32) <= x"00000000"; ALUout(31 downto 16) <= Op2(15 downto 0); ALUout(15 downto 0) <= x"0000"; when mux_2_brcst => ALUout <= Op1(15 downto 0)&Op1(15 downto 0)&Op1(15 downto 0)&Op1(15 downto 0); --repeat subwords when load_8_upd | load_8 | store_8_upd => ALUout <= std_logic_vector(signed(Op1) + signed(Op2)); -- add Rs1 + imm13 assume the o/p is taken care of -- by the controller to be written back or not --!! HERE MORE INSTRUCTIONS-->> when others => assert (false) -- assert always report "Invalid ALU function!!" severity WARNING; end case; end process DoOperation; --EOProcess end behav; --EOArchitecture