X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Falu_b.vhd;h=746fbc3489e85f38a74e287224d97e8e7f481b9d;hb=0ba0c7effbaf554ad42db51334581859a0570bfa;hp=9a0749155f5c5070eacfb780f779a2516fb67f29;hpb=ce413b7c5c11c0d2ffda62afbe8a84bbbb7c9d5f;p=calu.git diff --git a/cpu/src/alu_b.vhd b/cpu/src/alu_b.vhd index 9a07491..746fbc3 100755 --- a/cpu/src/alu_b.vhd +++ b/cpu/src/alu_b.vhd @@ -1,201 +1,243 @@ -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_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_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'; - - left_o <= left_operand; - right_o <= right_operand; - - addr <= add_result.result; - data <= right_operand; - - pinc_v := '0'; - pwr_en_v := '0'; - - paddr <= (others =>'0'); - - result_v.result := add_result.result; - prog_cnt_nxt := std_logic_vector(unsigned(prog_cnt)+1); - 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 => - 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; - res_prod := '1'; - mem_op := '0'; - end if; - if op_detail(ST_OPT) = '1' then - mem_en := '1'; - end if; - when JMP_OP => - if op_detail(JMP_REG_OPT) = '0' then - 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; - - 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_jump := alu_jump and cond_met; - result_v.brpr := brpr and nop; - - 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; - +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_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, 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'; + hword_op := '0'; + byte_op := '0'; + alu_jump := '0'; + + left_o <= left_operand; + right_o <= right_operand; + + addr <= add_result.result; + data <= right_operand; + + pinc_v := '0'; + pwr_en_v := '0'; + + paddr <= (others =>'0'); + + result_v.result := add_result.result; + 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; + addr(DATA_ADDR_WIDTH + 3) <= '0'; + when AND_OP => + result_v := and_result; + addr(DATA_ADDR_WIDTH + 3) <= '0'; + when OR_OP => + result_v := or_result; + addr(DATA_ADDR_WIDTH + 3) <= '0'; + when XOR_OP => + result_v := xor_result; + addr(DATA_ADDR_WIDTH + 3) <= '0'; + when SHIFT_OP => + result_v := shift_result; + addr(DATA_ADDR_WIDTH + 3) <= '0'; + 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; + + 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'; + addr(DATA_ADDR_WIDTH + 3) <= '0'; + end if; + if op_detail(ST_OPT) = '1' then + 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_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; + 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_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; +