library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.alu_pkg.all; architecture behaviour of alu is component exec_op is port( --System inputs clk : in std_logic; reset : in std_logic; --operation inputs left_operand : in gp_register_t; right_operand : in gp_register_t; op_detail : in op_opt_t; alu_state : in alu_result_rec; alu_result : out alu_result_rec ); end component exec_op; signal add_result, and_result, or_result, xor_result, shift_result : alu_result_rec; begin add_inst : exec_op port map(clk,reset,left_operand, right_operand, op_detail, alu_state, add_result); and_inst : exec_op port map(clk,reset,left_operand, right_operand, op_detail, alu_state, and_result); or_inst : exec_op port map(clk,reset,left_operand, right_operand, op_detail, alu_state, or_result); xor_inst : exec_op port map(clk,reset,left_operand, right_operand, op_detail, alu_state, xor_result); shift_inst : exec_op port map(clk,reset,left_operand, right_operand, op_detail, alu_state, shift_result); calc: process(condition, op_group, op_detail ,alu_state,and_result,add_result,or_result,xor_result,shift_result) variable result_v : alu_result_rec; variable res_prod : std_logic; variable cond_met : std_logic; variable mem_en : std_logic; begin result_v := alu_state; result_v.result := add_result.result; res_prod := '1'; mem_en := '0'; addr <= add_result; case condition is when COND_NZERO => cond_met := not(alu_state.status.zero); when COND_ZERO => cond_met := alu_state.status.zero; when COND_NOFLO => cond_met := not(alu_state.status.oflo); when COND_OFLO => cond_met := alu_state.status.oflo; when COND_NCARRY => cond_met := not(alu_state.status.carry); when COND_CARRY => cond_met := alu_state.status.carry; when COND_NSIGN => cond_met := not(alu_state.status.sign); when COND_SIGN => cond_met := alu_state.status.sign; when COND_ABOVE => cond_met := not(alu_state.status.carry) and not(alu_state.status.zero); when COND_BEQ => cond_met := alu_state.status.carry or alu_state.status.zero; when COND_GEQ => cond_met := not(alu_state.status.sign xor alu_state.status.oflo); when COND_LT => cond_met := alu_state.status.sign xor alu_state.status.oflo; when COND_GT => cond_met := not(alu_state.status.zero) and not(alu_state.status.sign xor alu_state.status.oflo); when COND_LEQ => cond_met := alu_state.status.zero or (alu_state.status.sign xor alu_state.status.oflo); when COND_ALWAYS => cond_met := '1'; when COND_NEVER => cond_met := '0'; end case; case op_group is when ADDSUB_OP => result_v := add_result; when AND_OP => result_v := and_result; when OR_OP => result_v := or_result; when XOR_OP => result_v := xor_result; when SHIFT_OP => result_v := shift_result; end case; if result_v.result = REG_ZERO then result_v.status.zero := '1'; end if; result_v.status.sign := result_v.result(gp_register_t'high); if (op_detail(NO_PSW_OPT) = '1') or (cond_met = '0') then result_v.status := alu_state.status; end if; result_v.new_val := not(op_detail(NO_DST_OPT)) and res_prod and cond_met; result_v.mem_en := mem_en and cond_met; data <= add_result; alu_result <= result_v; end process calc; end architecture behaviour; configuration alu_cfg of alu is for behaviour for add_inst : exec_op use entity work.exec_op(add_op); end for; for and_inst : exec_op use entity work.exec_op(and_op); end for; for or_inst : exec_op use entity work.exec_op(or_op); end for; for xor_inst : exec_op use entity work.exec_op(xor_op); end for; for shift_inst : exec_op use entity work.exec_op(shift_op); end for; end for; end configuration alu_cfg;