uart_rx: ein prozessmodell. spart weitere 3 logic elements :P
[hwmod.git] / src / post_alu_tb.vhd
index 7a960787ac4ac5a4af685898ada14ce7d43d551b..ce4bcc3850df5a5b61cd42e4f72ef395519d6b4e 100644 (file)
@@ -7,6 +7,7 @@ entity post_alu_tb is
 end entity post_alu_tb;
 
 architecture sim of post_alu_tb is
+       -- TODO: braucht man hier wirklich eine andere entity definition?
        component alu is
                port
                (
@@ -16,14 +17,16 @@ architecture sim of post_alu_tb is
                        op1 : in std_logic_vector(31 downto 0);
                        op2 : in std_logic_vector(31 downto 0);
                        op3 : out std_logic_vector(31 downto 0);
+                       opM : 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, opM : std_logic_vector((CBITS-1) downto 0);
        signal stop : boolean := false;
 begin
        inst : alu
@@ -36,7 +39,9 @@ begin
                op1 => op1,
                op2 => op2,
                op3 => op3,
-               opcode => opcode
+               opM => opM,
+               opcode => opcode,
+               calc_error => calc_error
        );
 
        process
@@ -55,34 +60,87 @@ begin
                        o1 : cinteger;
                        o : alu_ops;
                        o2 : cinteger;
+                       om : 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 65) 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, 2, -1, false),
+                         1 => (7, ALU_ADD, 3, 0, 10, false),
+                         2 => (7, ALU_SUB, 1, 0, 6, false),
+                         3 => (7, ALU_DIV, 1, 0, 7, false),
+                         4 => (7, ALU_DIV, 3, 1, 2, false),
+                         5 => (7, ALU_ADD, 1, 0, 8, false),
+                         6 => (7, ALU_MUL, 3, 0, 21, false),
+                         7 => (-7, ALU_MUL, 3, 0, -21, false),
+                         8 => (268435456, ALU_MUL, -2, 0, -536870912, false),
+                         9 => (268435456, ALU_MUL, 2**5, 0, 0, false), -- um fuenf nach links shiften
+                         10 => (268435456 + 5, ALU_MUL, 2**5, 0, 160, false), -- = 5 * (2^5)
+                         11 => (100, ALU_DIV, 10, 0, 10, false),
+                         12 => (100, ALU_DIV, 51, 49, 1, false),
+                         13 => (100, ALU_DIV, 49, 2, 2, false),
+                         14 => (153156, ALU_DIV, 3543, 807, 43, false),
+                         15 => (-153156, ALU_DIV, 3543, 807, -43, false),
+                         16 => (153156, ALU_DIV, -3543, 807, -43, false),
+                         17 => (-153156, ALU_DIV, -3543, 807, 43, false),
+                         -- add: sign and under-/overflow check
+                         18 => (2147483647, ALU_ADD, -1, 0, 2147483646, false),
+                         19 => (2147483647, ALU_ADD, 1, 0, 0, true),
+                         20 => (-2147483645, ALU_ADD, -100, 0, 0, true),
+                         21 => (7, ALU_ADD, 1, 0, 8, false),
+                         22 => (7, ALU_ADD, -1, 0, 6, false),
+                         23 => (-7, ALU_ADD, 1, 0, -6, false),
+                         24 => (-7, ALU_ADD, -1, 0, -8, false),
+                         -- sub: sign and under-/overflow check
+                         25 => (-7, ALU_SUB, 1, 0, -8, false),
+                         26 => (-7, ALU_SUB, -1, 0, -6, false),
+                         27 => (7, ALU_SUB, 1, 0, 6, false),
+                         28 => (7, ALU_SUB, -1, 0, 8, false),
+                         29 => (-2147483645, ALU_SUB, 1000, 0, 0, true),
+                         30 => (2147483645, ALU_SUB, -1000, 0, 0, true),
+                         31 => (-1000, ALU_SUB, 2147483645, 0, 0, true),
+                         32 => (1000, ALU_SUB, -2147483645, 0, 0, true),
+                         -- mul: sign and under-/overflow check
+                         33 => (3, ALU_MUL, 2, 0, 6, false),
+                         34 => (3, ALU_MUL, -2, 0, -6, false),
+                         35 => (-3, ALU_MUL, 2, 0, -6, false),
+                         36 => (-3, ALU_MUL, -2, 0, 6, false),
+                         37 => (90000, ALU_MUL, 100000, 0, 0, true),
+                         38 => (90000, ALU_MUL, -100000, 0, 0, true),
+                         39 => (-90000, ALU_MUL, 100000, 0, 0, true),
+                         40 => (-90000, ALU_MUL, -100000, 0, 0, true),
+                         -- div: overflow check und division durch null
+                         41 => (-2147483648, ALU_DIV, -1, 0, 0, true),
+                         42 => (-2147483648, ALU_DIV, 0, 0, 0, true),
+                         43 => (-4, ALU_DIV, 2, 0, -2, false),
+                         -- div/mod:
+                         44 => (1234, ALU_DIV, 3, 1, 411, false),
+                         45 => (1, ALU_DIV, 10, 1, 0, false),
+                         46 => (2, ALU_DIV, 10, 2, 0, false),
+                         47 => (3, ALU_DIV, 10, 3, 0, false),
+                         48 => (4, ALU_DIV, 10, 4, 0, false),
+                         49 => (5, ALU_DIV, 10, 5, 0, false),
+                         50 => (6, ALU_DIV, 10, 6, 0, false),
+                         51 => (7, ALU_DIV, 10, 7, 0, false),
+                         52 => (8, ALU_DIV, 10, 8, 0, false),
+                         53 => (9, ALU_DIV, 10, 9, 0, false),
+                         54 => (0, ALU_DIV, 10, 0, 0, false),
+                         55 => (10, ALU_DIV, 10, 0, 1, false),
+                         56 => (5134123, ALU_DIV, 358015, 121913, 14, false),
+                         -- extra
+                         60 => (5, ALU_SUB, -2147483648, 0, 0, true),
+                         61 => (-2147483647, ALU_SUB, 1, 0, -2147483648, false),
+                         62 => (-2147483647, ALU_ADD, -1, 0, -2147483648, false),
+                         63 => (-2147483648, ALU_DIV, 10, 8, -214748364, false),
+                         64 => (-214748364, ALU_DIV, 10, 4, -21474836, false),
+                         65 => (1, ALU_DIV, -2147483648, 1, 0, false),
+                         others => (0, ALU_ADD, 0, 0, 0, false)
                        );
-
+               variable checkall : boolean := true;
        begin
                -- init & reset
                sys_res_n <= '0';
@@ -107,20 +165,40 @@ 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 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
+                               if not((op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))) and (opcode /= ALU_DIV or opM = std_logic_vector(to_signed(testmatrix(i).om,CBITS)))) then
+                                       assert(false) 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;
+                               end if;
+                       end if;
 
                        icwait(sys_clk, 2);
                        -- ack it!
                        do_calc <= '0';
                end loop;
 
-               assert false
+               if checkall then
                        report "alle testfaelle der ALU waren erfolgreich!";
+               else
+                       report "einige testfaelle schlugen fehl";
+               end if;
                stop <= true;
                wait;
        end process;