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);
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);
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 66 loop
118 if d2.valid = '1' then
122 assert d2.valid = '1';
124 behave_rt := (others => '0');
125 if rb /= x"0000000000000000" and (ra /= x"8000000000000000" or rb /= x"ffffffffffffffff") then
126 behave_rt := ppc_divd(ra, rb);
128 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
129 report "bad divd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
136 divdu_loop : for dlength in 1 to 8 loop
137 for vlength in 1 to dlength loop
138 for i in 0 to 100 loop
139 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
140 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
150 for j in 0 to 66 loop
152 if d2.valid = '1' then
156 assert d2.valid = '1';
158 behave_rt := (others => '0');
159 if rb /= x"0000000000000000" then
160 behave_rt := ppc_divdu(ra, rb);
162 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
163 report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
170 divde_loop : for vlength in 1 to 8 loop
171 for dlength in 1 to vlength loop
172 for i in 0 to 100 loop
173 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
174 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
179 d1.is_extended <= '1';
185 for j in 0 to 66 loop
187 if d2.valid = '1' then
191 assert d2.valid = '1';
193 behave_rt := (others => '0');
194 if rb /= x"0000000000000000" then
195 d128 := ra & x"0000000000000000";
196 q128 := std_ulogic_vector(signed(d128) / signed(rb));
197 if q128(127 downto 63) = x"0000000000000000" & '0' or
198 q128(127 downto 63) = x"ffffffffffffffff" & '1' then
199 behave_rt := q128(63 downto 0);
202 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
203 report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
209 report "test divdeu";
210 divdeu_loop : for vlength in 1 to 8 loop
211 for dlength in 1 to vlength loop
212 for i in 0 to 100 loop
213 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
214 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
219 d1.is_extended <= '1';
225 for j in 0 to 66 loop
227 if d2.valid = '1' then
231 assert d2.valid = '1';
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 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
240 report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
247 divw_loop : for dlength in 1 to 4 loop
248 for vlength in 1 to dlength loop
249 for i in 0 to 100 loop
250 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
251 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
256 d1.is_extended <= '0';
263 for j in 0 to 66 loop
265 if d2.valid = '1' then
269 assert d2.valid = '1';
271 behave_rt := (others => '0');
272 if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then
273 behave_rt := ppc_divw(ra, rb);
275 assert behave_rt = d2.write_reg_data
276 report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
283 divwu_loop : for dlength in 1 to 4 loop
284 for vlength in 1 to dlength loop
285 for i in 0 to 100 loop
286 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
287 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
292 d1.is_extended <= '0';
299 for j in 0 to 66 loop
301 if d2.valid = '1' then
305 assert d2.valid = '1';
307 behave_rt := (others => '0');
308 if rb /= x"0000000000000000" then
309 behave_rt := ppc_divwu(ra, rb);
311 assert behave_rt = d2.write_reg_data
312 report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
319 divwe_loop : for vlength in 1 to 4 loop
320 for dlength in 1 to vlength loop
321 for i in 0 to 100 loop
322 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 32)) & x"00000000";
323 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
328 d1.is_extended <= '0';
335 for j in 0 to 66 loop
337 if d2.valid = '1' then
341 assert d2.valid = '1';
343 behave_rt := (others => '0');
344 if rb /= x"0000000000000000" then
345 q64 := std_ulogic_vector(signed(ra) / signed(rb));
346 if q64(63 downto 31) = x"00000000" & '0' or
347 q64(63 downto 31) = x"ffffffff" & '1' then
348 behave_rt := x"00000000" & q64(31 downto 0);
350 assert behave_rt = d2.write_reg_data
351 report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
358 report "test divweu";
359 divweu_loop : for vlength in 1 to 4 loop
360 for dlength in 1 to vlength loop
361 for i in 0 to 100 loop
362 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 32)) & x"00000000";
363 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
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));
404 d1.is_extended <= '0';
406 d1.is_modulus <= '1';
412 for j in 0 to 66 loop
414 if d2.valid = '1' then
418 assert d2.valid = '1';
420 behave_rt := (others => '0');
421 if rb /= x"0000000000000000" then
422 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
424 assert behave_rt = d2.write_reg_data
425 report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
432 modud_loop : for dlength in 1 to 8 loop
433 for vlength in 1 to dlength loop
434 for i in 0 to 100 loop
435 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
436 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
441 d1.is_extended <= '0';
443 d1.is_modulus <= '1';
449 for j in 0 to 66 loop
451 if d2.valid = '1' then
455 assert d2.valid = '1';
457 behave_rt := (others => '0');
458 if rb /= x"0000000000000000" then
459 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
461 assert behave_rt = d2.write_reg_data
462 report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
469 modsw_loop : for dlength in 1 to 4 loop
470 for vlength in 1 to dlength loop
471 for i in 0 to 100 loop
472 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
473 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
478 d1.is_extended <= '0';
480 d1.is_modulus <= '1';
486 for j in 0 to 66 loop
488 if d2.valid = '1' then
492 assert d2.valid = '1';
494 behave_rt := (others => '0');
495 if rb /= x"0000000000000000" then
496 rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0)));
497 if rem32(31) = '0' then
498 behave_rt := x"00000000" & rem32;
500 behave_rt := x"ffffffff" & rem32;
503 assert behave_rt = d2.write_reg_data
504 report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
511 moduw_loop : for dlength in 1 to 4 loop
512 for vlength in 1 to dlength loop
513 for i in 0 to 100 loop
514 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
515 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
520 d1.is_extended <= '0';
522 d1.is_modulus <= '1';
528 for j in 0 to 66 loop
530 if d2.valid = '1' then
534 assert d2.valid = '1';
536 behave_rt := (others => '0');
537 if rb /= x"0000000000000000" then
538 behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0)));
540 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
541 report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
546 assert false report "end of test" severity failure;