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