op1 : out csigned;
op2 : out csigned;
op3 : in csigned;
+ opM : in csigned;
do_calc : out std_logic;
calc_done : in std_logic;
calc_error : in std_logic;
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_CHAR1, SWRITE_CHAR2, SWRITE_SIGN1,
- SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
+ 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 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;
+ signal err_next, err_int : hstr_int;
+ signal errc_next, errc_int : hstr_int;
+ signal errc_tmp_next, errc_tmp_int : hstr_int;
begin
p_write <= p_write_int;
p_rget <= p_rget_int;
state_next <= SREAD_OP1;
elsif goto_space3 = '1' then
state_next <= SREAD_SPACE3;
- else
+ elsif calc_done = '1' then
state_next <= SREAD_CALCNUMBER2;
end if;
when SREAD_OP1 =>
end if;
end if;
when SREAD_CALCNUMBER2 =>
- if p_rdone = '0' then
+ if p_rdone = '0' and calc_done = '0' then
state_next <= SREAD_NEXTBYTE;
end if;
when SCALC_1 =>
state_next <= SCALC_2;
end if;
when SCALC_2 =>
- if aktop_int = ALU_DONE then
+ 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;
- else
- state_next <= SREAD_NEWNUMBER;
end if;
when SWRITE_CHAR1 =>
if p_wdone = '1' then
state_next <= SERROR1;
end if;
when SWRITE_CHAR2 =>
- if p_wdone = '0' then
- state_next <= SWRITE_CHAR1;
+ if p_wdone = '0' and calc_done = '0' then
+ state_next <= SWRITE_CHAR0;
end if;
when SWRITE_SIGN1 =>
if p_wdone = '0' then
-- 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,
+ 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)
function hbyte2csigned (x : hbyte) return csigned is
variable y : csigned;
begin
case x is
- when x"30" => y := to_signed(0, CBITS);
- when x"31" => y := to_signed(1, CBITS);
- when x"32" => y := to_signed(2, CBITS);
- when x"33" => y := to_signed(3, CBITS);
- when x"34" => y := to_signed(4, CBITS);
- when x"35" => y := to_signed(5, CBITS);
- when x"36" => y := to_signed(6, CBITS);
- when x"37" => y := to_signed(7, CBITS);
- when x"38" => y := to_signed(8, CBITS);
- when x"39" => y := to_signed(9, CBITS);
+ when x"30" => y := x"00000000";
+ when x"31" => y := x"00000001";
+ when x"32" => y := x"00000002";
+ when x"33" => y := x"00000003";
+ when x"34" => y := x"00000004";
+ when x"35" => y := x"00000005";
+ when x"36" => y := x"00000006";
+ when x"37" => y := x"00000007";
+ when x"38" => y := x"00000008";
+ when x"39" => y := x"00000009";
when others => assert(false) report "hbyte2csigned: shouldn't happen";
end case;
return y;
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 "
+ constant error_str : errstrings := (
+ 1 => " Division durch Null" & nul,
+ 2 => " Syntax" & nul,
+ 3 => " Over- bzw. Underflow" & nul
);
begin
-- internal
p_rget_next <= '1';
when others =>
- -- TODO: check auf overflow
- multmp := (z_int * 10) + hbyte2csigned(p_read);
- z_next <= multmp((CBITS-1) downto 0);
+ op1_next <= z_int;
+ opcode_next <= ALU_MUL;
+ op2_next <= to_signed(10,CBITS);
firstz_next <= false;
+ do_calc_next <= '1';
end case;
when SREAD_SIGN1 =>
z_sign_next <= '1';
- when SREAD_CALCNUMBER2 | SREAD_OP2 =>
+ when SREAD_CALCNUMBER2 =>
+ z_next <= op3 + hbyte2csigned(p_read);
+ when SREAD_OP2 =>
null;
when SREAD_OP1 =>
case p_read is
- -- '+'
- when x"2B" => aktop_next <= ALU_ADD;
- -- '-'
- when x"2D" => aktop_next <= ALU_SUB;
- -- '*'
- when x"2A" => aktop_next <= ALU_MUL;
- -- '/'
- when x"2F" => aktop_next <= ALU_DIV;
- -- '\0'
- when x"00" => aktop_next <= ALU_DONE;
+ when x"2B" => aktop_next <= ALU_ADD; -- '+'
+ when x"2D" => aktop_next <= ALU_SUB; -- '-'
+ when x"2A" => aktop_next <= ALU_MUL; -- '*'
+ when x"2F" => aktop_next <= ALU_DIV; -- '/'
+ when x"00" => aktop_next <= ALU_DONE; -- '\0'
when others => err_next <= 2;
end case;
when ALU_ADD | ALU_SUB | ALU_DONE =>
if aktop_int = ALU_DONE and op3 < 0 then
strich_next <= (not op3) + 1;
+ wtmp_next <= (not op3) + 1;
z_sign_next <= '1';
else
strich_next <= op3;
+ wtmp_next <= op3;
end if;
when ALU_MUL | ALU_DIV =>
punkt_next <= op3;
-- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
opp_next <= aktop_int;
+ when SWRITE_CHAR0 =>
+ op1_next <= strich_int;
+ opcode_next <= ALU_DIV;
+ op2_next <= to_signed(10,CBITS);
+ do_calc_next <= '1';
when SWRITE_CHAR1 =>
+ do_calc_next <= '1';
p_wtake_next <= '1';
- tmp := strich_int mod 10;
+ tmp := opM;
p_write_next <= csigned2hbyte(tmp);
- wtmp_next <= strich_int / 10;
+ wtmp_next <= op3;
when SWRITE_CHAR2 =>
strich_next <= wtmp_int;
when SERROR1 =>
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 =>