parser: refactor (von drei auf zwei prozess-modell)
authorBernhard Urban <lewurm@gmail.com>
Mon, 24 May 2010 13:49:38 +0000 (15:49 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 24 May 2010 17:26:14 +0000 (19:26 +0200)
logic elements: 3029 -> 3002

spartan3e/.gitignore
src/parser.vhd

index 9118e9d9aded17a48847d867314858feb5f6a760..58b0ee8c1c8e1996aad6db1c041b25b7b37fdb4c 100644 (file)
@@ -27,3 +27,4 @@ generated/
 smartpreview.twr
 xlnx_auto_0_xdb/
 *.log
 smartpreview.twr
 xlnx_auto_0_xdb/
 *.log
+_xmsgs/
index b4b9593f5d69fdbabb11d70f8a0f2c548fd57728..2bf4e9540b74ecdd61b1fa5f8a8354af9a7753f1 100644 (file)
@@ -4,8 +4,7 @@ use ieee.numeric_std.all;
 use work.gen_pkg.all;
 
 entity parser is
 use work.gen_pkg.all;
 
 entity parser is
-       port
-       (
+       port (
                sys_clk : in std_logic;
                sys_res_n : in std_logic;
                -- History
                sys_clk : in std_logic;
                sys_res_n : in std_logic;
                -- History
@@ -23,11 +22,11 @@ entity parser is
 end entity parser;
 
 architecture beh of parser is
 end entity parser;
 
 architecture beh of parser is
-       type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_SPACE1_2,
-       SREAD_SPACE1_3, SREAD_SPACE2, SREAD_SPACE3, SREAD_OP1, SREAD_OP2,
-       SREAD_SIGN1, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
-       SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR0, SWRITE_CHAR1, SWRITE_CHAR2,
-       SWRITE_SIGN1, SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
+       type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_SPACE_GET,
+               SREAD_SPACE_GET_SIGN, SREAD_SPACE_PROC, SREAD_SPACE_PROC_SIGN, SREAD_OP1, SREAD_OP2,
+               SREAD_SIGN, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
+               SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR0, SWRITE_CHAR1, SWRITE_CHAR2,
+               SWRITE_SIGN1, SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
        signal state_int, state_next : PARSER_STATE;
        signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
        signal punkt_int, punkt_next : csigned;
        signal state_int, state_next : PARSER_STATE;
        signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
        signal punkt_int, punkt_next : csigned;
@@ -43,7 +42,6 @@ architecture beh of parser is
        signal op1_int, op1_next : csigned;
        signal op2_int, op2_next : csigned;
        signal do_calc_int, do_calc_next : std_logic;
        signal op1_int, op1_next : csigned;
        signal op2_int, op2_next : csigned;
        signal do_calc_int, do_calc_next : std_logic;
-       signal goto_calcn1, goto_op1, goto_space3, goto_sign : std_logic;
        signal z_sign_next, z_sign_int : std_logic;
        signal firstz_next, firstz_int : boolean;
        signal err_next, err_int : hstr_int;
        signal z_sign_next, z_sign_int : std_logic;
        signal firstz_next, firstz_int : boolean;
        signal err_next, err_int : hstr_int;
@@ -140,172 +138,11 @@ begin
        end process;
 
        -- next state
        end process;
 
        -- next state
-       process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
-               punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
-               goto_space3, goto_sign, z_sign_int, err_int, errc_int, calc_error,
-               op2_int)
-       begin
-               state_next <= state_int;
-
-               case state_int is
-                       when SIDLE =>
-                               if do_it = '1' then
-                                       state_next <= SREAD_NEWNUMBER;
-                               end if;
-                       when SREAD_NEWNUMBER =>
-                               state_next <= SREAD_SPACE1_2;
-                       when SREAD_SPACE1_2 =>
-                               if p_rdone = '1' then
-                                       state_next <= SREAD_SPACE2;
-                               end if;
-                       when SREAD_SPACE1_3 =>
-                               if p_rdone = '1' then
-                                       state_next <= SREAD_SPACE3;
-                               end if;
-                       when SREAD_SPACE2 | SREAD_SPACE3 =>
-                               if goto_calcn1 = '1' then
-                                       case state_int is
-                                               when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
-                                               when SREAD_SPACE3 => state_next <= SREAD_OP1;
-                                               when others => assert(false) report "wtf @ state2";
-                                       end case;
-                               end if;
-                               if goto_sign = '1' then
-                                       case state_int is
-                                               when SREAD_SPACE2 => state_next <= SREAD_SIGN1;
-                                               when others => assert(false) report "wtf @ state3";
-                                       end case;
-                               end if;
-                               if p_rdone = '0' then
-                                       if goto_calcn1 = '0' then
-                                               case state_int is
-                                                       when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
-                                                       when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
-                                                       when others => assert(false) report "wtf @ state1";
-                                               end case;
-                                       end if;
-                               end if;
-                       when SREAD_SIGN1 =>
-                               if p_rdone = '0' then
-                                       state_next <= SREAD_NEXTBYTE;
-                               end if;
-                       when SREAD_NEXTBYTE =>
-                               if p_rdone = '1' then
-                                       state_next <= SREAD_CALCNUMBER1;
-                               end if;
-                       when SREAD_CALCNUMBER1 =>
-                               if goto_op1 = '1' then
-                                       state_next <= SREAD_OP1;
-                               elsif goto_space3 = '1' then
-                                       state_next <= SREAD_SPACE3;
-                               elsif calc_done = '1' then
-                                       state_next <= SREAD_CALCNUMBER2;
-                               end if;
-                       when SREAD_OP1 =>
-                               state_next <= SREAD_OP2;
-                       when SREAD_OP2 =>
-                               if p_rdone = '0' then
-                                       if aktop_int /= ALU_NOP then
-                                               state_next <= SCALC_1;
-                                       end if;
-                               end if;
-                       when SREAD_CALCNUMBER2 =>
-                               if p_rdone = '0' and calc_done = '0' then
-                                       state_next <= SREAD_NEXTBYTE;
-                               end if;
-                       when SCALC_1 =>
-                               if calc_done = '1' then
-                                       case opp_int is
-                                               -- spezialfall: eine zwischenberechnung wird fuer diese
-                                               -- kombination benoetigt
-                                               when ALU_MUL | ALU_DIV =>
-                                                       case aktop_int is
-                                                               when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
-                                                               when others => state_next <= SCALC_2;
-                                                       end case;
-                                               when others => state_next <= SCALC_2;
-                                       end case;
-                               end if;
-                       when SCALC_14 =>
-                               if calc_done = '0' then
-                                       state_next <= SCALC_15;
-                               end if;
-                       when SCALC_15 =>
-                               if calc_done = '1' then
-                                       state_next <= SCALC_2;
-                               end if;
-                       when SCALC_2 =>
-                               if calc_done = '0' then
-                                       if aktop_int = ALU_DONE then
-                                               state_next <= SWRITE_CHAR2;
-                                       else
-                                               state_next <= SREAD_NEWNUMBER;
-                                       end if;
-                               end if;
-                       when SWRITE_CHAR0 =>
-                               if calc_done = '1' then
-                                       state_next <= SWRITE_CHAR1;
-                               end if;
-                       when SWRITE_CHAR1 =>
-                               if p_wdone = '1' then
-                                       -- ueberpruefung auf -2147483648 fuer testfall 39 und 40
-                                       -- x"80000000": xst (xilinx) workaround
-                                       if strich_int < 10 and strich_int /= x"80000000" then
-                                               if z_sign_int = '1' then
-                                                       state_next <= SWRITE_SIGN1;
-                                               else
-                                                       state_next <= SDONE;
-                                               end if;
-                                       else
-                                               state_next <= SWRITE_CHAR2;
-                                       end if;
-                               end if;
-                       when SERROR1 =>
-                               if p_wdone = '1' then
-                                       if errc_int <= 2 then
-                                               state_next <= SDONE;
-                                       else
-                                               state_next <= SERROR2;
-                                       end if;
-                               end if;
-                       when SERROR2 =>
-                               if p_wdone = '0' then
-                                       state_next <= SERROR1;
-                               end if;
-                       when SWRITE_CHAR2 =>
-                               if p_wdone = '0' and calc_done = '0' then
-                                       state_next <= SWRITE_CHAR0;
-                               end if;
-                       when SWRITE_SIGN1 =>
-                               if p_wdone = '0' then
-                                       state_next <= SWRITE_SIGN2;
-                               end if;
-                       when SWRITE_SIGN2 =>
-                               if p_wdone = '1' then
-                                       state_next <= SDONE;
-                               end if;
-
-                       when SDONE =>
-                               if p_wdone = '0' and do_it = '0' then
-                                       state_next <= SIDLE;
-                               end if;
-               end case;
-
-               -- fehlerbehandlung
-               case state_int is
-                       when SERROR1 | SERROR2 | SDONE => null;
-                       when others =>
-                               if err_int > 0 then
-                                       state_next <= SERROR1;
-                               end if;
-               end case;
-       end process;
-
-       -- out
-       process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
-               strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3, opM,
-               do_calc_int, wtmp_int, punkt_int, z_sign_int, err_int, errc_int,
-               errc_tmp_int, firstz_int, calc_done, calc_error)
+       process(do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int, punkt_int,
+                       calc_done, wtmp_int, opp_int, z_sign_int, err_int, errc_int,
+                       calc_error, op2_int, state_int, p_write_int, z_int, rbyte_int,
+                       p_rget_int, opcode_int, op1_int, op3, opM, do_calc_int,
+                       errc_tmp_int, firstz_int)
                function hbyte2csigned (x : hbyte) return csigned is
                        variable y : csigned;
                begin
                function hbyte2csigned (x : hbyte) return csigned is
                        variable y : csigned;
                begin
@@ -344,7 +181,6 @@ begin
                        return y;
                end function csigned2hbyte;
 
                        return y;
                end function csigned2hbyte;
 
-
                variable multmp : signed(((2*CBITS)-1) downto 0);
                variable tmp : csigned;
 
                variable multmp : signed(((2*CBITS)-1) downto 0);
                variable tmp : csigned;
 
@@ -355,6 +191,7 @@ begin
                        3 => " Fehler:                             Over- bzw. Underflow              " & nul
                );
        begin
                        3 => " Fehler:                             Over- bzw. Underflow              " & nul
                );
        begin
+               state_next <= state_int;
                -- internal
                z_next <= z_int;
                z_sign_next <= z_sign_int;
                -- internal
                z_next <= z_int;
                z_sign_next <= z_sign_int;
@@ -378,16 +215,16 @@ begin
                op1_next <= op1_int;
                op2_next <= op2_int;
                do_calc_next <= '0';
                op1_next <= op1_int;
                op2_next <= op2_int;
                do_calc_next <= '0';
-               goto_calcn1 <= '0';
-               goto_op1 <= '0';
-               goto_space3 <= '0';
-               goto_sign <= '0';
 
                case state_int is
                        when SIDLE =>
                                strich_next <= (others => '0');
                                punkt_next <= (0 => '1', others => '0');
                                opp_next <= ALU_NOP;
 
                case state_int is
                        when SIDLE =>
                                strich_next <= (others => '0');
                                punkt_next <= (0 => '1', others => '0');
                                opp_next <= ALU_NOP;
+                               if do_it = '1' then
+                                       state_next <= SREAD_NEWNUMBER;
+                               end if;
+
                        when SREAD_NEWNUMBER =>
                                z_next <= (others => '0');
                                z_sign_next <= '0';
                        when SREAD_NEWNUMBER =>
                                z_next <= (others => '0');
                                z_sign_next <= '0';
@@ -395,23 +232,65 @@ begin
                                rbyte_next <= (others => '0');
                                p_write_next <= (others => '0');
                                aktop_next <= ALU_NOP;
                                rbyte_next <= (others => '0');
                                p_write_next <= (others => '0');
                                aktop_next <= ALU_NOP;
-                       when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
+                               state_next <= SREAD_SPACE_GET;
+
+                       when SREAD_SPACE_GET =>
                                p_rget_next <= '1';
                                p_rget_next <= '1';
-                       when SREAD_SPACE2 | SREAD_SPACE3 =>
+                               if p_rdone = '1' then
+                                       state_next <= SREAD_SPACE_PROC;
+                               end if;
+                       when SREAD_SPACE_GET_SIGN =>
+                               p_rget_next <= '1';
+                               if p_rdone = '1' then
+                                       state_next <= SREAD_SPACE_PROC_SIGN;
+                               end if;
+                       when SREAD_SPACE_PROC | SREAD_SPACE_PROC_SIGN =>
                                case p_read is
                                case p_read is
-                                       when x"20" =>
-                                               null;
+                                       when x"20" => null;
                                        when x"2D" =>
                                                case state_int is
                                        when x"2D" =>
                                                case state_int is
-                                                       when SREAD_SPACE2 => goto_sign <= '1';
-                                                       when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1';
-                                                       when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen";
+                                                       when SREAD_SPACE_PROC =>
+                                                               case state_int is
+                                                                       when SREAD_SPACE_PROC => state_next <= SREAD_SIGN;
+                                                                       when others => assert(false) report "wtf @ state3";
+                                                               end case;
+
+                                                       when SREAD_SPACE_PROC_SIGN =>
+                                                               p_rget_next <= '1';
+                                                               case state_int is
+                                                                       when SREAD_SPACE_PROC => state_next <= SREAD_NEXTBYTE;
+                                                                       when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_OP1;
+                                                                       when others => assert(false) report "wtf @ state2";
+                                                               end case;
+
+                                                       when others => assert(false) report "SREAD_SPACE_PROC/3: shouldn't happen";
                                                end case;
                                        when others =>
                                                end case;
                                        when others =>
-                                               goto_calcn1 <= '1';
                                                p_rget_next <= '1';
                                                p_rget_next <= '1';
+                                               case state_int is
+                                                       when SREAD_SPACE_PROC => state_next <= SREAD_NEXTBYTE;
+                                                       when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_OP1;
+                                                       when others => assert(false) report "wtf @ state2";
+                                               end case;
                                end case;
 
                                end case;
 
+                               if p_rdone = '0' then
+                                       case state_int is
+                                               when SREAD_SPACE_PROC => state_next <= SREAD_SPACE_GET;
+                                               when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_SPACE_GET_SIGN;
+                                               when others => assert(false) report "wtf @ state1";
+                                       end case;
+                               end if;
+                       when SREAD_SIGN =>
+                               z_sign_next <= '1';
+                               if p_rdone = '0' then
+                                       state_next <= SREAD_NEXTBYTE;
+                               end if;
+                       when SREAD_NEXTBYTE =>
+                               p_rget_next <= '1';
+                               if p_rdone = '1' then
+                                       state_next <= SREAD_CALCNUMBER1;
+                               end if;
                        when SREAD_CALCNUMBER1 =>
                                case p_read is
                                        -- '+', '-', '*', '/'
                        when SREAD_CALCNUMBER1 =>
                                case p_read is
                                        -- '+', '-', '*', '/'
@@ -419,13 +298,13 @@ begin
                                                if firstz_int then
                                                        err_next <= 2;
                                                else
                                                if firstz_int then
                                                        err_next <= 2;
                                                else
-                                                       goto_op1 <= '1';
+                                                       state_next <= SREAD_OP1;
                                                        p_rget_next <= '1';
                                                end if;
 
                                        -- ' '
                                        when x"20" =>
                                                        p_rget_next <= '1';
                                                end if;
 
                                        -- ' '
                                        when x"20" =>
-                                               goto_space3 <= '1';
+                                               state_next <= SREAD_SPACE_PROC_SIGN;
                                                p_rget_next <= '1';
 
                                        when others =>
                                                p_rget_next <= '1';
 
                                        when others =>
@@ -435,12 +314,15 @@ begin
                                                firstz_next <= false;
                                                do_calc_next <= '1';
                                end case;
                                                firstz_next <= false;
                                                do_calc_next <= '1';
                                end case;
-                       when SREAD_SIGN1 =>
-                               z_sign_next <= '1';
+                               if calc_done = '1' then
+                                       state_next <= SREAD_CALCNUMBER2;
+                               end if;
                        when SREAD_CALCNUMBER2 =>
                                z_next <= op3 + hbyte2csigned(p_read);
                        when SREAD_CALCNUMBER2 =>
                                z_next <= op3 + hbyte2csigned(p_read);
-                       when SREAD_OP2 =>
-                               null;
+                               if p_rdone = '0' and calc_done = '0' then
+                                       state_next <= SREAD_NEXTBYTE;
+                               end if;
+
                        when SREAD_OP1 =>
                                case p_read is
                                        when x"2B" => aktop_next <= ALU_ADD; -- '+'
                        when SREAD_OP1 =>
                                case p_read is
                                        when x"2B" => aktop_next <= ALU_ADD; -- '+'
@@ -451,7 +333,13 @@ begin
 
                                        when others => err_next <= 2;
                                end case;
 
                                        when others => err_next <= 2;
                                end case;
-
+                               state_next <= SREAD_OP2;
+                       when SREAD_OP2 =>
+                               if p_rdone = '0' then
+                                       if aktop_int /= ALU_NOP then
+                                               state_next <= SCALC_1;
+                                       end if;
+                               end if;
 
                        when SCALC_1 =>
                                if z_sign_int = '1' then
 
                        when SCALC_1 =>
                                if z_sign_int = '1' then
@@ -498,12 +386,27 @@ begin
                                end case;
                                do_calc_next <= '1';
 
                                end case;
                                do_calc_next <= '1';
 
+                               if calc_done = '1' then
+                                       case opp_int is
+                                               -- spezialfall: eine zwischenberechnung wird fuer diese
+                                               -- kombination benoetigt
+                                               when ALU_MUL | ALU_DIV =>
+                                                       case aktop_int is
+                                                               when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
+                                                               when others => state_next <= SCALC_2;
+                                                       end case;
+                                               when others => state_next <= SCALC_2;
+                                       end case;
+                               end if;
                        when SCALC_14 =>
                                -- ueberpruefung kann man sich sparen, da diese ohnehin in
                                -- nextstate gemacht wird.
                                op1_next <= op3;
                                do_calc_next <= '0';
 
                        when SCALC_14 =>
                                -- ueberpruefung kann man sich sparen, da diese ohnehin in
                                -- nextstate gemacht wird.
                                op1_next <= op3;
                                do_calc_next <= '0';
 
+                               if calc_done = '0' then
+                                       state_next <= SCALC_15;
+                               end if;
                        when SCALC_15 =>
                                -- ueberpruefung kann man sich sparen, da diese ohnehin in
                                -- nextstate gemacht wird.
                        when SCALC_15 =>
                                -- ueberpruefung kann man sich sparen, da diese ohnehin in
                                -- nextstate gemacht wird.
@@ -512,6 +415,9 @@ begin
                                punkt_next <= (0 => '1', others => '0');
                                do_calc_next <= '1';
 
                                punkt_next <= (0 => '1', others => '0');
                                do_calc_next <= '1';
 
+                               if calc_done = '1' then
+                                       state_next <= SCALC_2;
+                               end if;
                        when SCALC_2 =>
                                case opp_int is
                                        when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
                        when SCALC_2 =>
                                case opp_int is
                                        when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
@@ -535,6 +441,14 @@ begin
                                -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
                                opp_next <= aktop_int;
 
                                -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
                                opp_next <= aktop_int;
 
+                               if calc_done = '0' then
+                                       if aktop_int = ALU_DONE then
+                                               state_next <= SWRITE_CHAR2;
+                                       else
+                                               state_next <= SREAD_NEWNUMBER;
+                                       end if;
+                               end if;
+
                        when SWRITE_CHAR0 =>
                                -- fuer testfall 39 und 40
                                if strich_int = to_signed(-214748364,CBITS) then
                        when SWRITE_CHAR0 =>
                                -- fuer testfall 39 und 40
                                if strich_int = to_signed(-214748364,CBITS) then
@@ -546,17 +460,40 @@ begin
                                opcode_next <= ALU_DIV;
                                op2_next <= to_signed(10,CBITS);
                                do_calc_next <= '1';
                                opcode_next <= ALU_DIV;
                                op2_next <= to_signed(10,CBITS);
                                do_calc_next <= '1';
+
+                               if calc_done = '1' then
+                                       state_next <= SWRITE_CHAR1;
+                               end if;
                        when SWRITE_CHAR1 =>
                                do_calc_next <= '1';
                                p_wtake_next <= '1';
                                tmp := opM;
                                p_write_next <= csigned2hbyte(tmp);
                                wtmp_next <= op3;
                        when SWRITE_CHAR1 =>
                                do_calc_next <= '1';
                                p_wtake_next <= '1';
                                tmp := opM;
                                p_write_next <= csigned2hbyte(tmp);
                                wtmp_next <= op3;
+
+                               if p_wdone = '1' then
+                                       -- ueberpruefung auf -2147483648 fuer testfall 39 und 40
+                                       -- x"80000000": xst (xilinx) workaround
+                                       if strich_int < 10 and strich_int /= x"80000000" then
+                                               if z_sign_int = '1' then
+                                                       state_next <= SWRITE_SIGN1;
+                                               else
+                                                       state_next <= SDONE;
+                                               end if;
+                                       else
+                                               state_next <= SWRITE_CHAR2;
+                                       end if;
+                               end if;
                        when SWRITE_CHAR2 =>
                                strich_next <= wtmp_int;
                        when SWRITE_CHAR2 =>
                                strich_next <= wtmp_int;
+                               if p_wdone = '0' and calc_done = '0' then
+                                       state_next <= SWRITE_CHAR0;
+                               end if;
 
                        when SWRITE_SIGN1 =>
 
                        when SWRITE_SIGN1 =>
-                               null;
+                               if p_wdone = '0' then
+                                       state_next <= SWRITE_SIGN2;
+                               end if;
                        when SWRITE_SIGN2 =>
                                if z_sign_int = '1' then
                                        p_wtake_next <= '1';
                        when SWRITE_SIGN2 =>
                                if z_sign_int = '1' then
                                        p_wtake_next <= '1';
@@ -565,23 +502,43 @@ begin
                                        assert(false) report "SWRITE_SIGN: shouldn't happen!";
                                end if;
 
                                        assert(false) report "SWRITE_SIGN: shouldn't happen!";
                                end if;
 
+                               if p_wdone = '1' then
+                                       state_next <= SDONE;
+                               end if;
+
                        when SERROR1 =>
                        when SERROR1 =>
-                               p_wtake_next <= '1';
-                               p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
-                               errc_tmp_next <= errc_int - 1;
+                               if p_wdone = '1' then
+                                       if errc_int <= 2 then
+                                               state_next <= SDONE;
+                                       else
+                                               state_next <= SERROR2;
+                                       end if;
+                               end if;
                        when SERROR2 =>
                        when SERROR2 =>
-                               errc_next <= errc_tmp_int;
+                               if p_wdone = '0' then
+                                       state_next <= SERROR1;
+                               end if;
 
                        when SDONE =>
                                err_next <= 0;
                                errc_next <= 71;
                                p_finished_next <= '1';
                                finished_next <= '1';
 
                        when SDONE =>
                                err_next <= 0;
                                errc_next <= 71;
                                p_finished_next <= '1';
                                finished_next <= '1';
+
+                               if p_wdone = '0' and do_it = '0' then
+                                       state_next <= SIDLE;
+                               end if;
                end case;
 
                -- fehlerbehandlung
                case state_int is
                end case;
 
                -- fehlerbehandlung
                case state_int is
-                       when SERROR1 | SERROR2 | SDONE => null;
+                       when SERROR1 =>
+                               p_wtake_next <= '1';
+                               p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
+                               errc_tmp_next <= errc_int - 1;
+                       when SERROR2 =>
+                               errc_next <= errc_tmp_int;
+                       when SDONE => null;
                        when others =>
                                if calc_error = '1' then
                                        if op2_int = 0 then
                        when others =>
                                if calc_error = '1' then
                                        if op2_int = 0 then
@@ -590,6 +547,10 @@ begin
                                                err_next <= 3;
                                        end if;
                                end if;
                                                err_next <= 3;
                                        end if;
                                end if;
+
+                               if err_int > 0 then
+                                       state_next <= SERROR1;
+                               end if;
                end case;
        end process;
 end architecture beh;
                end case;
        end process;
 end architecture beh;