alu: error flag setzen bei overflow/underflow bzw. bei division durch 0
authorBernhard Urban <lewurm@gmail.com>
Mon, 10 May 2010 21:00:42 +0000 (23:00 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 10 May 2010 21:00:42 +0000 (23:00 +0200)
quartus/project_web.tcl
src/alu.vhd
src/beh_alu_tb.do
src/beh_alu_tb.vhd
src/gen_pkg.vhd
src/parser.vhd
src/post_alu_tb.vhd

index 5d297b1640fc3c9dc1047cd3d12898cd3cf381e9..1fef3ff4e08c75e7df86a12b9bb91f5f44b95621 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 parser
+       set_global_assignment -name TOP_LEVEL_ENTITY alu
        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 cdb9fdd44254ecd9d5815827c877455ee6b8325c..7a57b59229cd1ad6f63287f827c14e42bdc8d4ee 100644 (file)
@@ -13,17 +13,19 @@ entity alu is
                op2 : in csigned;
                op3 : out csigned;
                do_calc : in std_logic;
-               calc_done : out std_logic
-               -- TODO: calc_error : out std_logic;
+               calc_done : out std_logic;
+               calc_error : out std_logic
        );
 end entity alu;
 
 architecture beh of alu is
-       type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDIV_CALC, SDIV_DONE, SDONE);
+       type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDIV_CALC, SDIV_DONE,
+       SDONE, SERROR);
        signal state_int, state_next : ALU_STATE;
-       signal done_intern, div_calc_done, div_go_calc : std_logic;
+       signal done_intern, error_intern, div_calc_done, div_go_calc : std_logic;
        signal op3_int, op3_next : csigned := (others => '0');
        signal calc_done_int, calc_done_next : std_logic;
+       signal calc_error_int, calc_error_next : std_logic;
        -- signale fuer division
        signal dividend_msb_int, dividend_msb_next, laengediv_int, laengediv_next : natural;
        signal quo_int, quo_next, aktdiv_int, aktdiv_int_next, op1_int, op1_next, op2_int, op2_next : csigned;
@@ -31,6 +33,7 @@ architecture beh of alu is
 begin
        op3 <= op3_int;
        calc_done <= calc_done_int;
+       calc_error <= calc_error_int;
 
        -- sync
        process(sys_clk, sys_res_n)
@@ -39,6 +42,7 @@ begin
                        state_int <= SIDLE;
                        op3_int <= (others => '0');
                        calc_done_int <= '0';
+                       calc_error_int <= '0';
                        --div
                        dividend_msb_int <= 0;
                        laengediv_int <= 0;
@@ -51,6 +55,7 @@ begin
                        state_int <= state_next;
                        op3_int <= op3_next;
                        calc_done_int <= calc_done_next;
+                       calc_error_int <= calc_error_next;
                        -- div
                        dividend_msb_int <= dividend_msb_next;
                        laengediv_int <= laengediv_next;
@@ -63,7 +68,8 @@ begin
        end process;
 
        -- next state
-       process(state_int, opcode, done_intern, do_calc, div_calc_done, div_go_calc)
+       process(state_int, opcode, done_intern, error_intern, do_calc,
+               div_calc_done, div_go_calc)
        begin
                -- set a default value for next state
                state_next <= state_int;
@@ -88,15 +94,21 @@ begin
                                if done_intern = '1' then
                                        state_next <= SDONE;
                                end if;
+                               if error_intern = '1' then
+                                       state_next <= SERROR;
+                               end if;
                        when SDIV =>
                                if div_go_calc = '1' then
                                        state_next <= SDIV_CALC;
                                end if;
+                               if error_intern = '1' then
+                                       state_next <= SERROR;
+                               end if;
                        when SDIV_CALC =>
                                if div_calc_done = '1' then
                                        state_next <= SDIV_DONE;
                                end if;
-                       when SDONE =>
+                       when SDONE | SERROR =>
                                if do_calc = '0' then
                                        state_next <= SIDLE;
                                end if;
@@ -105,15 +117,19 @@ begin
 
        -- output
        process(state_int, op1, op2, dividend_msb_int, laengediv_int, quo_int, aktdiv_int, sign_int, op1_int, op2_int, op3_int)
-               variable multmp : signed(((2*CBITS)-1) downto 0);
+               variable multmp, multmp2 : signed(((2*CBITS)-1) downto 0);
+               variable mulsign : std_logic;
+               variable tmp : csigned;
                -- vars fuer div
                variable laengediv_var, dividend_msb_var : natural;
                variable aktdiv_int_var, quo_var, op1_var, op2_var : csigned;
        begin
                calc_done_next <= '0';
+               calc_error_next <= '0';
                div_calc_done <= '0';
                div_go_calc <= '0';
                done_intern <= '0';
+               error_intern <= '0';
                -- default fuer div
                dividend_msb_next <= 0;
                laengediv_next <= 0;
@@ -128,21 +144,47 @@ begin
                        when SIDLE =>
                                null;
                        when SADD =>
-                               op3_next <= op1 + op2;
-                               done_intern <= '1';
+                               tmp := op1 + op2;
+                               op3_next <= tmp;
+
+                               -- over- bzw. underflow?
+                               if (op1(CBITS-1) = op2(CBITS-1)) and (op1(CBITS-1) /= tmp(CBITS -1)) then
+                                       error_intern <= '1';
+                               else
+                                       done_intern <= '1';
+                               end if;
                        when SSUB =>
-                               op3_next <= op1 - op2;
-                               done_intern <= '1';
+                               tmp := op1 - op2;
+                               op3_next <= tmp;
+
+                               -- over- bzw. underflow?
+                               if (op1(CBITS-1) /= op2(CBITS-1)) and (op1(CBITS-1) /= tmp(CBITS -1)) then
+                                       error_intern <= '1';
+                               else
+                                       done_intern <= '1';
+                               end if;
                        when SMUL =>
+                               mulsign := op1(CBITS-1) xor op2(CBITS-1);
                                multmp := op1 * op2;
-                               op3_next(CBITS-1) <= multmp((2*CBITS)-1);
                                op3_next((CBITS-2) downto 0) <= multmp((CBITS-2) downto 0);
-                               done_intern <= '1';
+                               op3_next(CBITS-1) <= mulsign;
+
+                               if mulsign = '1' then
+                                       multmp2 := not (multmp + 1);
+                               else
+                                       multmp2 := multmp;
+                               end if;
+                               -- overflow?
+                               if(multmp2((2*CBITS)-2 downto (CBITS-1)) > 0) then
+                                       error_intern <= '1';
+                               else
+                                       done_intern <= '1';
+                               end if;
+
                        when SDIV =>
                                -- division implementiert nach ~hwmod/doc/division.pdf
-                               if op2 = to_signed(0,CBITS) then
-                                       -- TODO: err out signal
-                                       done_intern <= '1';
+                               if ((op1 = x"80000000" and op2 = to_signed(-1, CBITS)) or op2 = to_signed(0, CBITS)) then
+                                       error_intern <= '1';
                                else
                                        -- sign check
                                        op1_var := op1;
@@ -196,8 +238,11 @@ begin
                        when SDIV_DONE =>
                                op3_next <= quo_int;
                                done_intern <= '1';
-                       when SDONE =>
+                       when SDONE | SERROR =>
                                calc_done_next <= '1';
+                               if (state_int = SERROR) then
+                                       calc_error_next <= '1';
+                               end if;
                                op3_next <= op3_int;
                end case;
        end process;
index 27a93631bd731e6a3e73c5034bed4b0e6b373547..3a147704ec8670ec4b7267a7cf9e745d72360240 100644 (file)
@@ -2,14 +2,23 @@
 alias rr "restart -f"
 
 #signale hinzufuegen
-add wave sys_clk
-add wave sys_res_n
-add wave -radix decimal op1
-add wave opcode
-add wave -radix decimal op2
-add wave -radix decimal op3
-add wave do_calc
-add wave calc_done
+add wave inst/*
+
+delete wave /beh_alu_tb/inst/op1_int
+delete wave /beh_alu_tb/inst/op1
+delete wave /beh_alu_tb/inst/op1_next
+add wave -radix decimal inst/op1_int
+
+delete wave /beh_alu_tb/inst/op2_int
+delete wave /beh_alu_tb/inst/op1
+delete wave /beh_alu_tb/inst/op2_next
+add wave -radix decimal inst/op2_int
+
+delete wave /beh_alu_tb/inst/op3_int
+delete wave /beh_alu_tb/inst/op1
+delete wave /beh_alu_tb/inst/op3_next
+add wave -radix decimal inst/op3_int
+
 
 #rauszoomen
 wave zoomout 500.0
index 0da87c23242c55700ab63b4d0fc744b3afd72769..8a3f5b3b3c774a3f46a8d448729bbd82a2dcefc5 100644 (file)
@@ -7,7 +7,7 @@ entity beh_alu_tb is
 end entity beh_alu_tb;
 
 architecture sim of beh_alu_tb is
-       signal sys_clk, sys_res_n, do_calc, calc_done : std_logic;
+       signal sys_clk, sys_res_n, do_calc, calc_done, calc_error : std_logic;
        signal opcode : alu_ops;
        signal op1, op2, op3 : csigned;
        signal stop : boolean := false;
@@ -22,7 +22,8 @@ begin
                op1 => op1,
                op2 => op2,
                op3 => op3,
-               opcode => opcode
+               opcode => opcode,
+               calc_error => calc_error
        );
 
        process
@@ -42,31 +43,61 @@ begin
                        o : alu_ops;
                        o2 : cinteger;
                        expected : cinteger;
+                       errcase : boolean;
                end record alu_testv;
 
                -- ggf. groesse des arrays erhoehen
-               type alu_testv_array is array (natural range 0 to 30) of alu_testv;
+               type alu_testv_array is array (natural range 0 to 44) of alu_testv;
 
                variable testmatrix : alu_testv_array :=
-                       ( 0 => (-5, ALU_DIV, 3, -1),
-                         1 => (7, ALU_ADD, 3, 10),
-                         2 => (7, ALU_SUB, 1, 6),
-                         3 => (7, ALU_DIV, 1, 7),
-                         4 => (7, ALU_DIV, 3, 2),
-                         5 => (7, ALU_ADD, 1, 8),
-                         6 => (7, ALU_MUL, 3, 21),
-                         7 => (-7, ALU_MUL, 3, -21),
-                         8 => (268435456, ALU_MUL, -2, -536870912),
-                         9 => (268435456, ALU_MUL, 2**5, 0), -- um fuenf nach links shiften
-                         10 => (268435456 + 5, ALU_MUL, 2**5, 160), -- = 5 * (2^5)
-                         11 => (100, ALU_DIV, 10, 10),
-                         12 => (100, ALU_DIV, 51, 1),
-                         13 => (100, ALU_DIV, 49, 2),
-                         14 => (153156, ALU_DIV, 3543, 43),
-                         15 => (-153156, ALU_DIV, 3543, -43),
-                         16 => (153156, ALU_DIV, -3543, -43),
-                         17 => (-153156, ALU_DIV, -3543, 43),
-                         others => (0, ALU_ADD, 0, 0)
+                       ( 0 => (-5, ALU_DIV, 3, -1, false),
+                         1 => (7, ALU_ADD, 3, 10, false),
+                         2 => (7, ALU_SUB, 1, 6, false),
+                         3 => (7, ALU_DIV, 1, 7, false),
+                         4 => (7, ALU_DIV, 3, 2, false),
+                         5 => (7, ALU_ADD, 1, 8, false),
+                         6 => (7, ALU_MUL, 3, 21, false),
+                         7 => (-7, ALU_MUL, 3, -21, false),
+                         8 => (268435456, ALU_MUL, -2, -536870912, false),
+                         9 => (268435456, ALU_MUL, 2**5, 0, false), -- um fuenf nach links shiften
+                         10 => (268435456 + 5, ALU_MUL, 2**5, 160, false), -- = 5 * (2^5)
+                         11 => (100, ALU_DIV, 10, 10, false),
+                         12 => (100, ALU_DIV, 51, 1, false),
+                         13 => (100, ALU_DIV, 49, 2, false),
+                         14 => (153156, ALU_DIV, 3543, 43, false),
+                         15 => (-153156, ALU_DIV, 3543, -43, false),
+                         16 => (153156, ALU_DIV, -3543, -43, false),
+                         17 => (-153156, ALU_DIV, -3543, 43, false),
+                         -- add: sign and under-/overflow check
+                         18 => (2147483647, ALU_ADD, -1, 2147483646, false),
+                         19 => (2147483647, ALU_ADD, 1, 0, true),
+                         20 => (-2147483645, ALU_ADD, -100, 0, true),
+                         21 => (7, ALU_ADD, 1, 8, false),
+                         22 => (7, ALU_ADD, -1, 6, false),
+                         23 => (-7, ALU_ADD, 1, -6, false),
+                         24 => (-7, ALU_ADD, -1, -8, false),
+                         -- sub: sign and under-/overflow check
+                         25 => (-7, ALU_SUB, 1, -8, false),
+                         26 => (-7, ALU_SUB, -1, -6, false),
+                         27 => (7, ALU_SUB, 1, 6, false),
+                         28 => (7, ALU_SUB, -1, 8, false),
+                         29 => (-2147483645, ALU_SUB, 1000, 0, true),
+                         30 => (2147483645, ALU_SUB, -1000, 0, true),
+                         31 => (-1000, ALU_SUB, 2147483645, 0, true),
+                         32 => (1000, ALU_SUB, -2147483645, 0, true),
+                         -- mul: sign and under-/overflow check
+                         33 => (3, ALU_MUL, 2, 6, false),
+                         34 => (3, ALU_MUL, -2, -6, false),
+                         35 => (-3, ALU_MUL, 2, -6, false),
+                         36 => (-3, ALU_MUL, -2, 6, false),
+                         37 => (90000, ALU_MUL, 100000, 0, true),
+                         38 => (90000, ALU_MUL, -100000, 0, true),
+                         39 => (-90000, ALU_MUL, 100000, 0, true),
+                         40 => (-90000, ALU_MUL, -100000, 0, true),
+                         -- mul: overflow check und division durch null
+                         41 => (-2147483648, ALU_DIV, -1, 0, true),
+                         42 => (-2147483648, ALU_DIV, 0, 0, true),
+                         others => (0, ALU_ADD, 0, 0, false)
                        );
                variable checkall : boolean := true;
        begin
@@ -93,15 +124,30 @@ begin
                        wait on calc_done;
                        icwait(sys_clk, 1);
 
-                       assert op3 = to_signed(testmatrix(i).expected,CBITS)
-                               report "" & cinteger'image(testmatrix(i).o1) & 
-                               " " & integer'image(to_integer(signed(opcode))) &
-                               " " & cinteger'image(testmatrix(i).o2) &
-                               "/= " & integer'image(to_integer(op3)) &
-                               " -- erwartet: " & cinteger'image(testmatrix(i).expected);
+                       if testmatrix(i).errcase then
+                               if (calc_error = '0') then
+                                       assert(false) report "sollte ein error sein";
+                                       assert op3 = to_signed(testmatrix(i).expected,CBITS)
+                                               report "" & cinteger'image(testmatrix(i).o1) & 
+                                               " " & integer'image(to_integer(signed(opcode))) &
+                                               " " & cinteger'image(testmatrix(i).o2) &
+                                               "/= " & integer'image(to_integer(op3)) &
+                                               " -- erwartet: " & cinteger'image(testmatrix(i).expected);
+                                       checkall := false;
+                               else
+                                       assert(false) report "testfall war ein error (passt)";
+                               end if;
+                       else
+                               assert op3 = to_signed(testmatrix(i).expected,CBITS)
+                                       report "" & cinteger'image(testmatrix(i).o1) & 
+                                       " " & integer'image(to_integer(signed(opcode))) &
+                                       " " & cinteger'image(testmatrix(i).o2) &
+                                       "/= " & integer'image(to_integer(op3)) &
+                                       " -- erwartet: " & cinteger'image(testmatrix(i).expected);
 
-                       if op3 /= to_signed(testmatrix(i).expected,CBITS) then
-                               checkall := false;
+                               if op3 /= to_signed(testmatrix(i).expected,CBITS) then
+                                       checkall := false;
+                               end if;
                        end if;
 
                        icwait(sys_clk, 2);
@@ -112,7 +158,7 @@ begin
                if checkall then
                        report "alle testfaelle der ALU waren erfolgreich!";
                else
-                       report "nicht alle testfaelle der ALU waren erfolgreich!";
+                       report "einige testfaelle schlugen fehl";
                end if;
                stop <= true;
                wait;
index e5c692e3f1ca74413eb89590fddcd87fce2e850c..7f5e2dc30b387cbc02456b7276f66ac4fa648bd0 100644 (file)
@@ -13,8 +13,8 @@ package gen_pkg is
 
        constant CBITS : integer := 32;
        subtype csigned is signed((CBITS-1) downto 0);
-       --TODO: bei CBITS-1 gibts einen overflow :/
-       subtype cinteger is integer range -(2**(CBITS-2)) to ((2**(CBITS-2))-1);
+       -- integer ist 32bit (31bit + sign)
+       subtype cinteger is integer;
 
        subtype hspalte is std_logic_vector(6 downto 0);
        subtype hzeile is std_logic_vector(4 downto 0);
index e9778da86dc854f58c84f4016e1727e92fa7f2e5..a2a2cafc73aee2aa74895449e68b043296444072 100644 (file)
@@ -159,7 +159,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)
+               do_calc_int, wtmp_int)
                function hbyte2csigned (x : hbyte) return csigned is
                        variable y : csigned;
                begin
index 5c05298d69e77450cf2ecdd3cfca34d7daedc2e4..d113dcaa893060980dac8b1617bf22eb7eb9459d 100644 (file)
@@ -18,13 +18,14 @@ architecture sim of post_alu_tb is
                        op2 : in std_logic_vector(31 downto 0);
                        op3 : out std_logic_vector(31 downto 0);
                        do_calc : in std_logic;
-                       calc_done : out std_logic
+                       calc_done : out std_logic;
+                       calc_error : out std_logic
                );
        end component alu;
 
-       signal sys_clk, sys_res_n, do_calc, calc_done : std_logic;
+       signal sys_clk, sys_res_n, do_calc, calc_done, calc_error : std_logic;
        signal opcode : alu_ops;
-       signal op1, op2, op3 : std_logic_vector(31 downto 0);
+       signal op1, op2, op3 : std_logic_vector((CBITS-1) downto 0);
        signal stop : boolean := false;
 begin
        inst : alu
@@ -37,7 +38,8 @@ begin
                op1 => op1,
                op2 => op2,
                op3 => op3,
-               opcode => opcode
+               opcode => opcode,
+               calc_error => calc_error
        );
 
        process
@@ -57,31 +59,61 @@ begin
                        o : alu_ops;
                        o2 : cinteger;
                        expected : cinteger;
+                       errcase : boolean;
                end record alu_testv;
 
                -- ggf. groesse des arrays erhoehen
-               type alu_testv_array is array (natural range 0 to 20) of alu_testv;
+               type alu_testv_array is array (natural range 0 to 44) of alu_testv;
 
                variable testmatrix : alu_testv_array :=
-                       ( 0 => (-5, ALU_DIV, 3, -1),
-                         1 => (7, ALU_ADD, 3, 10),
-                         2 => (7, ALU_SUB, 1, 6),
-                         3 => (7, ALU_DIV, 1, 7),
-                         4 => (7, ALU_DIV, 3, 2),
-                         5 => (7, ALU_ADD, 1, 8),
-                         6 => (7, ALU_MUL, 3, 21),
-                         7 => (-7, ALU_MUL, 3, -21),
-                         8 => (268435456, ALU_MUL, -2, -536870912),
-                         9 => (268435456, ALU_MUL, 2**5, 0), -- um fuenf nach links shiften
-                         10 => (268435456 + 5, ALU_MUL, 2**5, 160), -- = 5 * (2^5)
-                         11 => (100, ALU_DIV, 10, 10),
-                         12 => (100, ALU_DIV, 51, 1),
-                         13 => (100, ALU_DIV, 49, 2),
-                         14 => (153156, ALU_DIV, 3543, 43),
-                         15 => (-153156, ALU_DIV, 3543, -43),
-                         16 => (153156, ALU_DIV, -3543, -43),
-                         17 => (-153156, ALU_DIV, -3543, 43),
-                         others => (0, ALU_ADD, 0, 0)
+                       ( 0 => (-5, ALU_DIV, 3, -1, false),
+                         1 => (7, ALU_ADD, 3, 10, false),
+                         2 => (7, ALU_SUB, 1, 6, false),
+                         3 => (7, ALU_DIV, 1, 7, false),
+                         4 => (7, ALU_DIV, 3, 2, false),
+                         5 => (7, ALU_ADD, 1, 8, false),
+                         6 => (7, ALU_MUL, 3, 21, false),
+                         7 => (-7, ALU_MUL, 3, -21, false),
+                         8 => (268435456, ALU_MUL, -2, -536870912, false),
+                         9 => (268435456, ALU_MUL, 2**5, 0, false), -- um fuenf nach links shiften
+                         10 => (268435456 + 5, ALU_MUL, 2**5, 160, false), -- = 5 * (2^5)
+                         11 => (100, ALU_DIV, 10, 10, false),
+                         12 => (100, ALU_DIV, 51, 1, false),
+                         13 => (100, ALU_DIV, 49, 2, false),
+                         14 => (153156, ALU_DIV, 3543, 43, false),
+                         15 => (-153156, ALU_DIV, 3543, -43, false),
+                         16 => (153156, ALU_DIV, -3543, -43, false),
+                         17 => (-153156, ALU_DIV, -3543, 43, false),
+                         -- add: sign and under-/overflow check
+                         18 => (2147483647, ALU_ADD, -1, 2147483646, false),
+                         19 => (2147483647, ALU_ADD, 1, 0, true),
+                         20 => (-2147483645, ALU_ADD, -100, 0, true),
+                         21 => (7, ALU_ADD, 1, 8, false),
+                         22 => (7, ALU_ADD, -1, 6, false),
+                         23 => (-7, ALU_ADD, 1, -6, false),
+                         24 => (-7, ALU_ADD, -1, -8, false),
+                         -- sub: sign and under-/overflow check
+                         25 => (-7, ALU_SUB, 1, -8, false),
+                         26 => (-7, ALU_SUB, -1, -6, false),
+                         27 => (7, ALU_SUB, 1, 6, false),
+                         28 => (7, ALU_SUB, -1, 8, false),
+                         29 => (-2147483645, ALU_SUB, 1000, 0, true),
+                         30 => (2147483645, ALU_SUB, -1000, 0, true),
+                         31 => (-1000, ALU_SUB, 2147483645, 0, true),
+                         32 => (1000, ALU_SUB, -2147483645, 0, true),
+                         -- mul: sign and under-/overflow check
+                         33 => (3, ALU_MUL, 2, 6, false),
+                         34 => (3, ALU_MUL, -2, -6, false),
+                         35 => (-3, ALU_MUL, 2, -6, false),
+                         36 => (-3, ALU_MUL, -2, 6, false),
+                         37 => (90000, ALU_MUL, 100000, 0, true),
+                         38 => (90000, ALU_MUL, -100000, 0, true),
+                         39 => (-90000, ALU_MUL, 100000, 0, true),
+                         40 => (-90000, ALU_MUL, -100000, 0, true),
+                         -- mul: overflow check und division durch null
+                         41 => (-2147483648, ALU_DIV, -1, 0, true),
+                         42 => (-2147483648, ALU_DIV, 0, 0, true),
+                         others => (0, ALU_ADD, 0, 0, false)
                        );
                variable checkall : boolean := true;
        begin
@@ -108,14 +140,30 @@ begin
                        wait on calc_done;
                        icwait(sys_clk, 1);
 
-                       assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))
-                               report "" & cinteger'image(testmatrix(i).o1) & 
-                               " " & integer'image(to_integer(signed(opcode))) &
-                               " " & cinteger'image(testmatrix(i).o2) &
-                               "/= " & integer'image(to_integer(signed(op3))) &
-                               " -- erwartet: " & cinteger'image(testmatrix(i).expected);
-                       if op3 /= std_logic_vector(to_signed(testmatrix(i).expected,CBITS)) then
-                               checkall := false;
+                       if testmatrix(i).errcase then
+                               if (calc_error = '0') then
+                                       assert(false) report "sollte ein error sein";
+                                       assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))
+                                               report "" & cinteger'image(testmatrix(i).o1) & 
+                                               " " & integer'image(to_integer(signed(opcode))) &
+                                               " " & cinteger'image(testmatrix(i).o2) &
+                                               "/= " & integer'image(to_integer(signed(op3))) &
+                                               " -- erwartet: " & cinteger'image(testmatrix(i).expected);
+                                       checkall := false;
+                               else
+                                       assert(false) report "testfall war ein error (passt)";
+                               end if;
+                       else
+                               assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))
+                                       report "" & cinteger'image(testmatrix(i).o1) & 
+                                       " " & integer'image(to_integer(signed(opcode))) &
+                                       " " & cinteger'image(testmatrix(i).o2) &
+                                       "/= " & integer'image(to_integer(signed(op3))) &
+                                       " -- erwartet: " & cinteger'image(testmatrix(i).expected);
+
+                               if op3 /= std_logic_vector(to_signed(testmatrix(i).expected,CBITS)) then
+                                       checkall := false;
+                               end if;
                        end if;
 
                        icwait(sys_clk, 2);
@@ -126,7 +174,7 @@ begin
                if checkall then
                        report "alle testfaelle der ALU waren erfolgreich!";
                else
-                       report "nicht alle testfaelle der ALU waren erfolgreich!";
+                       report "einige testfaelle schlugen fehl";
                end if;
                stop <= true;
                wait;