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.write_reg <= "10001";
47 d1.dividend <= x"0000000010001000";
48 d1.divisor <= x"0000000000001111";
51 d1.is_extended <= '0';
57 assert d2.valid = '0';
63 if d2.valid = '1' then
68 assert d2.valid = '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_nr = "10001";
93 assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data);
97 assert d2.valid = '0';
101 divd_loop : for dlength in 1 to 8 loop
102 for vlength in 1 to dlength loop
103 for i in 0 to 100 loop
104 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
105 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
107 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
108 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
110 d1.neg_result <= ra(63) xor rb(63);
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));
145 d1.neg_result <= '0';
151 for j in 0 to 66 loop
153 if d2.valid = '1' then
157 assert d2.valid = '1';
159 behave_rt := (others => '0');
160 if rb /= x"0000000000000000" then
161 behave_rt := ppc_divdu(ra, rb);
163 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
164 report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
171 divde_loop : for vlength in 1 to 8 loop
172 for dlength in 1 to vlength loop
173 for i in 0 to 100 loop
174 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
175 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
177 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
178 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
180 d1.neg_result <= ra(63) xor rb(63);
181 d1.is_extended <= '1';
187 for j in 0 to 66 loop
189 if d2.valid = '1' then
193 assert d2.valid = '1';
195 behave_rt := (others => '0');
196 if rb /= x"0000000000000000" then
197 d128 := ra & x"0000000000000000";
198 q128 := std_ulogic_vector(signed(d128) / signed(rb));
199 if q128(127 downto 63) = x"0000000000000000" & '0' or
200 q128(127 downto 63) = x"ffffffffffffffff" & '1' then
201 behave_rt := q128(63 downto 0);
204 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
205 report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
211 report "test divdeu";
212 divdeu_loop : for vlength in 1 to 8 loop
213 for dlength in 1 to vlength loop
214 for i in 0 to 100 loop
215 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
216 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
221 d1.neg_result <= '0';
222 d1.is_extended <= '1';
228 for j in 0 to 66 loop
230 if d2.valid = '1' then
234 assert d2.valid = '1';
236 behave_rt := (others => '0');
237 if unsigned(rb) > unsigned(ra) then
238 d128 := ra & x"0000000000000000";
239 q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb));
240 behave_rt := q128(63 downto 0);
242 assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data)
243 report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
250 divw_loop : for dlength in 1 to 4 loop
251 for vlength in 1 to dlength loop
252 for i in 0 to 100 loop
253 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
254 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
256 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
257 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
259 d1.neg_result <= ra(63) xor rb(63);
260 d1.is_extended <= '0';
267 for j in 0 to 66 loop
269 if d2.valid = '1' then
273 assert d2.valid = '1';
275 behave_rt := (others => '0');
276 if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then
277 behave_rt := ppc_divw(ra, rb);
279 assert behave_rt = d2.write_reg_data
280 report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
287 divwu_loop : for dlength in 1 to 4 loop
288 for vlength in 1 to dlength loop
289 for i in 0 to 100 loop
290 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
291 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
296 d1.neg_result <= '0';
297 d1.is_extended <= '0';
304 for j in 0 to 66 loop
306 if d2.valid = '1' then
310 assert d2.valid = '1';
312 behave_rt := (others => '0');
313 if rb /= x"0000000000000000" then
314 behave_rt := ppc_divwu(ra, rb);
316 assert behave_rt = d2.write_reg_data
317 report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
324 divwe_loop : for vlength in 1 to 4 loop
325 for dlength in 1 to vlength loop
326 for i in 0 to 100 loop
327 ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 32)) & x"00000000";
328 rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
330 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
331 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
333 d1.neg_result <= ra(63) xor rb(63);
334 d1.is_extended <= '0';
341 for j in 0 to 66 loop
343 if d2.valid = '1' then
347 assert d2.valid = '1';
349 behave_rt := (others => '0');
350 if rb /= x"0000000000000000" then
351 q64 := std_ulogic_vector(signed(ra) / signed(rb));
352 if q64(63 downto 31) = x"00000000" & '0' or
353 q64(63 downto 31) = x"ffffffff" & '1' then
354 behave_rt := x"00000000" & q64(31 downto 0);
356 assert behave_rt = d2.write_reg_data
357 report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
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.neg_result <= '0';
375 d1.is_extended <= '0';
382 for j in 0 to 66 loop
384 if d2.valid = '1' then
388 assert d2.valid = '1';
390 behave_rt := (others => '0');
391 if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then
392 behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb));
394 assert behave_rt = d2.write_reg_data
395 report "bad divweu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb);
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));
408 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
409 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
411 d1.neg_result <= ra(63);
412 d1.is_extended <= '0';
414 d1.is_modulus <= '1';
420 for j in 0 to 66 loop
422 if d2.valid = '1' then
426 assert d2.valid = '1';
428 behave_rt := (others => '0');
429 if rb /= x"0000000000000000" then
430 behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
432 assert behave_rt = d2.write_reg_data
433 report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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.neg_result <= '0';
450 d1.is_extended <= '0';
452 d1.is_modulus <= '1';
458 for j in 0 to 66 loop
460 if d2.valid = '1' then
464 assert d2.valid = '1';
466 behave_rt := (others => '0');
467 if rb /= x"0000000000000000" then
468 behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
470 assert behave_rt = d2.write_reg_data
471 report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
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));
484 d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
485 d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
487 d1.neg_result <= ra(63);
488 d1.is_extended <= '0';
490 d1.is_modulus <= '1';
496 for j in 0 to 66 loop
498 if d2.valid = '1' then
502 assert d2.valid = '1';
504 behave_rt := (others => '0');
505 if rb /= x"0000000000000000" then
506 rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0)));
507 if rem32(31) = '0' then
508 behave_rt := x"00000000" & rem32;
510 behave_rt := x"ffffffff" & rem32;
513 assert behave_rt = d2.write_reg_data
514 report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
521 moduw_loop : for dlength in 1 to 4 loop
522 for vlength in 1 to dlength loop
523 for i in 0 to 100 loop
524 ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
525 rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
530 d1.neg_result <= '0';
531 d1.is_extended <= '0';
533 d1.is_modulus <= '1';
539 for j in 0 to 66 loop
541 if d2.valid = '1' then
545 assert d2.valid = '1';
547 behave_rt := (others => '0');
548 if rb /= x"0000000000000000" then
549 behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0)));
551 assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0)
552 report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data);
557 assert false report "end of test" severity failure;