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