From c0f02d6bfea6fb375ff3a2ff5aad105f4ec1fd22 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Tue, 11 May 2010 16:21:57 +0200 Subject: [PATCH] parser: vorzeichen werden nun auch beachtet --- src/parser.test | 18 ++++++++++ src/parser.vhd | 95 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/src/parser.test b/src/parser.test index caee21e..a0098f1 100644 --- a/src/parser.test +++ b/src/parser.test @@ -57,3 +57,21 @@ # t19 50+1 51 +# t20 +40-100 +-60 +# t21 +-40*2 +-80 +# t22 +4/-2 +-2 +# t23 +-2 * -1 --1 +3 +# t24 +-2 * -2 --2 * -1 * -1 - 100 +-94 +# t25 + -1234 / -500 +2 diff --git a/src/parser.vhd b/src/parser.vhd index c622fc4..d0f523a 100644 --- a/src/parser.vhd +++ b/src/parser.vhd @@ -35,8 +35,9 @@ end entity parser; 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_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_14, - SCALC_15, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SDONE, SERROR1, SERROR2); + 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); 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; @@ -51,7 +52,8 @@ architecture beh of parser is signal op1_int, op1_next : csigned; signal op2_int, op2_next : csigned; signal do_calc_int, do_calc_next : std_logic; - signal goto_calcn1, goto_op1, goto_space3 : std_logic; + signal goto_calcn1, goto_op1, goto_space3, goto_sign : std_logic; + signal z_sign_next, z_sign_int : std_logic; begin p_write <= p_write_int; p_rget <= p_rget_int; @@ -68,6 +70,7 @@ begin if sys_res_n = '0' then state_int <= SIDLE; z_int <= (others => '0'); + z_sign_int <= '0'; strich_int <= (others => '0'); punkt_int <= (others => '0'); wtmp_int <= (others => '0'); @@ -90,6 +93,7 @@ begin -- internal state_int <= state_next; z_int <= z_next; + z_sign_int <= z_sign_next; strich_int <= strich_next; punkt_int <= punkt_next; wtmp_int <= wtmp_next; @@ -111,7 +115,7 @@ 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_space3, goto_sign, z_sign_int) begin state_next <= state_int; @@ -131,21 +135,31 @@ begin state_next <= SREAD_SPACE3; end if; when SREAD_SPACE2 | SREAD_SPACE3 => + if goto_calcn1 = '1' then + case state_int is + when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE; + when SREAD_SPACE3 => state_next <= SREAD_OP1; + when others => assert(false) report "wtf @ state2"; + end case; + end if; + if goto_sign = '1' then + case state_int is + when SREAD_SPACE2 => state_next <= SREAD_SIGN1; + when others => assert(false) report "wtf @ state3"; + end case; + end if; if p_rdone = '0' then if goto_calcn1 = '0' then case state_int is when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2; when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3; - when others => assert(false) report "wtf @ state2"; + when others => assert(false) report "wtf @ state1"; end case; end if; end if; - if goto_calcn1 = '1' then - case state_int is - when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE; - when SREAD_SPACE3 => state_next <= SREAD_OP1; - when others => assert(false) report "wtf @ state1"; - end case; + when SREAD_SIGN1 => + if p_rdone = '0' then + state_next <= SREAD_NEXTBYTE; end if; when SREAD_NEXTBYTE => if p_rdone = '1' then @@ -201,7 +215,11 @@ begin when SWRITE_CHAR1 => if p_wdone = '1' then if strich_int < 10 then - state_next <= SDONE; + if z_sign_int = '1' then + state_next <= SWRITE_SIGN1; + else + state_next <= SDONE; + end if; else state_next <= SWRITE_CHAR2; end if; @@ -219,6 +237,15 @@ begin if p_wdone = '0' then state_next <= SWRITE_CHAR1; end if; + when SWRITE_SIGN1 => + if p_wdone = '0' then + state_next <= SWRITE_SIGN2; + end if; + when SWRITE_SIGN2 => + if p_wdone = '1' then + state_next <= SDONE; + end if; + when SDONE => if p_wdone = '0' and do_it = '0' then state_next <= SIDLE; @@ -229,7 +256,7 @@ 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, - do_calc_int, wtmp_int, punkt_int) + do_calc_int, wtmp_int, punkt_int, z_sign_int) function hbyte2csigned (x : hbyte) return csigned is variable y : csigned; begin @@ -273,6 +300,7 @@ begin begin -- internal z_next <= z_int; + z_sign_next <= z_sign_int; strich_next <= strich_int; punkt_next <= punkt_int; wtmp_next <= wtmp_int; @@ -291,6 +319,7 @@ begin goto_calcn1 <= '0'; goto_op1 <= '0'; goto_space3 <= '0'; + goto_sign <= '0'; case state_int is when SIDLE => @@ -299,6 +328,7 @@ begin opp_next <= ALU_NOP; when SREAD_NEWNUMBER => z_next <= (others => '0'); + z_sign_next <= '0'; rbyte_next <= (others => '0'); p_write_next <= (others => '0'); aktop_next <= ALU_NOP; @@ -308,6 +338,12 @@ begin case p_read is when x"20" => null; + when x"2D" => + case state_int is + when SREAD_SPACE2 => goto_sign <= '1'; + when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1'; + when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen"; + end case; when others => goto_calcn1 <= '1'; p_rget_next <= '1'; @@ -330,6 +366,8 @@ begin multmp := (z_int * 10) + hbyte2csigned(p_read); z_next <= multmp((CBITS-1) downto 0); end case; + when SREAD_SIGN1 => + z_sign_next <= '1'; when SREAD_CALCNUMBER2 | SREAD_OP2 => null; when SREAD_OP1 => @@ -358,11 +396,19 @@ begin when SCALC_1 => + if z_sign_int = '1' then + tmp := (not z_int) + 1; + z_next <= tmp; + z_sign_next <= '0'; + else + tmp := z_int; + end if; + case opp_int is when ALU_NOP | ALU_ADD | ALU_SUB => case opp_int is - when ALU_SUB => op1_next <= (not z_int) + 1; - when others => op1_next <= z_int; + when ALU_SUB => op1_next <= (not tmp) + 1; + when others => op1_next <= tmp; end case; case aktop_int is when ALU_ADD | ALU_SUB | ALU_DONE => @@ -379,7 +425,7 @@ begin when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV => op1_next <= punkt_int; opcode_next <= opp_int; - op2_next <= z_int; + op2_next <= tmp; when others => assert(false) report "SCALC_1/2: shouldn't happen!"; end case; when others => assert(false) report "SCALC_1/3: shouldn't happen!"; @@ -405,7 +451,12 @@ begin when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV => case aktop_int is when ALU_ADD | ALU_SUB | ALU_DONE => - strich_next <= op3; + if aktop_int = ALU_DONE and op3 < 0 then + strich_next <= (not op3) + 1; + z_sign_next <= '1'; + else + strich_next <= op3; + end if; when ALU_MUL | ALU_DIV => punkt_next <= op3; when others => assert (false) report "SCALC_2/1: shouldn't happen!"; @@ -423,6 +474,16 @@ begin when SWRITE_CHAR2 => strich_next <= wtmp_int; + when SWRITE_SIGN1 => + null; + when SWRITE_SIGN2 => + if z_sign_int = '1' then + p_wtake_next <= '1'; + p_write_next <= x"2D"; + else + assert(false) report "SWRITE_SIGN: shouldn't happen!"; + end if; + when SERROR1 => -- TODO null; -- 2.25.1