parser: fehlermeldungen
authorBernhard Urban <lewurm@gmail.com>
Tue, 11 May 2010 17:10:25 +0000 (19:10 +0200)
committerBernhard Urban <lewurm@gmail.com>
Tue, 11 May 2010 17:10:25 +0000 (19:10 +0200)
TODO: *, / und mod noch durch ALU ersetzen (ALU muss dazu noch erweitert
werden). durch error flag der ALU kann noch overflow fehlermeldung eingebaut
werden (fuer die berechnung von z_int).

spec/speck.tex
src/parser.test
src/parser.vhd

index dbe6ed449d58b1dbfd9b3f7edc4f219969b21039..7fb8b2d465ed09127d1fbac123491dba98cd895b 100644 (file)
@@ -615,6 +615,9 @@ verarbeitet werden.
 \emph{error} ein Schl\"usselwort in VHDL ist.
 \item Die Richtungen bei den Signalen \emph{p\_read} und \emph{p\_write} wurden
 jeweils im Modul Parser und History vertauscht.
+\item TODO: \emph{p\_rw} und \emph{p\_spalte} unnoetig (wenn man es in history richtig
+behandelt??)
+\item aussagekr\"aftigere Fehlermeldungen.
 \end{itemize}
 
 \end{document}
index a0098f11eea875ee8b42c8899ad12ae3b989eabd..a162ebd5e0f2eddafb1cd84c03b2c0f1cd0cf94d 100644 (file)
 # t25
      -1234 / -500
 2
+# t26
+3 3
+Syntax
+# t27
+  ++
+Syntax
+# t28
+**
+Syntax
+# t29
+*+/-
+Syntax
+# t30
+   *       /
+Syntax
+# t31
+  2        +     ----
+Syntax
+# t32
+2 --1
+3
+# t33
+21448368 * 123141
+Over- bzw. Underflow
+# t34
+21448368 * -123141
+Over- bzw. Underflow
+# t35
+341212 /                 0
+Division durch Null
+# t36
+341212 /                 -0*2
+Division durch Null
index d0f523ae2b83ca85e8707d4595e4fa7e10ebae3a..74c4661cd9f6ec04ab2e1bd67387f97273e10075 100644 (file)
@@ -54,6 +54,10 @@ architecture beh of parser is
        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 err_next, err_int : natural;
+       signal errc_next, errc_int : natural;
+       signal errc_tmp_next, errc_tmp_int : natural;
+       signal firstz_next, firstz_int : boolean;
 begin
        p_write <= p_write_int;
        p_rget <= p_rget_int;
@@ -77,6 +81,10 @@ begin
                        rbyte_int <= (others => '0');
                        aktop_int <= ALU_NOP;
                        opp_int <= ALU_NOP;
+                       err_int <= 0;
+                       errc_int <= 70;
+                       errc_tmp_int <= 0;
+                       firstz_int <= true;
                        -- out ports
                        p_rw <= '0';
                        p_spalte <= (others => '0');
@@ -100,6 +108,10 @@ begin
                        rbyte_int <= rbyte_next;
                        aktop_int <= aktop_next;
                        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;
                        p_write_int <= p_write_next;
@@ -115,7 +127,8 @@ begin
        -- 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)
+               goto_space3, goto_sign, z_sign_int, err_int, errc_int, calc_error,
+               op2_int)
        begin
                state_next <= state_int;
 
@@ -226,14 +239,17 @@ begin
                                end if;
                        when SERROR1 =>
                                if p_wdone = '1' then
-                                       -- TODO 
-                                       if strich_int < 10 then
+                                       if errc_int <= 2 then
                                                state_next <= SDONE;
                                        else
-                                               state_next <= SWRITE_CHAR2;
+                                               state_next <= SERROR2;
                                        end if;
                                end if;
-                       when SWRITE_CHAR2 | SERROR2 =>
+                       when SERROR2 =>
+                               if p_wdone = '0' then
+                                       state_next <= SERROR1;
+                               end if;
+                       when SWRITE_CHAR2 =>
                                if p_wdone = '0' then
                                        state_next <= SWRITE_CHAR1;
                                end if;
@@ -251,12 +267,22 @@ begin
                                        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,
-               do_calc_int, wtmp_int, punkt_int, z_sign_int)
+               do_calc_int, wtmp_int, punkt_int, z_sign_int, err_int, errc_int,
+               errc_tmp_int, firstz_int, calc_done, calc_error)
                function hbyte2csigned (x : hbyte) return csigned is
                        variable y : csigned;
                begin
@@ -295,8 +321,17 @@ begin
                        return y;
                end function csigned2hbyte;
 
+
                variable multmp : signed(((2*CBITS)-1) downto 0);
                variable tmp : csigned;
+
+               type errstrings is array (natural range 1 to 3) of hstring;
+               variable error_str : errstrings := (
+                       --1 => (71 => character'val(0), 50 to 70 => "    Division durch 0", others => character'val(20)),
+                       1 => "                                                   Division durch Null ",
+                       2 => "                                                                Syntax ",
+                       3 => "                                                  Over- bzw. Underflow "
+               );
        begin
                -- internal
                z_next <= z_int;
@@ -307,6 +342,10 @@ begin
                rbyte_next <= rbyte_int;
                aktop_next <= aktop_int;
                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';
                p_write_next <= p_write_int;
@@ -329,6 +368,7 @@ begin
                        when SREAD_NEWNUMBER =>
                                z_next <= (others => '0');
                                z_sign_next <= '0';
+                               firstz_next <= true;
                                rbyte_next <= (others => '0');
                                p_write_next <= (others => '0');
                                aktop_next <= ALU_NOP;
@@ -353,8 +393,12 @@ begin
                                case p_read is
                                        -- '+', '-', '*', '/'
                                        when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
-                                               goto_op1 <= '1';
-                                               p_rget_next <= '1';
+                                               if firstz_int then
+                                                       err_next <= 2;
+                                               else
+                                                       goto_op1 <= '1';
+                                                       p_rget_next <= '1';
+                                               end if;
 
                                        -- ' '
                                        when x"20" =>
@@ -365,6 +409,7 @@ begin
                                                -- TODO: check auf overflow
                                                multmp := (z_int * 10) + hbyte2csigned(p_read);
                                                z_next <= multmp((CBITS-1) downto 0);
+                                               firstz_next <= false;
                                end case;
                        when SREAD_SIGN1 =>
                                z_sign_next <= '1';
@@ -373,25 +418,17 @@ begin
                        when SREAD_OP1 =>
                                case p_read is
                                        -- '+'
-                                       when x"2B" =>
-                                               aktop_next <= ALU_ADD;
+                                       when x"2B" => aktop_next <= ALU_ADD;
                                        -- '-'
-                                       when x"2D" =>
-                                               -- TODO: sign check beim ersten byte lesen!
-                                               aktop_next <= ALU_SUB;
+                                       when x"2D" => aktop_next <= ALU_SUB;
                                        -- '*'
-                                       when x"2A" =>
-                                               aktop_next <= ALU_MUL;
+                                       when x"2A" => aktop_next <= ALU_MUL;
                                        -- '/'
-                                       when x"2F" =>
-                                               aktop_next <= ALU_DIV;
-
+                                       when x"2F" => aktop_next <= ALU_DIV;
                                        -- '\0'
-                                       when x"00" =>
-                                               aktop_next <= ALU_DONE;
+                                       when x"00" => aktop_next <= ALU_DONE;
 
-                                       -- TODO: err!
-                                       when others => assert(false) report "TODO: ...";
+                                       when others => err_next <= 2;
                                end case;
 
 
@@ -485,14 +522,31 @@ begin
                                end if;
 
                        when SERROR1 =>
-                               -- TODO
-                               null;
+                               p_wtake_next <= '1';
+                               -- workaround
+                               error_str(err_int)(71) := character'val(0);
+                               p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
+                               errc_tmp_next <= errc_int - 1;
                        when SERROR2 =>
-                               -- TODO
-                               null;
+                               errc_next <= errc_tmp_int;
 
                        when SDONE =>
+                               err_next <= 0;
+                               errc_next <= 70;
                                p_finished_next <= '1';
                end case;
+
+               -- fehlerbehandlung
+               case state_int is
+                       when SERROR1 | SERROR2 | SDONE => null;
+                       when others =>
+                               if calc_error = '1' then
+                                       if op2_int = 0 then
+                                               err_next <= 1;
+                                       else
+                                               err_next <= 3;
+                                       end if;
+                               end if;
+               end case;
        end process;
 end architecture beh;