stack op
[calu.git] / cpu / src / alu_b.vhd
index 9a0749155f5c5070eacfb780f779a2516fb67f29..c9e832e9c9ed321c37360beea36476d66e57ad04 100755 (executable)
-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, pval, pval_nxt)\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
-       \r
-       variable pinc_v, pwr_en_v : std_logic;\r
-       \r
-       variable prog_cnt_nxt : std_logic_vector(prog_cnt'range);\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
-       pinc_v := '0';\r
-       pwr_en_v := '0';\r
-       \r
-       paddr <= (others =>'0');\r
-       \r
-       result_v.result := add_result.result;\r
-       prog_cnt_nxt := std_logic_vector(unsigned(prog_cnt)+1);\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
-               --right_o <= displacement;\r
-               addr <= std_logic_vector(unsigned(left_operand)+unsigned(displacement));\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
-                        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 => \r
-               left_o <= prog_cnt;\r
-               mem_en := '1';\r
-               alu_jump := '1';\r
-               mem_op := '1';\r
-               pinc_v := '1';\r
-               pwr_en_v := '1';\r
-               paddr <= (others =>'0');\r
-               \r
-               addr <= pval;\r
-               data <= prog_cnt_nxt;\r
-               if op_detail(RET_OPT) = '1' then\r
-                       addr <= pval_nxt;\r
-                       mem_en := '0';\r
-                       pinc_v := '0';\r
-                       res_prod := '0';\r
-               end if;\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
-       pwr_en_v := pwr_en_v and cond_met;\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) := prog_cnt_nxt;\r
-               --result_v.reg_op := '1';\r
-       end if;\r
-\r
-       -- if result_v.mem_op = '0' then --- do this if selecting enable for extension modules is too slow.\r
-               -- addr <= (others => '0');\r
-       -- end if;\r
-       alu_result <= result_v;\r
-       pinc <= pinc_v;\r
-       pwr_en <= pwr_en_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;
+       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;
+                                        
+                                        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 := '1';
+               if op_detail(PUSH_OPT) = '1' then
+                       mem_en := '1';
+                       pinc_v := '1';
+                       res_prod := '0';
+                       addr <= pval_nxt;
+                       data <= left_o;
+               else
+                       addr <= std_logic_vector(unsigned(pval_nxt)-4);
+               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;
+