parser/alu: extrem mega super sonderfall bugfix
[hwmod.git] / src / parser.vhd
index ec03fedc4e407f4c4ef9a98e68562b9422d501ed..8fa3a2b3c38a8679d275ff5bfd3d8956802d7354 100644 (file)
@@ -9,8 +9,6 @@ entity parser is
                sys_clk : in std_logic;
                sys_res_n : in std_logic;
                -- History
-               p_rw : out std_logic;
-               p_spalte : out hspalte;
                p_rget : out std_logic;
                p_rdone : in std_logic;
                p_read : in hbyte;
@@ -38,6 +36,7 @@ architecture beh of parser is
        signal p_rget_int, p_rget_next : std_logic;
        signal p_wtake_int, p_wtake_next : std_logic;
        signal p_finished_int, p_finished_next : std_logic;
+       signal finished_int, finished_next : std_logic;
        signal aktop_int, aktop_next : alu_ops;
        signal opp_int, opp_next : alu_ops;
        signal opcode_int, opcode_next : alu_ops;
@@ -79,6 +78,7 @@ begin
        p_rget <= p_rget_int;
        p_wtake <= p_wtake_int;
        p_finished <= p_finished_int;
+       finished <= finished_int;
 
        opcode <= opcode_int;
        op1 <= op1_int;
@@ -98,21 +98,19 @@ begin
                        aktop_int <= ALU_NOP;
                        opp_int <= ALU_NOP;
                        err_int <= 0;
-                       errc_int <= 70;
+                       errc_int <= 71;
                        errc_tmp_int <= 0;
                        firstz_int <= true;
                        -- out ports
-                       p_rw <= '0';
-                       p_spalte <= (others => '0');
                        p_rget_int <= '0';
                        p_write_int <= (others => '0');
                        p_wtake_int <= '0';
                        p_finished_int <= '0';
+                       finished_int <= '0';
                        opcode_int <= ALU_NOP;
                        op1_int <= (others => '0');
                        op2_int <= (others => '0');
                        do_calc_int <= '0';
-                       finished <= '0';
                elsif rising_edge(sys_clk) then
                        -- internal
                        state_int <= state_next;
@@ -133,6 +131,7 @@ begin
                        p_write_int <= p_write_next;
                        p_wtake_int <= p_wtake_next;
                        p_finished_int <= p_finished_next;
+                       finished_int <= finished_next;
                        opcode_int <= opcode_next;
                        op1_int <= op1_next;
                        op2_int <= op2_next;
@@ -249,7 +248,9 @@ begin
                                end if;
                        when SWRITE_CHAR1 =>
                                if p_wdone = '1' then
-                                       if strich_int < 10 then
+                                       -- ueberpruefung auf -2147483648 fuer testfall 39 und 40
+                                       -- x"80000000": xst (xilinx) workaround
+                                       if strich_int < 10 and strich_int /= x"80000000" then
                                                if z_sign_int = '1' then
                                                        state_next <= SWRITE_SIGN1;
                                                else
@@ -349,9 +350,9 @@ begin
 
                type errstrings is array (natural range 1 to 3) of hstring;
                constant error_str : errstrings := (
-                       1 => "                                                   Division durch Null" & nul,
-                       2 => "                                                                Syntax" & nul,
-                       3 => "                                                  Over- bzw. Underflow" & nul
+                       1 => " > Fehler:                             Division durch Null             " & nul,
+                       2 => " > Fehler:                             Syntax                          " & nul,
+                       3 => " > Fehler:                             Over- bzw. Underflow            " & nul
                );
        begin
                -- internal
@@ -372,6 +373,7 @@ begin
                p_write_next <= p_write_int;
                p_wtake_next <= '0';
                p_finished_next <= '0';
+               finished_next <= '0';
                opcode_next <= opcode_int;
                op1_next <= op1_int;
                op2_next <= op2_int;
@@ -463,7 +465,15 @@ begin
                                case opp_int is
                                        when ALU_NOP | ALU_ADD | ALU_SUB =>
                                                case opp_int  is
-                                                       when ALU_SUB => op1_next <= (not tmp) + 1;
+                                                       when ALU_SUB =>
+                                                               -- xst (xilinx) workaround
+                                                               if x"80000000" = tmp then
+                                                                       -- vgl. testfall 37 und 38
+                                                                       err_next <= 3;
+                                                                       op1_next <= tmp;
+                                                               else
+                                                                       op1_next <= (not tmp) + 1;
+                                                               end if;
                                                        when others => op1_next <= tmp;
                                                end case;
                                                case aktop_int is
@@ -519,13 +529,20 @@ begin
                                                                punkt_next <= op3;
                                                        when others => assert (false) report "SCALC_2/1: shouldn't happen!";
                                                end case;
+                                       when ALU_DONE => null;
                                        when others => assert (false) report "SCALC_2/2: shouldn't happen!";
                                end case;
                                -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
                                opp_next <= aktop_int;
 
                        when SWRITE_CHAR0 =>
-                               op1_next <= strich_int;
+                               -- fuer testfall 39 und 40
+                               if strich_int = to_signed(-214748364,CBITS) then
+                                       op1_next <= to_signed(214748364,CBITS);
+                                       strich_next <= to_signed(214748364,CBITS);
+                               else
+                                       op1_next <= strich_int;
+                               end if;
                                opcode_next <= ALU_DIV;
                                op2_next <= to_signed(10,CBITS);
                                do_calc_next <= '1';
@@ -557,8 +574,9 @@ begin
 
                        when SDONE =>
                                err_next <= 0;
-                               errc_next <= 70;
+                               errc_next <= 71;
                                p_finished_next <= '1';
+                               finished_next <= '1';
                end case;
 
                -- fehlerbehandlung