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