X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Falu_b.vhd;h=60a14bf867acc3aae5c85484d14c8f3b79581a9e;hb=d4a0ea68530da911bc41c44b24d244c7dc198190;hp=8399d6087e835d11d1375fc5a43e4c7d5bf10c27;hpb=37835209871e507ea3956c9fd616a6546b39d991;p=calu.git diff --git a/cpu/src/alu_b.vhd b/cpu/src/alu_b.vhd index 8399d60..60a14bf 100755 --- a/cpu/src/alu_b.vhd +++ b/cpu/src/alu_b.vhd @@ -1,158 +1,237 @@ -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; - +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; - signal left, right : gp_register_t; - -begin - - add_inst : entity work.exec_op(add_op) - port map(clk,reset,left, right, op_detail, alu_state, add_result); - - and_inst : entity work.exec_op(and_op) - port map(clk,reset,left, right, op_detail, alu_state, and_result); - - or_inst : entity work.exec_op(or_op) - port map(clk,reset,left, right, op_detail, alu_state, or_result); - - xor_inst : entity work.exec_op(xor_op) - port map(clk,reset,left, right, op_detail, alu_state, xor_result); - - shift_inst : entity work.exec_op(shift_op) - port map(clk,reset,left, right, op_detail, alu_state, shift_result); - -calc: process(left_operand, right_operand,displacement, cond, 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; + signal left_o, right_o : gp_register_t; + +begin + + add_inst : entity work.exec_op(add_op) + port map(clk,reset,left_o, right_o, op_detail, alu_state, add_result); + + and_inst : entity work.exec_op(and_op) + port map(clk,reset,left_o, right_o, op_detail, alu_state, and_result); + + or_inst : entity work.exec_op(or_op) + port map(clk,reset,left_o, right_o, op_detail, alu_state, or_result); + + xor_inst : entity work.exec_op(xor_op) + port map(clk,reset,left_o, right_o, op_detail, alu_state, xor_result); + + shift_inst : entity work.exec_op(shift_op) + port map(clk,reset,left_o, right_o, op_detail, alu_state, shift_result); + +calc: process(left_operand, right_operand,displacement, cond, op_group, op_detail ,alu_state,and_result,add_result,or_result,xor_result,shift_result, prog_cnt,brpr, pval, pval_nxt) + variable result_v : alu_result_rec; + variable res_prod : std_logic; + variable cond_met : std_logic; variable mem_en : std_logic; - variable mem_op : std_logic; - variable alu_jmp : std_logic; -begin - result_v := alu_state; - - res_prod := '1'; + variable mem_op, hword_op, byte_op : std_logic; + variable alu_jump : std_logic; + variable nop : std_logic; + + variable pinc_v, pwr_en_v : std_logic; + + variable prog_cnt_nxt : std_logic_vector(prog_cnt'range); +begin + result_v := alu_state; + + res_prod := '1'; mem_en := '0'; - mem_op := '0'; - alu_jump := '0'; + mem_op := '0'; + hword_op := '0'; + byte_op := '0'; + alu_jump := '0'; - left <= left_operand; - right <= right_operand; + left_o <= left_operand; + right_o <= right_operand; addr <= add_result.result; - data <= right_operand; + data <= right_operand; + + pinc_v := '0'; + pwr_en_v := '0'; + + paddr <= (others =>'0'); result_v.result := add_result.result; - - case cond 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'; - when others => null; - end case; - - cond_met := cond_met and (alu_state.alu_jmp xnor alu_state.brpr); - - 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 => + if (op_detail(DIRECT_JUMP_OPT) = '0') then + prog_cnt_nxt := std_logic_vector(unsigned(prog_cnt)+1); + else + prog_cnt_nxt := prog_cnt; + end if; + case cond 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'; + when others => null; + end case; + + nop := (alu_state.alu_jump xnor alu_state.brpr); + cond_met := cond_met and nop; + + 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; - when LDST_OP => + when LDST_OP => res_prod := '0'; mem_op := '1'; + --right_o <= displacement; + addr <= std_logic_vector(unsigned(left_operand)+unsigned(displacement)); if op_detail(IMM_OPT) = '1' then - result_v.result := right_operand; + + result_v.result := right_operand; + + if (op_detail(LDI_REPLACE_OPT) = '0') then + result_v.result := left_operand; + if (op_detail(LOW_HIGH_OPT) = '1') then + result_v.result(31 downto 16) := right_operand(31 downto 16); + else + result_v.result(15 downto 0) := right_operand(15 downto 0); + end if; + end if; + res_prod := '1'; mem_op := '0'; end if; if op_detail(ST_OPT) = '1' then - right <= displacement; mem_en := '1'; end if; + + hword_op := op_detail(HWORD_OPT); + byte_op := op_detail(BYTE_OPT); + when JMP_OP => if op_detail(JMP_REG_OPT) = '0' then - left <= prog_cnt; + left_o <= prog_cnt; + end if; + alu_jump := '1'; + when JMP_ST_OP => + left_o <= prog_cnt; + mem_en := '1'; + alu_jump := '1'; + mem_op := '1'; + pinc_v := '1'; + pwr_en_v := '1'; + paddr <= (others =>'0'); + + addr <= pval; + data <= prog_cnt_nxt; + if op_detail(RET_OPT) = '1' then + addr <= pval_nxt; + mem_en := '0'; + pinc_v := '0'; + res_prod := '0'; end if; - result_v.alu_jmp := '1'; - when JMP_ST_OP => null; - end case; - - - result_v.status.zero := '0'; - 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.reg_op := not(op_detail(NO_DST_OPT)) and res_prod and cond_met; + when STACK_OP => + mem_op := '1'; + pwr_en_v := op_detail(PWREN_OPT); + if op_detail(PUSH_OPT) = '1' then + mem_en := '1'; + pinc_v := '1'; + res_prod := '0'; + addr <= pval; + data <= left_operand; + else + addr <= pval_nxt; + end if; + + end case; + + + result_v.status.zero := '0'; + 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.reg_op := not(op_detail(NO_DST_OPT)) and res_prod and cond_met; result_v.mem_en := mem_en and cond_met; - result_v.mem_op := mem_op and cond_met; - result_v.alu_jmp := alu_jmp and cond_met; - - alu_result <= result_v; - -end process calc; - -end architecture behaviour; - + result_v.mem_op := mem_op and cond_met; + result_v.alu_jump := alu_jump and cond_met; + result_v.brpr := brpr and nop; + + result_v.hw_op := hword_op and cond_met; + result_v.byte_op := byte_op and cond_met; + + pwr_en_v := pwr_en_v and cond_met; + + if (result_v.alu_jump = '0') and (brpr = '1') then + result_v.result := (others => '0'); + result_v.result(prog_cnt'range) := prog_cnt_nxt; + --result_v.reg_op := '1'; + end if; + + -- if result_v.mem_op = '0' then --- do this if selecting enable for extension modules is too slow. + -- addr <= (others => '0'); + -- end if; + alu_result <= result_v; + pinc <= pinc_v; + pwr_en <= pwr_en_v; + +end process calc; + +end architecture behaviour; +