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).
\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.
\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}
\end{itemize}
\end{document}
+# 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
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 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;
begin
p_write <= p_write_int;
p_rget <= p_rget_int;
rbyte_int <= (others => '0');
aktop_int <= ALU_NOP;
opp_int <= ALU_NOP;
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');
-- out ports
p_rw <= '0';
p_spalte <= (others => '0');
rbyte_int <= rbyte_next;
aktop_int <= aktop_next;
opp_int <= opp_next;
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;
-- out ports
p_rget_int <= p_rget_next;
p_write_int <= p_write_next;
-- 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,
-- 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;
begin
state_next <= state_int;
end if;
when SERROR1 =>
if p_wdone = '1' then
end if;
when SERROR1 =>
if p_wdone = '1' then
- -- TODO
- if strich_int < 10 then
state_next <= SDONE;
else
state_next <= SDONE;
else
- state_next <= SWRITE_CHAR2;
- 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;
if p_wdone = '0' then
state_next <= SWRITE_CHAR1;
end if;
state_next <= SIDLE;
end if;
end case;
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,
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
function hbyte2csigned (x : hbyte) return csigned is
variable y : csigned;
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;
+
+ 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;
begin
-- internal
z_next <= z_int;
rbyte_next <= rbyte_int;
aktop_next <= aktop_int;
opp_next <= opp_int;
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;
-- signals
p_rget_next <= '0';
p_write_next <= p_write_int;
when SREAD_NEWNUMBER =>
z_next <= (others => '0');
z_sign_next <= '0';
when SREAD_NEWNUMBER =>
z_next <= (others => '0');
z_sign_next <= '0';
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;
case p_read is
-- '+', '-', '*', '/'
when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
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;
-- TODO: check auf overflow
multmp := (z_int * 10) + hbyte2csigned(p_read);
z_next <= multmp((CBITS-1) downto 0);
-- TODO: check auf overflow
multmp := (z_int * 10) + hbyte2csigned(p_read);
z_next <= multmp((CBITS-1) downto 0);
end case;
when SREAD_SIGN1 =>
z_sign_next <= '1';
end case;
when SREAD_SIGN1 =>
z_sign_next <= '1';
when SREAD_OP1 =>
case p_read is
-- '+'
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;
- 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;
+ 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;
+ errc_next <= errc_tmp_int;
+ err_next <= 0;
+ errc_next <= 70;
p_finished_next <= '1';
end case;
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;
end process;
end architecture beh;