-library IEEE;\r
-use IEEE.std_logic_1164.all;\r
-use IEEE.numeric_std.all;\r
-\r
-use work.alu_pkg.all;\r
-\r
-\r
-architecture behaviour of alu is\r
- component exec_op is\r
- port(\r
- --System inputs\r
- \r
- clk : in std_logic;\r
- reset : in std_logic;\r
- --operation inputs\r
- left_operand : in gp_register_t;\r
- right_operand : in gp_register_t;\r
- op_detail : in op_opt_t;\r
- alu_state : in alu_result_rec;\r
- alu_result : out alu_result_rec\r
- ); \r
- end component exec_op;\r
- \r
- signal add_result, and_result, or_result, xor_result, shift_result : alu_result_rec;\r
- signal left_o, right_o : gp_register_t;\r
- \r
-begin\r
-\r
- add_inst : entity work.exec_op(add_op)\r
- port map(clk,reset,left_o, right_o, op_detail, alu_state, add_result);\r
- \r
- and_inst : entity work.exec_op(and_op)\r
- port map(clk,reset,left_o, right_o, op_detail, alu_state, and_result);\r
-\r
- or_inst : entity work.exec_op(or_op)\r
- port map(clk,reset,left_o, right_o, op_detail, alu_state, or_result);\r
-\r
- xor_inst : entity work.exec_op(xor_op)\r
- port map(clk,reset,left_o, right_o, op_detail, alu_state, xor_result);\r
- \r
- shift_inst : entity work.exec_op(shift_op)\r
- port map(clk,reset,left_o, right_o, op_detail, alu_state, shift_result);\r
-\r
-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)\r
- variable result_v : alu_result_rec;\r
- variable res_prod : std_logic;\r
- variable cond_met : std_logic;\r
- variable mem_en : std_logic;\r
- variable mem_op : std_logic;\r
- variable alu_jump : std_logic;\r
- variable nop : std_logic;\r
-begin\r
- result_v := alu_state;\r
- \r
- res_prod := '1';\r
- mem_en := '0';\r
- mem_op := '0';\r
- alu_jump := '0';\r
- \r
- left_o <= left_operand;\r
- right_o <= right_operand;\r
-\r
- addr <= add_result.result;\r
- data <= right_operand;\r
- \r
- result_v.result := add_result.result;\r
-\r
- case cond is\r
- when COND_NZERO =>\r
- cond_met := not(alu_state.status.zero);\r
- when COND_ZERO =>\r
- cond_met := alu_state.status.zero;\r
- when COND_NOFLO =>\r
- cond_met := not(alu_state.status.oflo);\r
- when COND_OFLO =>\r
- cond_met := alu_state.status.oflo;\r
- when COND_NCARRY =>\r
- cond_met := not(alu_state.status.carry);\r
- when COND_CARRY =>\r
- cond_met := alu_state.status.carry;\r
- when COND_NSIGN =>\r
- cond_met := not(alu_state.status.sign);\r
- when COND_SIGN =>\r
- cond_met := alu_state.status.sign;\r
- when COND_ABOVE =>\r
- cond_met := not(alu_state.status.carry) and not(alu_state.status.zero);\r
- when COND_BEQ =>\r
- cond_met := alu_state.status.carry or alu_state.status.zero;\r
- when COND_GEQ =>\r
- cond_met := not(alu_state.status.sign xor alu_state.status.oflo);\r
- when COND_LT =>\r
- cond_met := alu_state.status.sign xor alu_state.status.oflo;\r
- when COND_GT =>\r
- cond_met := not(alu_state.status.zero) and not(alu_state.status.sign xor alu_state.status.oflo);\r
- when COND_LEQ =>\r
- cond_met := alu_state.status.zero or (alu_state.status.sign xor alu_state.status.oflo);\r
- when COND_ALWAYS =>\r
- cond_met := '1';\r
- when COND_NEVER =>\r
- cond_met := '0';\r
- when others => null;\r
- end case;\r
- \r
- nop := (alu_state.alu_jump xnor alu_state.brpr);\r
- cond_met := cond_met and nop;\r
-\r
- case op_group is\r
- when ADDSUB_OP =>\r
- result_v := add_result;\r
- when AND_OP =>\r
- result_v := and_result;\r
- when OR_OP =>\r
- result_v := or_result;\r
- when XOR_OP =>\r
- result_v := xor_result;\r
- when SHIFT_OP =>\r
- result_v := shift_result;\r
- when LDST_OP =>\r
- res_prod := '0';\r
- mem_op := '1';\r
- if op_detail(IMM_OPT) = '1' then\r
- result_v.result := right_operand;\r
- res_prod := '1';\r
- mem_op := '0';\r
- end if;\r
- if op_detail(ST_OPT) = '1' then\r
- right_o <= displacement;\r
- mem_en := '1';\r
- end if;\r
- when JMP_OP =>\r
- if op_detail(JMP_REG_OPT) = '0' then\r
- left_o <= prog_cnt;\r
- end if;\r
- alu_jump := '1';\r
- when JMP_ST_OP => null;\r
- \r
- end case;\r
- \r
-\r
- result_v.status.zero := '0';\r
- if result_v.result = REG_ZERO then\r
- result_v.status.zero := '1';\r
- end if;\r
- \r
- result_v.status.sign := result_v.result(gp_register_t'high);\r
-\r
- if (op_detail(NO_PSW_OPT) = '1') or (cond_met = '0') then\r
- result_v.status := alu_state.status;\r
- end if;\r
- \r
- result_v.reg_op := not(op_detail(NO_DST_OPT)) and res_prod and cond_met;\r
- result_v.mem_en := mem_en and cond_met;\r
- result_v.mem_op := mem_op and cond_met;\r
- result_v.alu_jump := alu_jump and cond_met;\r
- result_v.brpr := brpr and nop;\r
- \r
- if (result_v.alu_jump = '0') and (brpr = '1') then\r
- result_v.result := (others => '0');\r
- result_v.result(prog_cnt'range) := std_logic_vector(unsigned(prog_cnt)+1);\r
- --result_v.reg_op := '1';\r
- end if;\r
-\r
- alu_result <= result_v;\r
- \r
-end process calc; \r
-\r
-end architecture behaviour;\r
-\r
+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;
+