From: Bernhard Urban Date: Tue, 11 May 2010 17:10:25 +0000 (+0200) Subject: parser: fehlermeldungen X-Git-Tag: flashable_w00t~18 X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=hwmod.git;a=commitdiff_plain;h=b48867299effc164248901cb7d010ed46ce0924c parser: fehlermeldungen 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). --- diff --git a/spec/speck.tex b/spec/speck.tex index dbe6ed4..7fb8b2d 100644 --- a/spec/speck.tex +++ b/spec/speck.tex @@ -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} diff --git a/src/parser.test b/src/parser.test index a0098f1..a162ebd 100644 --- a/src/parser.test +++ b/src/parser.test @@ -75,3 +75,36 @@ # 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 diff --git a/src/parser.vhd b/src/parser.vhd index d0f523a..74c4661 100644 --- a/src/parser.vhd +++ b/src/parser.vhd @@ -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;