d113dcaa893060980dac8b1617bf22eb7eb9459d
[hwmod.git] / src / post_alu_tb.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5
6 entity post_alu_tb is
7 end entity post_alu_tb;
8
9 architecture sim of post_alu_tb is
10         -- TODO: braucht man hier wirklich eine andere entity definition?
11         component alu is
12                 port
13                 (
14                         sys_clk : in std_logic;
15                         sys_res_n : in std_logic;
16                         opcode : in alu_ops;
17                         op1 : in std_logic_vector(31 downto 0);
18                         op2 : in std_logic_vector(31 downto 0);
19                         op3 : out std_logic_vector(31 downto 0);
20                         do_calc : in std_logic;
21                         calc_done : out std_logic;
22                         calc_error : out std_logic
23                 );
24         end component alu;
25
26         signal sys_clk, sys_res_n, do_calc, calc_done, calc_error : std_logic;
27         signal opcode : alu_ops;
28         signal op1, op2, op3 : std_logic_vector((CBITS-1) downto 0);
29         signal stop : boolean := false;
30 begin
31         inst : alu
32         port map
33         (
34                 sys_clk => sys_clk,
35                 sys_res_n => sys_res_n,
36                 do_calc => do_calc,
37                 calc_done => calc_done,
38                 op1 => op1,
39                 op2 => op2,
40                 op3 => op3,
41                 opcode => opcode,
42                 calc_error => calc_error
43         );
44
45         process
46         begin
47                 sys_clk <= '0';
48                 wait for 15 ns;
49                 sys_clk <= '1';
50                 wait for 15 ns;
51                 if stop = true then
52                         wait;
53                 end if;
54         end process;
55
56         process
57                 type alu_testv is record
58                         o1 : cinteger;
59                         o : alu_ops;
60                         o2 : cinteger;
61                         expected : cinteger;
62                         errcase : boolean;
63                 end record alu_testv;
64
65                 -- ggf. groesse des arrays erhoehen
66                 type alu_testv_array is array (natural range 0 to 44) of alu_testv;
67
68                 variable testmatrix : alu_testv_array :=
69                         ( 0 => (-5, ALU_DIV, 3, -1, false),
70                           1 => (7, ALU_ADD, 3, 10, false),
71                           2 => (7, ALU_SUB, 1, 6, false),
72                           3 => (7, ALU_DIV, 1, 7, false),
73                           4 => (7, ALU_DIV, 3, 2, false),
74                           5 => (7, ALU_ADD, 1, 8, false),
75                           6 => (7, ALU_MUL, 3, 21, false),
76                           7 => (-7, ALU_MUL, 3, -21, false),
77                           8 => (268435456, ALU_MUL, -2, -536870912, false),
78                           9 => (268435456, ALU_MUL, 2**5, 0, false), -- um fuenf nach links shiften
79                           10 => (268435456 + 5, ALU_MUL, 2**5, 160, false), -- = 5 * (2^5)
80                           11 => (100, ALU_DIV, 10, 10, false),
81                           12 => (100, ALU_DIV, 51, 1, false),
82                           13 => (100, ALU_DIV, 49, 2, false),
83                           14 => (153156, ALU_DIV, 3543, 43, false),
84                           15 => (-153156, ALU_DIV, 3543, -43, false),
85                           16 => (153156, ALU_DIV, -3543, -43, false),
86                           17 => (-153156, ALU_DIV, -3543, 43, false),
87                           -- add: sign and under-/overflow check
88                           18 => (2147483647, ALU_ADD, -1, 2147483646, false),
89                           19 => (2147483647, ALU_ADD, 1, 0, true),
90                           20 => (-2147483645, ALU_ADD, -100, 0, true),
91                           21 => (7, ALU_ADD, 1, 8, false),
92                           22 => (7, ALU_ADD, -1, 6, false),
93                           23 => (-7, ALU_ADD, 1, -6, false),
94                           24 => (-7, ALU_ADD, -1, -8, false),
95                           -- sub: sign and under-/overflow check
96                           25 => (-7, ALU_SUB, 1, -8, false),
97                           26 => (-7, ALU_SUB, -1, -6, false),
98                           27 => (7, ALU_SUB, 1, 6, false),
99                           28 => (7, ALU_SUB, -1, 8, false),
100                           29 => (-2147483645, ALU_SUB, 1000, 0, true),
101                           30 => (2147483645, ALU_SUB, -1000, 0, true),
102                           31 => (-1000, ALU_SUB, 2147483645, 0, true),
103                           32 => (1000, ALU_SUB, -2147483645, 0, true),
104                           -- mul: sign and under-/overflow check
105                           33 => (3, ALU_MUL, 2, 6, false),
106                           34 => (3, ALU_MUL, -2, -6, false),
107                           35 => (-3, ALU_MUL, 2, -6, false),
108                           36 => (-3, ALU_MUL, -2, 6, false),
109                           37 => (90000, ALU_MUL, 100000, 0, true),
110                           38 => (90000, ALU_MUL, -100000, 0, true),
111                           39 => (-90000, ALU_MUL, 100000, 0, true),
112                           40 => (-90000, ALU_MUL, -100000, 0, true),
113                           -- mul: overflow check und division durch null
114                           41 => (-2147483648, ALU_DIV, -1, 0, true),
115                           42 => (-2147483648, ALU_DIV, 0, 0, true),
116                           others => (0, ALU_ADD, 0, 0, false)
117                         );
118                 variable checkall : boolean := true;
119         begin
120                 -- init & reset
121                 sys_res_n <= '0';
122                 do_calc <= '0';
123                 opcode <= ALU_NOP;
124                 op1 <= (others => '0');
125                 op2 <= (others => '0');
126
127                 icwait(sys_clk, 30);
128                 sys_res_n <= '1';
129
130                 for i in testmatrix'range loop
131                         icwait(sys_clk, 10);
132                         op1 <= std_logic_vector(to_signed(testmatrix(i).o1,CBITS));
133                         opcode <= testmatrix(i).o;
134                         op2 <= std_logic_vector(to_signed(testmatrix(i).o2,CBITS));
135
136                         -- berechnung kann los gehen
137                         do_calc <= '1';
138
139                         -- warten auf die alu einheit
140                         wait on calc_done;
141                         icwait(sys_clk, 1);
142
143                         if testmatrix(i).errcase then
144                                 if (calc_error = '0') then
145                                         assert(false) report "sollte ein error sein";
146                                         assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))
147                                                 report "" & cinteger'image(testmatrix(i).o1) & 
148                                                 " " & integer'image(to_integer(signed(opcode))) &
149                                                 " " & cinteger'image(testmatrix(i).o2) &
150                                                 "/= " & integer'image(to_integer(signed(op3))) &
151                                                 " -- erwartet: " & cinteger'image(testmatrix(i).expected);
152                                         checkall := false;
153                                 else
154                                         assert(false) report "testfall war ein error (passt)";
155                                 end if;
156                         else
157                                 assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))
158                                         report "" & cinteger'image(testmatrix(i).o1) & 
159                                         " " & integer'image(to_integer(signed(opcode))) &
160                                         " " & cinteger'image(testmatrix(i).o2) &
161                                         "/= " & integer'image(to_integer(signed(op3))) &
162                                         " -- erwartet: " & cinteger'image(testmatrix(i).expected);
163
164                                 if op3 /= std_logic_vector(to_signed(testmatrix(i).expected,CBITS)) then
165                                         checkall := false;
166                                 end if;
167                         end if;
168
169                         icwait(sys_clk, 2);
170                         -- ack it!
171                         do_calc <= '0';
172                 end loop;
173
174                 if checkall then
175                         report "alle testfaelle der ALU waren erfolgreich!";
176                 else
177                         report "einige testfaelle schlugen fehl";
178                 end if;
179                 stop <= true;
180                 wait;
181         end process;
182 end architecture sim;