2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
6 use work.decode_types.all;
8 use work.glibc_random.all;
9 use work.ppc_fx_insns.all;
14 architecture behave of divider_tb is
15 signal clk : std_ulogic;
16 signal rst : std_ulogic;
17 constant clk_period : time := 10 ns;
19 signal d1 : Decode2ToDividerType;
20 signal d2 : DividerToWritebackType;
22 divider_0: entity work.divider
23 port map (clk => clk, rst => rst, d_in => d1, d_out => d2);
28 wait for clk_period/2;
30 wait for clk_period/2;
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);
46 d1.write_reg <= "10001";
47 d1.dividend <= x"0000000010001000";
48 d1.divisor <= x"0000000000001111";
51 d1.is_extended <= '0';
56 assert d2.valid = '0';
62 if d2.valid = '1' then
67 assert d2.valid = '1';
68 assert d2.write_reg_enable = '1';
69 assert d2.write_reg_nr = "10001";
70 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
71 assert d2.write_cr_enable = '0';
74 assert d2.valid = '0' report "valid";
80 assert d2.valid = '0' report "valid";
86 if d2.valid = '1' then
91 assert d2.valid = '1';
92 assert d2.write_reg_enable = '1';
93 assert d2.write_reg_nr = "10001";
94 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
95 assert d2.write_cr_enable = '1';
96 assert d2.write_cr_mask = "10000000";
97 assert d2.write_cr_data = x"40000000" report "cr data is " & to_hstring(d2.write_cr_data);
100 assert d2.valid = '0';
104 divd_loop : for dlength in 1 to 8 loop
105 for vlength in 1 to dlength loop
106 for i in 0 to 100 loop
107 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
108 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
118 for j in 0 to 66 loop
120 if d2.valid = '1' then
124 assert d2.valid = '1';
126 behave_rt := (others => '0');
127 if rb /= x"0000000000000000" and (ra /= x"8000000000000000" or rb /= x"ffffffffffffffff") then
128 behave_rt := ppc_divd(ra, rb);
130 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
131 report "bad divd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
132 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
133 report "bad CR setting for divd";
140 divdu_loop : for dlength in 1 to 8 loop
141 for vlength in 1 to dlength loop
142 for i in 0 to 100 loop
143 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
144 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
154 for j in 0 to 66 loop
156 if d2.valid = '1' then
160 assert d2.valid = '1';
162 behave_rt := (others => '0');
163 if rb /= x"0000000000000000" then
164 behave_rt := ppc_divdu(ra, rb);
166 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
167 report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
168 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
169 report "bad CR setting for divdu";
176 divde_loop : for vlength in 1 to 8 loop
177 for dlength in 1 to vlength loop
178 for i in 0 to 100 loop
179 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
180 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
185 d1.is_extended <= '1';
191 for j in 0 to 66 loop
193 if d2.valid = '1' then
197 assert d2.valid = '1';
199 behave_rt := (others => '0');
200 if rb /= x"0000000000000000" then
201 d128 := ra & x"0000000000000000";
202 q128 := std_ulogic_vector(signed(d128) / signed(rb));
203 if q128(127 downto 63) = x"0000000000000000" & '0' or
204 q128(127 downto 63) = x"ffffffffffffffff" & '1' then
205 behave_rt := q128(63 downto 0);
208 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
209 report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
210 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
211 report "bad CR setting for divde";
217 report "test divdeu";
218 divdeu_loop : for vlength in 1 to 8 loop
219 for dlength in 1 to vlength loop
220 for i in 0 to 100 loop
221 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
222 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
227 d1.is_extended <= '1';
233 for j in 0 to 66 loop
235 if d2.valid = '1' then
239 assert d2.valid = '1';
241 behave_rt := (others => '0');
242 if unsigned(rb) > unsigned(ra) then
243 d128 := ra & x"0000000000000000";
244 q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb));
245 behave_rt := q128(63 downto 0);
247 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
248 report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
249 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
250 report "bad CR setting for divdeu";
257 divw_loop : for dlength in 1 to 4 loop
258 for vlength in 1 to dlength loop
259 for i in 0 to 100 loop
260 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
261 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
266 d1.is_extended <= '0';
273 for j in 0 to 66 loop
275 if d2.valid = '1' then
279 assert d2.valid = '1';
281 behave_rt := (others => '0');
282 if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then
283 behave_rt := ppc_divw(ra, rb);
285 assert behave_rt = d2.write_reg_data
286 report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
287 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
288 report "bad CR setting for divw";
295 divwu_loop : for dlength in 1 to 4 loop
296 for vlength in 1 to dlength loop
297 for i in 0 to 100 loop
298 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
299 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
304 d1.is_extended <= '0';
311 for j in 0 to 66 loop
313 if d2.valid = '1' then
317 assert d2.valid = '1';
319 behave_rt := (others => '0');
320 if rb /= x"0000000000000000" then
321 behave_rt := ppc_divwu(ra, rb);
323 assert behave_rt = d2.write_reg_data
324 report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
325 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
326 report "bad CR setting for divwu";
333 divwe_loop : for vlength in 1 to 4 loop
334 for dlength in 1 to vlength loop
335 for i in 0 to 100 loop
336 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 32)) & x"00000000";
337 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
342 d1.is_extended <= '0';
349 for j in 0 to 66 loop
351 if d2.valid = '1' then
355 assert d2.valid = '1';
357 behave_rt := (others => '0');
358 if rb /= x"0000000000000000" then
359 q64 := std_ulogic_vector(signed(ra) / signed(rb));
360 if q64(63 downto 31) = x"00000000" & '0' or
361 q64(63 downto 31) = x"ffffffff" & '1' then
362 behave_rt := x"00000000" & q64(31 downto 0);
364 assert behave_rt = d2.write_reg_data
365 report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
366 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
367 report "bad CR setting for divwe";
374 report "test divweu";
375 divweu_loop : for vlength in 1 to 4 loop
376 for dlength in 1 to vlength loop
377 for i in 0 to 100 loop
378 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 32)) & x"00000000";
379 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
384 d1.is_extended <= '0';
391 for j in 0 to 66 loop
393 if d2.valid = '1' then
397 assert d2.valid = '1';
399 behave_rt := (others => '0');
400 if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then
401 behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb));
403 assert behave_rt = d2.write_reg_data
404 report "bad divweu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
405 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
406 report "bad CR setting for divweu";
413 modsd_loop : for dlength in 1 to 8 loop
414 for vlength in 1 to dlength loop
415 for i in 0 to 100 loop
416 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
417 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
422 d1.is_extended <= '0';
424 d1.is_modulus <= '1';
430 for j in 0 to 66 loop
432 if d2.valid = '1' then
436 assert d2.valid = '1';
438 behave_rt := (others => '0');
439 if rb /= x"0000000000000000" then
440 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
442 assert behave_rt = d2.write_reg_data
443 report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
444 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
445 report "bad CR setting for modsd";
452 modud_loop : for dlength in 1 to 8 loop
453 for vlength in 1 to dlength loop
454 for i in 0 to 100 loop
455 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
456 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
461 d1.is_extended <= '0';
463 d1.is_modulus <= '1';
469 for j in 0 to 66 loop
471 if d2.valid = '1' then
475 assert d2.valid = '1';
477 behave_rt := (others => '0');
478 if rb /= x"0000000000000000" then
479 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
481 assert behave_rt = d2.write_reg_data
482 report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
483 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
484 report "bad CR setting for modud";
491 modsw_loop : for dlength in 1 to 4 loop
492 for vlength in 1 to dlength loop
493 for i in 0 to 100 loop
494 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
495 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
500 d1.is_extended <= '0';
502 d1.is_modulus <= '1';
508 for j in 0 to 66 loop
510 if d2.valid = '1' then
514 assert d2.valid = '1';
516 behave_rt := (others => '0');
517 if rb /= x"0000000000000000" then
518 rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0)));
519 if rem32(31) = '0' then
520 behave_rt := x"00000000" & rem32;
522 behave_rt := x"ffffffff" & rem32;
525 assert behave_rt = d2.write_reg_data
526 report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
527 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
528 report "bad CR setting for modsw";
535 moduw_loop : for dlength in 1 to 4 loop
536 for vlength in 1 to dlength loop
537 for i in 0 to 100 loop
538 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
539 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
544 d1.is_extended <= '0';
546 d1.is_modulus <= '1';
552 for j in 0 to 66 loop
554 if d2.valid = '1' then
558 assert d2.valid = '1';
560 behave_rt := (others => '0');
561 if rb /= x"0000000000000000" then
562 behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0)));
564 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
565 report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
566 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
567 report "bad CR setting for moduw";
572 assert false report "end of test" severity failure;