X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fparser.vhd;h=c2e6ed3f4e41b81cd772307cbec7b9420105f259;hb=f102be1de251276231f062df996fadc90227ae81;hp=a2a2cafc73aee2aa74895449e68b043296444072;hpb=05882ef8805341c413d6f4748766fc01bcd2b3f7;p=hwmod.git diff --git a/src/parser.vhd b/src/parser.vhd index a2a2caf..c2e6ed3 100644 --- a/src/parser.vhd +++ b/src/parser.vhd @@ -25,7 +25,7 @@ entity parser is op3 : in csigned; do_calc : out std_logic; calc_done : in std_logic; - -- TODO: calc_error : in std_logic; + calc_error : in std_logic; -- Scanner do_it : in std_logic; finished : out std_logic @@ -34,9 +34,11 @@ end entity parser; architecture beh of parser is type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_NEXTBYTE, - SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SDONE); + SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR1, + SWRITE_CHAR2, 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 rbyte_int, rbyte_next : hbyte; signal p_write_int, p_write_next : hbyte; signal p_rget_int, p_rget_next : std_logic; @@ -65,6 +67,7 @@ begin state_int <= SIDLE; z_int <= (others => '0'); strich_int <= (others => '0'); + punkt_int <= (others => '0'); wtmp_int <= (others => '0'); rbyte_int <= (others => '0'); aktop_int <= ALU_NOP; @@ -86,6 +89,7 @@ begin state_int <= state_next; z_int <= z_next; strich_int <= strich_next; + punkt_int <= punkt_next; wtmp_int <= wtmp_next; rbyte_int <= rbyte_next; aktop_int <= aktop_next; @@ -104,7 +108,7 @@ begin -- next state process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int, - strich_next, calc_done, wtmp_int) + punkt_int, calc_done, wtmp_int, opp_int) begin state_next <= state_int; @@ -128,6 +132,21 @@ begin state_next <= SREAD_NEXTBYTE; end if; when SCALC_1 => + if calc_done = '1' then + case opp_int is + when ALU_MUL | ALU_DIV => + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14; + when others => state_next <= SCALC_2; + end case; + when others => state_next <= SCALC_2; + end case; + end if; + when SCALC_14 => + if calc_done = '0' then + state_next <= SCALC_15; + end if; + when SCALC_15 => if calc_done = '1' then state_next <= SCALC_2; end if; @@ -145,7 +164,16 @@ begin state_next <= SWRITE_CHAR2; end if; end if; - when SWRITE_CHAR2 => + when SERROR1 => + if p_wdone = '1' then + -- TODO + if strich_int < 10 then + state_next <= SDONE; + else + state_next <= SWRITE_CHAR2; + end if; + end if; + when SWRITE_CHAR2 | SERROR2 => if p_wdone = '0' then state_next <= SWRITE_CHAR1; end if; @@ -159,7 +187,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) + do_calc_int, wtmp_int, punkt_int) function hbyte2csigned (x : hbyte) return csigned is variable y : csigned; begin @@ -204,6 +232,7 @@ begin -- internal z_next <= z_int; strich_next <= strich_int; + punkt_next <= punkt_int; wtmp_next <= wtmp_int; rbyte_next <= rbyte_int; aktop_next <= aktop_int; @@ -221,6 +250,7 @@ begin case state_int is when SIDLE => strich_next <= (others => '0'); + punkt_next <= (0 => '1', others => '0'); opp_next <= ALU_NOP; when SREAD_NEWNUMBER => z_next <= (others => '0'); @@ -234,6 +264,16 @@ begin -- '+' when x"2B" => aktop_next <= ALU_ADD; + -- '-' + when x"2D" => + -- TODO: sign check beim ersten byte lesen! + aktop_next <= ALU_SUB; + -- '*' + when x"2A" => + aktop_next <= ALU_MUL; + -- '/' + when x"2F" => + aktop_next <= ALU_DIV; -- '\0' when x"00" => @@ -249,26 +289,84 @@ begin when SCALC_1 => case opp_int is - when ALU_NOP | ALU_ADD => - op1_next <= z_int; + 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; + end case; case aktop_int is - when ALU_ADD | ALU_SUB | ALU_NOP | ALU_DONE => + when ALU_ADD | ALU_SUB | ALU_DONE => opcode_next <= ALU_ADD; op2_next <= strich_int; when ALU_MUL | ALU_DIV => opcode_next <= ALU_MUL; + op2_next <= punkt_int; + when others => assert(false) report "SCALC_1/1: shouldn't happen!"; + end case; + + when ALU_MUL | ALU_DIV => + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_DONE => + op2_next <= z_int; + opcode_next <= opp_int; + op1_next <= punkt_int; + when ALU_MUL | ALU_DIV => + op2_next <= z_int; + opcode_next <= opp_int; + op1_next <= punkt_int; + when others => assert(false) report "SCALC_1/2: shouldn't happen!"; + end case; + when others => assert(false) report "SCALC_1/3: shouldn't happen!"; + end case; + do_calc_next <= '1'; + + when SCALC_14 => + case opp_int is + when ALU_MUL | ALU_DIV => + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_DONE => + op1_next <= op3; + do_calc_next <= '0'; + when others => assert(false) report("SCALC_14/1: bla!"); + end case; + when others => assert(false) report("SCALC_14/2: bla!"); + end case; + + when SCALC_15 => + case opp_int is + when ALU_MUL | ALU_DIV => + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_DONE => + opcode_next <= ALU_ADD; op2_next <= strich_int; - when others => assert(false) report "SCALC_1/ALU_NOP: not implemented yet"; + punkt_next <= (0 => '1', others => '0'); + do_calc_next <= '1'; + when others => assert(false) report("SCALC_15/1: bla!"); end case; - do_calc_next <= '1'; - when others => assert(false) report "SCALC_1: not implemented yet"; + when others => assert(false) report("SCALC_15/2: bla!"); end case; + when SCALC_2 => case opp_int is - when ALU_NOP | ALU_ADD => - strich_next <= op3; - when others => assert (false) report "SCALC_2: not implemented yet"; + when ALU_NOP | ALU_ADD | ALU_SUB => + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_DONE => + strich_next <= op3; + when ALU_MUL | ALU_DIV => + punkt_next <= op3; + when others => assert (false) report "SCALC_2/1: shouldn't happen!"; + end case; + when ALU_MUL | ALU_DIV => + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_DONE => + strich_next <= op3; + when ALU_MUL | ALU_DIV => + punkt_next <= op3; + when others => assert(false) report "SCALC_2/2: shouldn't happen!"; + end case; + when others => assert (false) report "SCALC_2/3: shouldn't happen!"; end case; + opp_next <= aktop_int; when SWRITE_CHAR1 => @@ -279,6 +377,13 @@ begin when SWRITE_CHAR2 => strich_next <= wtmp_int; + when SERROR1 => + -- TODO + null; + when SERROR2 => + -- TODO + null; + when SDONE => p_finished_next <= '1'; end case;