-- MIPS I system -- Copyright 2011-2012 Stefan Schuermans -- Copyleft GNU public license V2 or later -- http://www.gnu.org/copyleft/gpl.html LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE work.mips_types.all; ENTITY e_mips_alu IS PORT ( i_alu: IN t_alu; i_op1: IN std_logic_vector(31 DOWNTO 0); i_op2: IN std_logic_vector(31 DOWNTO 0); o_res: OUT std_logic_vector(31 DOWNTO 0) ); END ENTITY e_mips_alu; ARCHITECTURE a_mips_alu OF e_mips_alu IS SIGNAL s_shift_arith: std_logic; SIGNAL s_shift_left: std_logic; SIGNAL s_shift_out: std_logic_vector(31 DOWNTO 0); COMPONENT e_mips_shifter IS PORT ( i_arith: IN std_logic; i_left: IN std_logic; i_val: IN std_logic_vector(31 DOWNTO 0); i_num: IN std_logic_vector(31 DOWNTO 0); o_val: OUT std_logic_vector(31 DOWNTO 0) ); END COMPONENT e_mips_shifter; BEGIN shifter: e_mips_shifter PORT MAP ( i_arith => s_shift_arith, i_left => s_shift_left, i_val => i_op2, i_num => i_op1, o_val => s_shift_out ); p_alu: PROCESS(i_alu, i_op1, i_op2, s_shift_out) VARIABLE v_op1_s: signed(31 DOWNTO 0); VARIABLE v_op2_s: signed(31 DOWNTO 0); VARIABLE v_op1_u: unsigned(31 DOWNTO 0); VARIABLE v_op2_u: unsigned(31 DOWNTO 0); BEGIN v_op1_s := signed(i_op1); v_op2_s := signed(i_op2); v_op1_u := unsigned(i_op1); v_op2_u := unsigned(i_op2); s_shift_arith <= '0'; s_shift_left <= '0'; CASE i_alu IS WHEN alu_add => o_res <= std_logic_vector(v_op1_s + v_op2_s); WHEN alu_and => o_res <= i_op1 AND i_op2; WHEN alu_nor => o_res <= i_op1 NOR i_op2; WHEN alu_or => o_res <= i_op1 OR i_op2; WHEN alu_sub => o_res <= std_logic_vector(v_op1_s - v_op2_s); WHEN alu_sll => s_shift_arith <= '0'; s_shift_left <= '1'; o_res <= s_shift_out; WHEN alu_sra => s_shift_arith <= '1'; s_shift_left <= '0'; o_res <= s_shift_out; WHEN alu_srl => s_shift_arith <= '0'; s_shift_left <= '0'; o_res <= s_shift_out; WHEN alu_slt => IF v_op1_s < v_op2_s THEN o_res <= X"00000001"; ELSE o_res <= X"00000000"; END IF; WHEN alu_sltu => IF v_op1_u < v_op2_u THEN o_res <= X"00000001"; ELSE o_res <= X"00000000"; END IF; WHEN alu_up => o_res <= i_op2(15 DOWNTO 0) & X"0000"; WHEN alu_xor => o_res <= i_op1 XOR i_op2; WHEN OTHERS => o_res <= X"00000000"; END CASE; END PROCESS p_alu; END ARCHITECTURE a_mips_alu;