From f102be1de251276231f062df996fadc90227ae81 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Tue, 11 May 2010 01:29:46 +0200 Subject: [PATCH] parser: ausdruecke werden erfolgreich geparst, einschraenkungen: o keine negative zahlen o keine leerzeichen o kein errorhandling o division und modulo gehoeren noch ersetzt ausserdem: bugfix in der alu (division hat nicht ganz gepasst bei negativen zahlen) --- quartus/project_web.tcl | 4 +- src/alu.vhd | 11 ++-- src/beh_alu_tb.vhd | 1 + src/beh_parser_tb.do | 5 ++ src/beh_parser_tb.vhd | 4 +- src/parser.test | 27 ++++++++ src/parser.vhd | 133 +++++++++++++++++++++++++++++++++++----- 7 files changed, 162 insertions(+), 23 deletions(-) diff --git a/quartus/project_web.tcl b/quartus/project_web.tcl index 1fef3ff..5d297b1 100755 --- a/quartus/project_web.tcl +++ b/quartus/project_web.tcl @@ -32,11 +32,11 @@ if {$make_assignments} { set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED" #set_global_assignment -name TOP_LEVEL_ENTITY calc - set_global_assignment -name TOP_LEVEL_ENTITY alu + set_global_assignment -name TOP_LEVEL_ENTITY parser set_global_assignment -name VHDL_FILE ../../src/gen_pkg.vhd #set_global_assignment -name VHDL_FILE ../../src/calc.vhd set_global_assignment -name VHDL_FILE ../../src/alu.vhd - #set_global_assignment -name VHDL_FILE ../../src/parser.vhd + set_global_assignment -name VHDL_FILE ../../src/parser.vhd set_location_assignment PIN_N3 -to sys_clk set_location_assignment PIN_AF17 -to sys_res_n diff --git a/src/alu.vhd b/src/alu.vhd index 7a57b59..a1b7a41 100644 --- a/src/alu.vhd +++ b/src/alu.vhd @@ -23,7 +23,7 @@ architecture beh of alu is SDONE, SERROR); signal state_int, state_next : ALU_STATE; signal done_intern, error_intern, div_calc_done, div_go_calc : std_logic; - signal op3_int, op3_next : csigned := (others => '0'); + signal op3_int, op3_next : csigned; signal calc_done_int, calc_done_next : std_logic; signal calc_error_int, calc_error_next : std_logic; -- signale fuer division @@ -138,7 +138,7 @@ begin op1_next <= (others => '0'); op2_next <= (others => '0'); sign_next <= '0'; - op3_next <= (others => '0'); + op3_next <= op3_int; case state_int is when SIDLE => @@ -170,7 +170,7 @@ begin op3_next(CBITS-1) <= mulsign; if mulsign = '1' then - multmp2 := not (multmp + 1); + multmp2 := (not multmp) + 1; else multmp2 := multmp; end if; @@ -190,10 +190,10 @@ begin op1_var := op1; op2_var := op2; if op1(CBITS-1) = '1' then - op1_var := not (op1_var + 1); + op1_var := (not op1_var) + 1; end if; if op2(CBITS-1) = '1' then - op2_var := not (op2_var + 1); + op2_var := (not op2_var) + 1; end if; dividend_msb_var := find_msb(op1_var)-1; @@ -243,7 +243,6 @@ begin if (state_int = SERROR) then calc_error_next <= '1'; end if; - op3_next <= op3_int; end case; end process; end architecture beh; diff --git a/src/beh_alu_tb.vhd b/src/beh_alu_tb.vhd index 8a3f5b3..cb303ce 100644 --- a/src/beh_alu_tb.vhd +++ b/src/beh_alu_tb.vhd @@ -97,6 +97,7 @@ begin -- mul: overflow check und division durch null 41 => (-2147483648, ALU_DIV, -1, 0, true), 42 => (-2147483648, ALU_DIV, 0, 0, true), + 43 => (-4, ALU_DIV, 2, -2, false), others => (0, ALU_ADD, 0, 0, false) ); variable checkall : boolean := true; diff --git a/src/beh_parser_tb.do b/src/beh_parser_tb.do index 35fed77..b7e63b6 100644 --- a/src/beh_parser_tb.do +++ b/src/beh_parser_tb.do @@ -27,6 +27,11 @@ delete wave /beh_parser_tb/inst/strich_next add wave -radix decimal inst/strich_int add wave -radix decimal inst/strich_next +delete wave /beh_parser_tb/inst/punkt_int +delete wave /beh_parser_tb/inst/punkt_next +add wave -radix decimal inst/punkt_int +add wave -radix decimal inst/punkt_next + delete wave /beh_parser_tb/inst/wtmp_int delete wave /beh_parser_tb/inst/wtmp_next add wave -radix decimal inst/wtmp_int diff --git a/src/beh_parser_tb.vhd b/src/beh_parser_tb.vhd index 70ed098..61d2544 100644 --- a/src/beh_parser_tb.vhd +++ b/src/beh_parser_tb.vhd @@ -17,7 +17,7 @@ architecture sim of beh_parser_tb is -- alu signal opcode : alu_ops; signal op1, op2, op3 : csigned; - signal do_calc, calc_done : std_logic; + signal do_calc, calc_done, calc_error : std_logic; --scanner signal do_it : std_logic; @@ -46,6 +46,7 @@ begin op3 => op3, do_calc => do_calc, calc_done => calc_done, + calc_error => calc_error, -- TODO: calc_error : in std_logic; -- Scanner do_it => do_it, @@ -59,6 +60,7 @@ begin sys_res_n => sys_res_n, do_calc => do_calc, calc_done => calc_done, + calc_error => calc_error, op1 => op1, op2 => op2, op3 => op3, diff --git a/src/parser.test b/src/parser.test index f27bc3a..c146374 100644 --- a/src/parser.test +++ b/src/parser.test @@ -18,3 +18,30 @@ # t6: 98+123+531511+131 531863 +# t7: +513-1-200 +312 +# t8 +5*10*200 +10000 +# t9 +100-30-50 +20 +# t10 +10*20+2000*10 +20200 +# t11 +1000/10 +100 +# t12 +1000/10/2-20 +30 +# t13 +10+2/2 +11 +# t14 +10-4/2 +8 +# t15 +1000-4*100+5-300/2 +455 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; -- 2.25.1