parser: ausdruecke werden erfolgreich geparst, einschraenkungen:
authorBernhard Urban <lewurm@gmail.com>
Mon, 10 May 2010 23:29:46 +0000 (01:29 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 10 May 2010 23:29:46 +0000 (01:29 +0200)
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
src/alu.vhd
src/beh_alu_tb.vhd
src/beh_parser_tb.do
src/beh_parser_tb.vhd
src/parser.test
src/parser.vhd

index 1fef3ff4e08c75e7df86a12b9bb91f5f44b95621..5d297b1640fc3c9dc1047cd3d12898cd3cf381e9 100755 (executable)
@@ -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
index 7a57b59229cd1ad6f63287f827c14e42bdc8d4ee..a1b7a41438e18ee6776ef3a5f9caf53b8b3bf041 100644 (file)
@@ -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;
index 8a3f5b3b3c774a3f46a8d448729bbd82a2dcefc5..cb303cece71801bd13a99d7525bacf78d8516542 100644 (file)
@@ -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;
index 35fed77b6df4960c670c2c46b50e3e8812af1a78..b7e63b6058d8f0efb05397cdaaa633b298289db0 100644 (file)
@@ -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
index 70ed098ad03a685d6df3353048ed4a47148bdc06..61d25447fed37a482cd15c77ae97f7d64149dc66 100644 (file)
@@ -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,
index f27bc3a09f918a3020bb25d274a5fa4d1ed8b2c7..c1463740d519adeb3c906d514e7aaf8dba6341de 100644 (file)
 # 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
index a2a2cafc73aee2aa74895449e68b043296444072..c2e6ed3f4e41b81cd772307cbec7b9420105f259 100644 (file)
@@ -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;