uart_rx: ein prozessmodell. spart weitere 3 logic elements :P
[hwmod.git] / src / parser.vhd
index 2bf4e9540b74ecdd61b1fa5f8a8354af9a7753f1..4ad14cc9246a34443f2aa2ebeb710632d5294eaa 100644 (file)
@@ -26,7 +26,7 @@ architecture beh of parser is
                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);
+               SWRITE_SIGN1, SWRITE_SIGN2, SDONE, SERROR1, SERROR2, SBLANK1, SBLANK2);
        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;
@@ -46,7 +46,6 @@ architecture beh of parser is
        signal firstz_next, firstz_int : boolean;
        signal err_next, err_int : hstr_int;
        signal errc_next, errc_int : hstr_int;
-       signal errc_tmp_next, errc_tmp_int : hstr_int;
        -- ALU
        signal opcode : alu_ops;
        signal op1 : csigned;
@@ -57,9 +56,8 @@ architecture beh of parser is
        signal calc_done : std_logic;
        signal calc_error : std_logic;
 begin
-       instalu : entity work.alu(beh)
-       port map
-       (
+       instalu : alu
+       port map (
                sys_clk => sys_clk,
                sys_res_n => sys_res_n,
                do_calc => do_calc,
@@ -96,8 +94,7 @@ begin
                        aktop_int <= ALU_NOP;
                        opp_int <= ALU_NOP;
                        err_int <= 0;
-                       errc_int <= 71;
-                       errc_tmp_int <= 0;
+                       errc_int <= HSPALTE_MAX;
                        firstz_int <= true;
                        -- out ports
                        p_rget_int <= '0';
@@ -122,7 +119,6 @@ begin
                        opp_int <= opp_next;
                        err_int <= err_next;
                        errc_int <= errc_next;
-                       errc_tmp_int <= errc_tmp_next;
                        firstz_int <= firstz_next;
                        -- out ports
                        p_rget_int <= p_rget_next;
@@ -142,7 +138,7 @@ begin
                        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)
+                       firstz_int)
                function hbyte2csigned (x : hbyte) return csigned is
                        variable y : csigned;
                begin
@@ -203,7 +199,6 @@ begin
                opp_next <= opp_int;
                err_next <= err_int;
                errc_next <= errc_int;
-               errc_tmp_next <= errc_tmp_int;
                firstz_next <= firstz_int;
                -- signals
                p_rget_next <= '0';
@@ -245,42 +240,27 @@ begin
                                        state_next <= SREAD_SPACE_PROC_SIGN;
                                end if;
                        when SREAD_SPACE_PROC | SREAD_SPACE_PROC_SIGN =>
-                               case p_read is
-                                       when x"20" => null;
-                                       when x"2D" =>
-                                               case state_int is
-                                                       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 =>
-                                               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;
-
                                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;
+                               else
+                                       if p_read = x"2d" and state_int = SREAD_SPACE_PROC then
+                                               -- vorzeichen?
+                                               state_next <= SREAD_SIGN;
+                                       elsif p_read /= x"20" then
+                                               -- leerzeichen sollen ignoriert werden
+                                               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 "SREAD_SPACE_PROC{,_SIGN}: shouldn't happen";
+                                               end case;
+                                       end if;
                                end if;
+
                        when SREAD_SIGN =>
                                z_sign_next <= '1';
                                if p_rdone = '0' then
@@ -336,9 +316,7 @@ begin
                                state_next <= SREAD_OP2;
                        when SREAD_OP2 =>
                                if p_rdone = '0' then
-                                       if aktop_int /= ALU_NOP then
-                                               state_next <= SCALC_1;
-                                       end if;
+                                       state_next <= SCALC_1;
                                end if;
 
                        when SCALC_1 =>
@@ -472,13 +450,14 @@ begin
                                wtmp_next <= op3;
 
                                if p_wdone = '1' then
+                                       errc_next <= errc_int - 1;
                                        -- 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;
+                                                       state_next <= SBLANK1;
                                                end if;
                                        else
                                                state_next <= SWRITE_CHAR2;
@@ -503,11 +482,31 @@ begin
                                end if;
 
                                if p_wdone = '1' then
+                                       errc_next <= errc_int - 1;
                                        state_next <= SDONE;
                                end if;
 
+                       when SBLANK1 =>
+                               p_wtake_next <= '1';
+                               p_write_next <= x"20";
+                               if p_wdone = '1' then
+                                       errc_next <= errc_int - 1;
+                                       if errc_int <= 2 then
+                                               state_next <= SDONE;
+                                       else
+                                               state_next <= SBLANK2;
+                                       end if;
+                               end if;
+                       when SBLANK2 =>
+                               if p_wdone = '0' then
+                                       state_next <= SBLANK1;
+                               end if;
+
                        when SERROR1 =>
+                               p_wtake_next <= '1';
+                               p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
                                if p_wdone = '1' then
+                                       errc_next <= errc_int - 1;
                                        if errc_int <= 2 then
                                                state_next <= SDONE;
                                        else
@@ -521,7 +520,7 @@ begin
 
                        when SDONE =>
                                err_next <= 0;
-                               errc_next <= 71;
+                               errc_next <= HSPALTE_MAX;
                                p_finished_next <= '1';
                                finished_next <= '1';
 
@@ -532,13 +531,8 @@ begin
 
                -- fehlerbehandlung
                case state_int is
-                       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;
+                       -- diese states sind ausgenommen vom "pokemon-exception-handling"
+                       when SERROR1 | SERROR2 | SDONE => null;
                        when others =>
                                if calc_error = '1' then
                                        if op2_int = 0 then