Add Tercel PHY reset synchronization
[microwatt.git] / divider_tb.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.decode_types.all;
7 use work.common.all;
8 use work.glibc_random.all;
9 use work.ppc_fx_insns.all;
10
11 entity divider_tb is
12 end divider_tb;
13
14 architecture behave of divider_tb is
15 signal clk : std_ulogic;
16 signal rst : std_ulogic;
17 constant clk_period : time := 10 ns;
18
19 signal d1 : Execute1ToDividerType;
20 signal d2 : DividerToExecute1Type;
21 begin
22 divider_0: entity work.divider
23 port map (clk => clk, rst => rst, d_in => d1, d_out => d2);
24
25 clk_process: process
26 begin
27 clk <= '0';
28 wait for clk_period/2;
29 clk <= '1';
30 wait for clk_period/2;
31 end process;
32
33 stim_process: process
34 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
35 variable si: std_ulogic_vector(15 downto 0);
36 variable d128: std_ulogic_vector(127 downto 0);
37 variable q128: std_ulogic_vector(127 downto 0);
38 variable q64: std_ulogic_vector(63 downto 0);
39 variable rem32: std_ulogic_vector(31 downto 0);
40 begin
41 rst <= '1';
42 wait for clk_period;
43 rst <= '0';
44
45 d1.valid <= '1';
46 d1.dividend <= x"0000000010001000";
47 d1.divisor <= x"0000000000001111";
48 d1.is_signed <= '0';
49 d1.is_32bit <= '0';
50 d1.is_extended <= '0';
51 d1.is_modulus <= '0';
52 d1.neg_result <= '0';
53
54 wait for clk_period;
55 assert d2.valid = '0';
56
57 d1.valid <= '0';
58
59 for j in 0 to 66 loop
60 wait for clk_period;
61 if d2.valid = '1' then
62 exit;
63 end if;
64 end loop;
65
66 assert d2.valid = '1';
67 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
68
69 wait for clk_period;
70 assert d2.valid = '0' report "valid";
71
72 d1.valid <= '1';
73
74 wait for clk_period;
75 assert d2.valid = '0' report "valid";
76
77 d1.valid <= '0';
78
79 for j in 0 to 66 loop
80 wait for clk_period;
81 if d2.valid = '1' then
82 exit;
83 end if;
84 end loop;
85
86 assert d2.valid = '1';
87 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
88
89 wait for clk_period;
90 assert d2.valid = '0';
91
92 -- test divd
93 report "test divd";
94 divd_loop : for dlength in 1 to 8 loop
95 for vlength in 1 to dlength loop
96 for i in 0 to 100 loop
97 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
98 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
99
100 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
101 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
102 d1.is_signed <= '1';
103 d1.neg_result <= ra(63) xor rb(63);
104 d1.valid <= '1';
105
106 wait for clk_period;
107
108 d1.valid <= '0';
109 for j in 0 to 66 loop
110 wait for clk_period;
111 if d2.valid = '1' then
112 exit;
113 end if;
114 end loop;
115 assert d2.valid = '1';
116
117 behave_rt := (others => '0');
118 if rb /= x"0000000000000000" and (ra /= x"8000000000000000" or rb /= x"ffffffffffffffff") then
119 behave_rt := ppc_divd(ra, rb);
120 end if;
121 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
122 report "bad divd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
123 end loop;
124 end loop;
125 end loop;
126
127 -- test divdu
128 report "test divdu";
129 divdu_loop : for dlength in 1 to 8 loop
130 for vlength in 1 to dlength loop
131 for i in 0 to 100 loop
132 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
133 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
134
135 d1.dividend <= ra;
136 d1.divisor <= rb;
137 d1.is_signed <= '0';
138 d1.neg_result <= '0';
139 d1.valid <= '1';
140
141 wait for clk_period;
142
143 d1.valid <= '0';
144 for j in 0 to 66 loop
145 wait for clk_period;
146 if d2.valid = '1' then
147 exit;
148 end if;
149 end loop;
150 assert d2.valid = '1';
151
152 behave_rt := (others => '0');
153 if rb /= x"0000000000000000" then
154 behave_rt := ppc_divdu(ra, rb);
155 end if;
156 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
157 report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
158 end loop;
159 end loop;
160 end loop;
161
162 -- test divde
163 report "test divde";
164 divde_loop : for vlength in 1 to 8 loop
165 for dlength in 1 to vlength loop
166 for i in 0 to 100 loop
167 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
168 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
169
170 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
171 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
172 d1.is_signed <= '1';
173 d1.neg_result <= ra(63) xor rb(63);
174 d1.is_extended <= '1';
175 d1.valid <= '1';
176
177 wait for clk_period;
178
179 d1.valid <= '0';
180 for j in 0 to 66 loop
181 wait for clk_period;
182 if d2.valid = '1' then
183 exit;
184 end if;
185 end loop;
186 assert d2.valid = '1';
187
188 behave_rt := (others => '0');
189 if rb /= x"0000000000000000" then
190 d128 := ra & x"0000000000000000";
191 q128 := std_ulogic_vector(signed(d128) / signed(rb));
192 if q128(127 downto 63) = x"0000000000000000" & '0' or
193 q128(127 downto 63) = x"ffffffffffffffff" & '1' then
194 behave_rt := q128(63 downto 0);
195 end if;
196 end if;
197 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
198 report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
199 end loop;
200 end loop;
201 end loop;
202
203 -- test divdeu
204 report "test divdeu";
205 divdeu_loop : for vlength in 1 to 8 loop
206 for dlength in 1 to vlength loop
207 for i in 0 to 100 loop
208 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
209 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
210
211 d1.dividend <= ra;
212 d1.divisor <= rb;
213 d1.is_signed <= '0';
214 d1.neg_result <= '0';
215 d1.is_extended <= '1';
216 d1.valid <= '1';
217
218 wait for clk_period;
219
220 d1.valid <= '0';
221 for j in 0 to 66 loop
222 wait for clk_period;
223 if d2.valid = '1' then
224 exit;
225 end if;
226 end loop;
227 assert d2.valid = '1';
228
229 behave_rt := (others => '0');
230 if unsigned(rb) > unsigned(ra) then
231 d128 := ra & x"0000000000000000";
232 q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb));
233 behave_rt := q128(63 downto 0);
234 end if;
235 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
236 report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
237 end loop;
238 end loop;
239 end loop;
240
241 -- test divw
242 report "test divw";
243 divw_loop : for dlength in 1 to 4 loop
244 for vlength in 1 to dlength loop
245 for i in 0 to 100 loop
246 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
247 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
248
249 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
250 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
251 d1.is_signed <= '1';
252 d1.neg_result <= ra(63) xor rb(63);
253 d1.is_extended <= '0';
254 d1.is_32bit <= '1';
255 d1.valid <= '1';
256
257 wait for clk_period;
258
259 d1.valid <= '0';
260 for j in 0 to 66 loop
261 wait for clk_period;
262 if d2.valid = '1' then
263 exit;
264 end if;
265 end loop;
266 assert d2.valid = '1';
267
268 behave_rt := (others => '0');
269 if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then
270 behave_rt := ppc_divw(ra, rb);
271 end if;
272 assert behave_rt = d2.write_reg_data
273 report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
274 end loop;
275 end loop;
276 end loop;
277
278 -- test divwu
279 report "test divwu";
280 divwu_loop : for dlength in 1 to 4 loop
281 for vlength in 1 to dlength loop
282 for i in 0 to 100 loop
283 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
284 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
285
286 d1.dividend <= ra;
287 d1.divisor <= rb;
288 d1.is_signed <= '0';
289 d1.neg_result <= '0';
290 d1.is_extended <= '0';
291 d1.is_32bit <= '1';
292 d1.valid <= '1';
293
294 wait for clk_period;
295
296 d1.valid <= '0';
297 for j in 0 to 66 loop
298 wait for clk_period;
299 if d2.valid = '1' then
300 exit;
301 end if;
302 end loop;
303 assert d2.valid = '1';
304
305 behave_rt := (others => '0');
306 if rb /= x"0000000000000000" then
307 behave_rt := ppc_divwu(ra, rb);
308 end if;
309 assert behave_rt = d2.write_reg_data
310 report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
311 end loop;
312 end loop;
313 end loop;
314
315 -- test divwe
316 report "test divwe";
317 divwe_loop : for vlength in 1 to 4 loop
318 for dlength in 1 to vlength loop
319 for i in 0 to 100 loop
320 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 32)) & x"00000000";
321 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
322
323 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
324 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
325 d1.is_signed <= '1';
326 d1.neg_result <= ra(63) xor rb(63);
327 d1.is_extended <= '0';
328 d1.is_32bit <= '1';
329 d1.valid <= '1';
330
331 wait for clk_period;
332
333 d1.valid <= '0';
334 for j in 0 to 66 loop
335 wait for clk_period;
336 if d2.valid = '1' then
337 exit;
338 end if;
339 end loop;
340 assert d2.valid = '1';
341
342 behave_rt := (others => '0');
343 if rb /= x"0000000000000000" then
344 q64 := std_ulogic_vector(signed(ra) / signed(rb));
345 if q64(63 downto 31) = x"00000000" & '0' or
346 q64(63 downto 31) = x"ffffffff" & '1' then
347 behave_rt := x"00000000" & q64(31 downto 0);
348 end if;
349 assert behave_rt = d2.write_reg_data
350 report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
351 end if;
352 end loop;
353 end loop;
354 end loop;
355
356 -- test divweu
357 report "test divweu";
358 divweu_loop : for vlength in 1 to 4 loop
359 for dlength in 1 to vlength loop
360 for i in 0 to 100 loop
361 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 32)) & x"00000000";
362 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
363
364 d1.dividend <= ra;
365 d1.divisor <= rb;
366 d1.is_signed <= '0';
367 d1.neg_result <= '0';
368 d1.is_extended <= '0';
369 d1.is_32bit <= '1';
370 d1.valid <= '1';
371
372 wait for clk_period;
373
374 d1.valid <= '0';
375 for j in 0 to 66 loop
376 wait for clk_period;
377 if d2.valid = '1' then
378 exit;
379 end if;
380 end loop;
381 assert d2.valid = '1';
382
383 behave_rt := (others => '0');
384 if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then
385 behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb));
386 end if;
387 assert behave_rt = d2.write_reg_data
388 report "bad divweu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
389 end loop;
390 end loop;
391 end loop;
392
393 -- test modsd
394 report "test modsd";
395 modsd_loop : for dlength in 1 to 8 loop
396 for vlength in 1 to dlength loop
397 for i in 0 to 100 loop
398 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
399 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
400
401 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
402 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
403 d1.is_signed <= '1';
404 d1.neg_result <= ra(63);
405 d1.is_extended <= '0';
406 d1.is_32bit <= '0';
407 d1.is_modulus <= '1';
408 d1.valid <= '1';
409
410 wait for clk_period;
411
412 d1.valid <= '0';
413 for j in 0 to 66 loop
414 wait for clk_period;
415 if d2.valid = '1' then
416 exit;
417 end if;
418 end loop;
419 assert d2.valid = '1';
420
421 behave_rt := (others => '0');
422 if rb /= x"0000000000000000" then
423 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
424 end if;
425 assert behave_rt = d2.write_reg_data
426 report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
427 end loop;
428 end loop;
429 end loop;
430
431 -- test modud
432 report "test modud";
433 modud_loop : for dlength in 1 to 8 loop
434 for vlength in 1 to dlength loop
435 for i in 0 to 100 loop
436 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
437 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
438
439 d1.dividend <= ra;
440 d1.divisor <= rb;
441 d1.is_signed <= '0';
442 d1.neg_result <= '0';
443 d1.is_extended <= '0';
444 d1.is_32bit <= '0';
445 d1.is_modulus <= '1';
446 d1.valid <= '1';
447
448 wait for clk_period;
449
450 d1.valid <= '0';
451 for j in 0 to 66 loop
452 wait for clk_period;
453 if d2.valid = '1' then
454 exit;
455 end if;
456 end loop;
457 assert d2.valid = '1';
458
459 behave_rt := (others => '0');
460 if rb /= x"0000000000000000" then
461 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
462 end if;
463 assert behave_rt = d2.write_reg_data
464 report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
465 end loop;
466 end loop;
467 end loop;
468
469 -- test modsw
470 report "test modsw";
471 modsw_loop : for dlength in 1 to 4 loop
472 for vlength in 1 to dlength loop
473 for i in 0 to 100 loop
474 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
475 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
476
477 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
478 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
479 d1.is_signed <= '1';
480 d1.neg_result <= ra(63);
481 d1.is_extended <= '0';
482 d1.is_32bit <= '1';
483 d1.is_modulus <= '1';
484 d1.valid <= '1';
485
486 wait for clk_period;
487
488 d1.valid <= '0';
489 for j in 0 to 66 loop
490 wait for clk_period;
491 if d2.valid = '1' then
492 exit;
493 end if;
494 end loop;
495 assert d2.valid = '1';
496
497 behave_rt := (others => '0');
498 if rb /= x"0000000000000000" then
499 rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0)));
500 if rem32(31) = '0' then
501 behave_rt := x"00000000" & rem32;
502 else
503 behave_rt := x"ffffffff" & rem32;
504 end if;
505 end if;
506 assert behave_rt = d2.write_reg_data
507 report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
508 end loop;
509 end loop;
510 end loop;
511
512 -- test moduw
513 report "test moduw";
514 moduw_loop : for dlength in 1 to 4 loop
515 for vlength in 1 to dlength loop
516 for i in 0 to 100 loop
517 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
518 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
519
520 d1.dividend <= ra;
521 d1.divisor <= rb;
522 d1.is_signed <= '0';
523 d1.neg_result <= '0';
524 d1.is_extended <= '0';
525 d1.is_32bit <= '1';
526 d1.is_modulus <= '1';
527 d1.valid <= '1';
528
529 wait for clk_period;
530
531 d1.valid <= '0';
532 for j in 0 to 66 loop
533 wait for clk_period;
534 if d2.valid = '1' then
535 exit;
536 end if;
537 end loop;
538 assert d2.valid = '1';
539
540 behave_rt := (others => '0');
541 if rb /= x"0000000000000000" then
542 behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0)));
543 end if;
544 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
545 report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
546 end loop;
547 end loop;
548 end loop;
549
550 std.env.finish;
551 end process;
552 end behave;