alu: logic cells von 1054 auf 1021 minimiert
authorBernhard Urban <lewurm@gmail.com>
Fri, 21 May 2010 04:33:21 +0000 (06:33 +0200)
committerBernhard Urban <lewurm@gmail.com>
Fri, 21 May 2010 04:33:21 +0000 (06:33 +0200)
src/alu.vhd

index 9abd7da3c30b8e52cfcc2cd818cab9c3b9112255..f3eb81c815f5277cbdf5d1597ee93d8d094c619f 100644 (file)
@@ -20,12 +20,9 @@ entity alu is
 end entity alu;
 
 architecture beh of alu is
-       type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDIV_CALC, SDIV_DONE,
-       SDONE, SERROR);
+       type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDIV_CALC, SDONE, SERROR);
        signal state_int, state_next : ALU_STATE;
        signal done_intern, error_intern : std_logic;
-       signal div_calc_done_int : std_logic;
-       signal div_calc_done2_int : std_logic;
        signal div_go_calc_int : std_logic;
        signal op3_int, op3_next, opM_int, opM_next : csigned;
        signal calc_done_int, calc_done_next : std_logic;
@@ -75,8 +72,7 @@ begin
        end process;
 
        -- next state
-       process(state_int, opcode, done_intern, error_intern, do_calc,
-               div_calc_done_int, div_calc_done2_int, div_go_calc_int)
+       process(state_int, opcode, done_intern, error_intern, do_calc, div_go_calc_int)
        begin
                -- set a default value for next state
                state_next <= state_int;
@@ -85,39 +81,27 @@ begin
                        when SIDLE =>
                                if do_calc = '1' then
                                        case opcode is
-                                               when ALU_ADD =>
-                                                       state_next <= SADD;
-                                               when ALU_SUB =>
-                                                       state_next <= SSUB;
-                                               when ALU_MUL =>
-                                                       state_next <= SMUL;
-                                               when ALU_DIV =>
-                                                       state_next <= SDIV;
-                                               when others =>
-                                                       state_next <= SIDLE;
+                                               when ALU_ADD => state_next <= SADD;
+                                               when ALU_SUB => state_next <= SSUB;
+                                               when ALU_MUL => state_next <= SMUL;
+                                               when ALU_DIV => state_next <= SDIV;
+                                               when others => state_next <= SIDLE;
                                        end case;
                                end if;
-                       when SADD | SSUB | SMUL | SDIV_DONE =>
+                       when SADD | SSUB | SMUL | SDIV | SDIV_CALC =>
+                               case state_int is
+                                       when SDIV =>
+                                               if div_go_calc_int = '1' then
+                                                       state_next <= SDIV_CALC;
+                                               end if;
+                                       when others => null;
+                               end case;
                                if done_intern = '1' then
                                        state_next <= SDONE;
                                end if;
                                if error_intern = '1' then
                                        state_next <= SERROR;
                                end if;
-                       when SDIV =>
-                               if div_go_calc_int = '1' then
-                                       state_next <= SDIV_CALC;
-                               end if;
-                               if div_calc_done2_int = '1' then
-                                       state_next <= SDIV_DONE;
-                               end if;
-                               if error_intern = '1' then
-                                       state_next <= SERROR;
-                               end if;
-                       when SDIV_CALC =>
-                               if div_calc_done_int = '1' then
-                                       state_next <= SDIV_DONE;
-                               end if;
                        when SDONE | SERROR =>
                                if do_calc = '0' then
                                        state_next <= SIDLE;
@@ -137,8 +121,6 @@ begin
        begin
                calc_done_next <= '0';
                calc_error_next <= '0';
-               div_calc_done_int <= '0';
-               div_calc_done2_int <= '0';
                div_go_calc_int <= '0';
                done_intern <= '0';
                error_intern <= '0';
@@ -220,13 +202,13 @@ begin
                                        -- darum folgende schreibweise ->
                                        if op1 = x"80000000" then
                                                -- so ziemlich das boeseste was passieren kann
-                                               div_calc_done2_int <= '1';
-                                               quo_next <= to_signed(-214748364,CBITS);
-                                               aktdiv_int_next <= to_signed(8,CBITS);
+                                               done_intern <= '1';
+                                               op3_next <= to_signed(-214748364,CBITS);
+                                               opM_next <= to_signed(8,CBITS);
                                        elsif (op1_var < op2_var) then
-                                               div_calc_done2_int <= '1';
-                                               quo_next <= to_signed(0,CBITS);
-                                               aktdiv_int_next <= op1_var;
+                                               done_intern <= '1';
+                                               op3_next <= to_signed(0,CBITS);
+                                               opM_next <= op1_var;
                                        else
                                                div_go_calc_int <= '1';
                                                dividend_msb_next <= dividend_msb_var;
@@ -259,16 +241,13 @@ begin
                                        sign_next <= sign_int;
                                else
                                        if sign_int = '1' then
-                                               quo_next <= (not quo_int) + 1;
+                                               op3_next <= (not quo_int) + 1;
                                        else
-                                               quo_next <= quo_int;
+                                               op3_next <= quo_int;
                                        end if;
-                                       div_calc_done_int <= '1';
+                                       opM_next <= aktdiv_int;
+                                       done_intern <= '1';
                                end if;
-                       when SDIV_DONE =>
-                               op3_next <= quo_int;
-                               opM_next <= aktdiv_int;
-                               done_intern <= '1';
                        when SDONE | SERROR =>
                                calc_done_next <= '1';
                                if (state_int = SERROR) then