2 context vunit_lib.vunit_context;
5 use ieee.std_logic_1164.all;
6 use ieee.numeric_std.all;
9 use work.decode_types.all;
11 use work.ppc_fx_insns.all;
14 use osvvm.RandomPkg.all;
17 generic (runner_cfg : string := runner_cfg_default);
20 architecture behave of divider_tb is
21 signal clk : std_ulogic;
22 signal rst : std_ulogic;
23 constant clk_period : time := 10 ns;
25 signal d1 : Execute1ToDividerType;
26 signal d2 : DividerToExecute1Type;
28 divider_0: entity work.divider
29 port map (clk => clk, rst => rst, d_in => d1, d_out => d2);
34 wait for clk_period/2;
36 wait for clk_period/2;
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;
48 rnd.InitSeed(stim_process'path_name);
50 test_runner_setup(runner, runner_cfg);
59 d1.is_extended <= '0';
64 if run("Test interface") then
66 d1.dividend <= x"0000000010001000";
67 d1.divisor <= x"0000000000001111";
70 check_false(?? d2.valid, result("for valid"));
76 if d2.valid = '1' then
81 check_true(?? d2.valid, result("for valid"));
82 check_equal(d2.write_reg_data, 16#f001#);
85 check_false(?? d2.valid, result("for valid"));
90 check_false(?? d2.valid, result("for valid"));
96 if d2.valid = '1' then
101 check_true(?? d2.valid, result("for valid"));
102 check_equal(d2.write_reg_data, 16#f001#);
105 check_false(?? d2.valid, result("for valid"));
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));
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));
117 d1.neg_result <= ra(63) xor rb(63);
123 for j in 0 to 66 loop
125 if d2.valid = '1' then
129 check_true(?? d2.valid, result("for valid"));
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);
135 check_equal(d2.write_reg_data, behave_rt, result("for divd"));
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));
154 for j in 0 to 66 loop
156 if d2.valid = '1' then
160 check_true(?? d2.valid, result("for valid"));
162 behave_rt := (others => '0');
163 if rb /= x"0000000000000000" then
164 behave_rt := ppc_divdu(ra, rb);
166 check_equal(d2.write_reg_data, behave_rt, result("for divdu"));
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));
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));
181 d1.neg_result <= ra(63) xor rb(63);
182 d1.is_extended <= '1';
188 for j in 0 to 66 loop
190 if d2.valid = '1' then
194 check_true(?? d2.valid, result("for valid"));
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);
205 check_equal(d2.write_reg_data, behave_rt, result("for divde"));
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));
219 d1.is_extended <= '1';
225 for j in 0 to 66 loop
227 if d2.valid = '1' then
231 check_true(?? d2.valid, result("for valid"));
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);
239 check_equal(d2.write_reg_data, behave_rt, result("for divdeu"));
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));
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));
254 d1.neg_result <= ra(63) xor rb(63);
261 for j in 0 to 66 loop
263 if d2.valid = '1' then
267 check_true(?? d2.valid, result("for valid"));
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);
273 check_equal(d2.write_reg_data, behave_rt, result("for divw"));
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));
293 for j in 0 to 66 loop
295 if d2.valid = '1' then
299 check_true(?? d2.valid, result("for valid"));
301 behave_rt := (others => '0');
302 if rb /= x"0000000000000000" then
303 behave_rt := ppc_divwu(ra, rb);
305 check_equal(d2.write_reg_data, behave_rt, result("for divwu"));
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));
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));
320 d1.neg_result <= ra(63) xor rb(63);
327 for j in 0 to 66 loop
329 if d2.valid = '1' then
333 check_true(?? d2.valid, result("for valid"));
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);
342 check_equal(d2.write_reg_data, behave_rt, result("for divwe"));
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));
363 for j in 0 to 66 loop
365 if d2.valid = '1' then
369 check_true(?? d2.valid, result("for valid"));
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));
375 check_equal(d2.write_reg_data, behave_rt, result("for divweu"));
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));
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));
390 d1.neg_result <= ra(63);
391 d1.is_modulus <= '1';
397 for j in 0 to 66 loop
399 if d2.valid = '1' then
403 check_true(?? d2.valid, result("for valid"));
405 behave_rt := (others => '0');
406 if rb /= x"0000000000000000" then
407 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
409 check_equal(d2.write_reg_data, behave_rt, result("for modsd"));
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));
423 d1.is_modulus <= '1';
429 for j in 0 to 66 loop
431 if d2.valid = '1' then
435 check_true(?? d2.valid, result("for valid"));
437 behave_rt := (others => '0');
438 if rb /= x"0000000000000000" then
439 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
441 check_equal(d2.write_reg_data, behave_rt, result("for modud"));
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));
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));
456 d1.neg_result <= ra(63);
458 d1.is_modulus <= '1';
464 for j in 0 to 66 loop
466 if d2.valid = '1' then
470 check_true(?? d2.valid, result("for valid"));
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;
478 behave_rt := x"ffffffff" & rem32;
481 check_equal(d2.write_reg_data, behave_rt, result("for modsw"));
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));
496 d1.is_modulus <= '1';
502 for j in 0 to 66 loop
504 if d2.valid = '1' then
508 check_true(?? d2.valid, result("for valid"));
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)));
514 check_equal(d2.write_reg_data(31 downto 0), behave_rt(31 downto 0), result("for moduw"));
521 test_runner_cleanup(runner);