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);
44 d1.write_reg <= "10001";
45 d1.dividend <= x"0000000010001000";
46 d1.divisor <= x"0000000000001111";
49 d1.is_extended <= '0';
54 assert d2.valid = '0';
60 if d2.valid = '1' then
65 assert d2.valid = '1';
66 assert d2.write_reg_enable = '1';
67 assert d2.write_reg_nr = "10001";
68 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
69 assert d2.write_cr_enable = '0';
72 assert d2.valid = '0' report "valid";
78 assert d2.valid = '0' report "valid";
84 if d2.valid = '1' then
89 assert d2.valid = '1';
90 assert d2.write_reg_enable = '1';
91 assert d2.write_reg_nr = "10001";
92 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
93 assert d2.write_cr_enable = '1';
94 assert d2.write_cr_mask = "10000000";
95 assert d2.write_cr_data = x"40000000" report "cr data is " & to_hstring(d2.write_cr_data);
98 assert d2.valid = '0';
102 divd_loop : for dlength in 1 to 8 loop
103 for vlength in 1 to dlength loop
104 for i in 0 to 100 loop
105 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
106 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
116 for j in 0 to 65 loop
118 if d2.valid = '1' then
122 assert d2.valid = '1';
124 if rb /= x"0000000000000000" then
125 behave_rt := ppc_divd(ra, rb);
126 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
127 report "bad divd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
128 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
129 report "bad CR setting for divd";
137 divdu_loop : for dlength in 1 to 8 loop
138 for vlength in 1 to dlength loop
139 for i in 0 to 100 loop
140 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
141 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
151 for j in 0 to 65 loop
153 if d2.valid = '1' then
157 assert d2.valid = '1';
159 if rb /= x"0000000000000000" then
160 behave_rt := ppc_divdu(ra, rb);
161 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
162 report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
163 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
164 report "bad CR setting for divdu";
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(pseudorand(dlength * 8)), 64));
176 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
181 d1.is_extended <= '1';
187 for j in 0 to 65 loop
189 if d2.valid = '1' then
193 assert d2.valid = '1';
195 if rb /= x"0000000000000000" then
196 d128 := ra & x"0000000000000000";
197 q128 := std_ulogic_vector(signed(d128) / signed(rb));
198 if q128(127 downto 63) = x"0000000000000000" & '0' or
199 q128(127 downto 63) = x"ffffffffffffffff" & '1' then
200 behave_rt := q128(63 downto 0);
201 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
202 report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
203 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
204 report "bad CR setting for divde";
212 report "test divdeu";
213 divdeu_loop : for vlength in 1 to 8 loop
214 for dlength in 1 to vlength loop
215 for i in 0 to 100 loop
216 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
217 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
222 d1.is_extended <= '1';
228 for j in 0 to 65 loop
230 if d2.valid = '1' then
234 assert d2.valid = '1';
236 if unsigned(rb) > unsigned(ra) then
237 d128 := ra & x"0000000000000000";
238 q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb));
239 behave_rt := q128(63 downto 0);
240 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
241 report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
242 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
243 report "bad CR setting for divdeu";
251 divw_loop : for dlength in 1 to 4 loop
252 for vlength in 1 to dlength loop
253 for i in 0 to 100 loop
254 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
255 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
260 d1.is_extended <= '0';
267 for j in 0 to 65 loop
269 if d2.valid = '1' then
273 assert d2.valid = '1';
275 if rb /= x"0000000000000000" then
276 behave_rt := ppc_divw(ra, rb);
277 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
278 report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
279 assert ppc_cmpi('0', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
280 report "bad CR setting for divw";
288 divwu_loop : for dlength in 1 to 4 loop
289 for vlength in 1 to dlength loop
290 for i in 0 to 100 loop
291 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
292 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
297 d1.is_extended <= '0';
304 for j in 0 to 65 loop
306 if d2.valid = '1' then
310 assert d2.valid = '1';
312 if rb /= x"0000000000000000" then
313 behave_rt := ppc_divwu(ra, rb);
314 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
315 report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
316 assert ppc_cmpi('0', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
317 report "bad CR setting for divwu";
325 divwe_loop : for vlength in 1 to 4 loop
326 for dlength in 1 to vlength loop
327 for i in 0 to 100 loop
328 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 32)) & x"00000000";
329 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
334 d1.is_extended <= '0';
341 for j in 0 to 65 loop
343 if d2.valid = '1' then
347 assert d2.valid = '1';
349 if rb /= x"0000000000000000" then
350 behave_rt := std_ulogic_vector(signed(ra) / signed(rb));
351 if behave_rt(63 downto 31) = x"00000000" & '0' or
352 behave_rt(63 downto 31) = x"ffffffff" & '1' then
353 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
354 report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
355 assert ppc_cmpi('0', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
356 report "bad CR setting for divwe";
364 report "test divweu";
365 divweu_loop : for vlength in 1 to 4 loop
366 for dlength in 1 to vlength loop
367 for i in 0 to 100 loop
368 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 32)) & x"00000000";
369 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
374 d1.is_extended <= '0';
381 for j in 0 to 65 loop
383 if d2.valid = '1' then
387 assert d2.valid = '1';
389 if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then
390 behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb));
391 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
392 report "bad divweu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
393 assert ppc_cmpi('0', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
394 report "bad CR setting for divweu";
402 modsd_loop : for dlength in 1 to 8 loop
403 for vlength in 1 to dlength loop
404 for i in 0 to 100 loop
405 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
406 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
411 d1.is_extended <= '0';
413 d1.is_modulus <= '1';
419 for j in 0 to 65 loop
421 if d2.valid = '1' then
425 assert d2.valid = '1';
427 if rb /= x"0000000000000000" then
428 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
429 assert behave_rt = d2.write_reg_data
430 report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
431 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
432 report "bad CR setting for modsd";
440 modud_loop : for dlength in 1 to 8 loop
441 for vlength in 1 to dlength loop
442 for i in 0 to 100 loop
443 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
444 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
449 d1.is_extended <= '0';
451 d1.is_modulus <= '1';
457 for j in 0 to 65 loop
459 if d2.valid = '1' then
463 assert d2.valid = '1';
465 if rb /= x"0000000000000000" then
466 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
467 assert behave_rt = d2.write_reg_data
468 report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
469 assert ppc_cmpi('1', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
470 report "bad CR setting for modud";
478 modsw_loop : for dlength in 1 to 4 loop
479 for vlength in 1 to dlength loop
480 for i in 0 to 100 loop
481 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
482 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
487 d1.is_extended <= '0';
489 d1.is_modulus <= '1';
495 for j in 0 to 65 loop
497 if d2.valid = '1' then
501 assert d2.valid = '1';
503 if rb /= x"0000000000000000" then
504 behave_rt := x"00000000" & std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0)));
505 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
506 report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
507 assert ppc_cmpi('0', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
508 report "bad CR setting for modsw";
516 moduw_loop : for dlength in 1 to 4 loop
517 for vlength in 1 to dlength loop
518 for i in 0 to 100 loop
519 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
520 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
525 d1.is_extended <= '0';
527 d1.is_modulus <= '1';
533 for j in 0 to 65 loop
535 if d2.valid = '1' then
539 assert d2.valid = '1';
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 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
544 report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
545 assert ppc_cmpi('0', behave_rt, x"0000") & x"0000000" = d2.write_cr_data
546 report "bad CR setting for moduw";
552 assert false report "end of test" severity failure;