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 : Execute1ToDividerType;
20 signal d2 : DividerToExecute1Type;
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.dividend <= x"0000000010001000";
47 d1.divisor <= x"0000000000001111";
50 d1.is_extended <= '0';
55 assert d2.valid = '0';
61 if d2.valid = '1' then
66 assert d2.valid = '1';
67 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
70 assert d2.valid = '0' report "valid";
75 assert d2.valid = '0' report "valid";
81 if d2.valid = '1' then
86 assert d2.valid = '1';
87 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
90 assert d2.valid = '0';
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));
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));
103 d1.neg_result <= ra(63) xor rb(63);
109 for j in 0 to 66 loop
111 if d2.valid = '1' then
115 assert d2.valid = '1';
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);
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);
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));
138 d1.neg_result <= '0';
144 for j in 0 to 66 loop
146 if d2.valid = '1' then
150 assert d2.valid = '1';
152 behave_rt := (others => '0');
153 if rb /= x"0000000000000000" then
154 behave_rt := ppc_divdu(ra, rb);
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);
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));
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));
173 d1.neg_result <= ra(63) xor rb(63);
174 d1.is_extended <= '1';
180 for j in 0 to 66 loop
182 if d2.valid = '1' then
186 assert d2.valid = '1';
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);
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);
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));
214 d1.neg_result <= '0';
215 d1.is_extended <= '1';
221 for j in 0 to 66 loop
223 if d2.valid = '1' then
227 assert d2.valid = '1';
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);
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);
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));
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));
252 d1.neg_result <= ra(63) xor rb(63);
253 d1.is_extended <= '0';
260 for j in 0 to 66 loop
262 if d2.valid = '1' then
266 assert d2.valid = '1';
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);
272 assert behave_rt = d2.write_reg_data
273 report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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));
289 d1.neg_result <= '0';
290 d1.is_extended <= '0';
297 for j in 0 to 66 loop
299 if d2.valid = '1' then
303 assert d2.valid = '1';
305 behave_rt := (others => '0');
306 if rb /= x"0000000000000000" then
307 behave_rt := ppc_divwu(ra, rb);
309 assert behave_rt = d2.write_reg_data
310 report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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));
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));
326 d1.neg_result <= ra(63) xor rb(63);
327 d1.is_extended <= '0';
334 for j in 0 to 66 loop
336 if d2.valid = '1' then
340 assert d2.valid = '1';
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);
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);
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));
367 d1.neg_result <= '0';
368 d1.is_extended <= '0';
375 for j in 0 to 66 loop
377 if d2.valid = '1' then
381 assert d2.valid = '1';
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));
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);
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));
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));
404 d1.neg_result <= ra(63);
405 d1.is_extended <= '0';
407 d1.is_modulus <= '1';
413 for j in 0 to 66 loop
415 if d2.valid = '1' then
419 assert d2.valid = '1';
421 behave_rt := (others => '0');
422 if rb /= x"0000000000000000" then
423 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
425 assert behave_rt = d2.write_reg_data
426 report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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));
442 d1.neg_result <= '0';
443 d1.is_extended <= '0';
445 d1.is_modulus <= '1';
451 for j in 0 to 66 loop
453 if d2.valid = '1' then
457 assert d2.valid = '1';
459 behave_rt := (others => '0');
460 if rb /= x"0000000000000000" then
461 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
463 assert behave_rt = d2.write_reg_data
464 report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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));
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));
480 d1.neg_result <= ra(63);
481 d1.is_extended <= '0';
483 d1.is_modulus <= '1';
489 for j in 0 to 66 loop
491 if d2.valid = '1' then
495 assert d2.valid = '1';
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;
503 behave_rt := x"ffffffff" & rem32;
506 assert behave_rt = d2.write_reg_data
507 report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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));
523 d1.neg_result <= '0';
524 d1.is_extended <= '0';
526 d1.is_modulus <= '1';
532 for j in 0 to 66 loop
534 if d2.valid = '1' then
538 assert d2.valid = '1';
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)));
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);