alu_mul-fail: minimal beispiel...
[hwmod.git] / src / alu.vhd
index de0b6a6aa32c4c0d95cce84bfe13a4edfb032a28..013764244ca693f037a5e025355cf0e8e90561e9 100644 (file)
@@ -13,93 +13,81 @@ entity alu is
                op2 : in csigned;
                op3 : out csigned;
                do_calc : in std_logic;
-               ack : in std_logic;
                calc_done : out std_logic
        );
 end entity alu;
 
 architecture beh of alu is
-       type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDONE);
-       signal state, state_next : ALU_STATE;
+       type ALU_STATE is (SIDLE, SMUL, SDONE);
+       signal state_int, state_next : ALU_STATE;
        signal done_intern : std_logic;
+       signal op3_int, op3_next : csigned;
+       signal calc_done_int, calc_done_next : std_logic;
 begin
+       op3 <= op3_int;
+       calc_done <= calc_done_int;
+
        -- sync
        process(sys_clk, sys_res_n)
        begin
                if sys_res_n = '0' then
-                       state <= SIDLE;
+                       state_int <= SIDLE;
+                       op3_int <= (others => '0');
+                       calc_done_int <= '0';
                elsif rising_edge(sys_clk) then
-                       state <= state_next;
+                       state_int <= state_next;
+                       op3_int <= op3_next;
+                       calc_done_int <= calc_done_next;
                end if;
        end process;
 
        -- next state
-       process(state, opcode, done_intern)
+       process(state_int, opcode, done_intern, do_calc)
        begin
                -- set a default value for next state
-               state_next <= state;
+               state_next <= state_int;
                -- next state berechnen
-               case state is
+               case state_int is
                        when SIDLE =>
-                               case opcode is
-                                       when ADD =>
-                                               state_next <= SADD;
-                                       when SUB =>
-                                               state_next <= SSUB;
-                                       when MUL =>
-                                               state_next <= SMUL;
-                                       when DIV =>
-                                               state_next <= SDIV;
-                                       when others =>
-                                               state_next <= SIDLE;
-                               end case;
-                       when SADD =>
-                               if done_intern = '1' then
-                                       state_next <= SDONE;
-                               end if;
-                       when SSUB =>
-                               if done_intern = '1' then
-                                       state_next <= SDONE;
+                               if do_calc = '1' then
+                                       case opcode is
+                                               when ALU_MUL =>
+                                                       state_next <= SMUL;
+                                               when others =>
+                                                       state_next <= SIDLE;
+                                       end case;
                                end if;
                        when SMUL =>
                                if done_intern = '1' then
                                        state_next <= SDONE;
                                end if;
-                       when SDIV =>
-                               if done_intern = '1' then
-                                       state_next <= SDONE;
-                               end if;
                        when SDONE =>
-                               if ack = '1' then
+                               if do_calc = '0' then
                                        state_next <= SIDLE;
                                end if;
                end case;
        end process;
 
        -- output
-       process(state)
+       process(state_int, op1, op2, op3_int)
+               variable multmp : signed(((2*CBITS)-1) downto 0);
        begin
-               op3 <= (others => '0');
-               calc_done <= '0';
+               done_intern <= '0';
+               calc_done_next <= '0';
+               op3_next <= (others => '0');
 
-               case state is
+               case state_int is
                        when SIDLE =>
-                               done_intern <= '0';
-                       when SADD =>
-                               op3 <= op1 + op2;
-                               done_intern <= '1';
-                       when SSUB =>
-                               op3 <= op1 - op2;
-                               done_intern <= '1';
+                               null;
                        when SMUL =>
-                               op3 <= op1 * op2;
-                               done_intern <= '1';
-                       when SDIV =>
-                               op3 <= op1 / op2;
+                               multmp := op1 * op2;
+                               op3_next(CBITS-1) <= multmp((2*CBITS)-1);
+                               op3_next((CBITS-2) downto 0) <= multmp((CBITS-2) downto 0);
                                done_intern <= '1';
                        when SDONE =>
-                               done_intern <= '1';
-                               calc_done <= '1';
+                               calc_done_next <= '1';
+                               op3_next <= op3_int;
                end case;
        end process;
 end architecture beh;
+