X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fparser.vhd;h=1d75398bfc87454dbc5694abba14d4844d40722d;hb=27c9670ed41bd1d234c325380433cefd57d2cadc;hp=74c4661cd9f6ec04ab2e1bd67387f97273e10075;hpb=e4d17ff9b56af5b05d5b610bac24127f697c8419;p=hwmod.git diff --git a/src/parser.vhd b/src/parser.vhd index 74c4661..1d75398 100644 --- a/src/parser.vhd +++ b/src/parser.vhd @@ -23,6 +23,7 @@ entity parser is 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; @@ -36,8 +37,8 @@ architecture beh of parser is 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; @@ -54,10 +55,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; + 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; @@ -183,7 +184,7 @@ begin 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 => @@ -195,7 +196,7 @@ begin 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 => @@ -220,10 +221,16 @@ begin 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 @@ -250,8 +257,8 @@ begin 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 @@ -280,23 +287,23 @@ begin -- 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; @@ -326,11 +333,10 @@ begin 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 @@ -406,27 +412,25 @@ begin 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; @@ -490,9 +494,11 @@ begin 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; @@ -503,11 +509,17 @@ begin -- 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; @@ -523,8 +535,6 @@ begin 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 =>