From: Lars Asplund Date: Tue, 8 Jun 2021 20:32:57 +0000 (+0200) Subject: Organized VUnit testbenches into test cases. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0940b8a9d3e77b6f9a6f10d632d674cde0ac47ac;p=microwatt.git Organized VUnit testbenches into test cases. Several of the testbenches have stimuli code divided into sections preceded with a header comment explaining what is being tested. These sections have been made into VUnit test cases. The default behavior of VUnit is to run each test case in a separate simulation which comes with a number of benefits: * A failing test case doesn't prevent other test cases to be executed * Test cases are independent. A test case cannot fail as a side-effect to a problem with another test case * Test execution can be more parallelized and the overall test execution time reduced Signed-off-by: Lars Asplund --- diff --git a/countzero_tb.vhdl b/countzero_tb.vhdl index 671cda3..c51d4a7 100644 --- a/countzero_tb.vhdl +++ b/countzero_tb.vhdl @@ -49,75 +49,77 @@ begin test_runner_setup(runner, runner_cfg); - -- test with input = 0 - report "test zero input"; - rs <= (others => '0'); - is_32bit <= '0'; - count_right <= '0'; - wait for clk_period; - assert result = x"0000000000000040" - report "bad cntlzd 0 = " & to_hstring(result); - count_right <= '1'; - wait for clk_period; - assert result = x"0000000000000040" - report "bad cnttzd 0 = " & to_hstring(result); - is_32bit <= '1'; - count_right <= '0'; - wait for clk_period; - assert result = x"0000000000000020" - report "bad cntlzw 0 = " & to_hstring(result); - count_right <= '1'; - wait for clk_period; - assert result = x"0000000000000020" - report "bad cnttzw 0 = " & to_hstring(result); - - report "test cntlzd/w"; - count_right <= '0'; - for j in 0 to 100 loop - r := rnd.RandSlv(64); - r(63) := '1'; - for i in 0 to 63 loop - rs <= r; + while test_suite loop + if run("Test with input = 0") then + rs <= (others => '0'); is_32bit <= '0'; + count_right <= '0'; wait for clk_period; - assert to_integer(unsigned(result)) = i - report "bad cntlzd " & to_hstring(rs) & " -> " & to_hstring(result); - rs <= r(31 downto 0) & r(63 downto 32); - is_32bit <= '1'; + assert result = x"0000000000000040" + report "bad cntlzd 0 = " & to_hstring(result); + count_right <= '1'; wait for clk_period; - if i < 32 then - assert to_integer(unsigned(result)) = i - report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result); - else - assert to_integer(unsigned(result)) = 32 - report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result); - end if; - r := '0' & r(63 downto 1); - end loop; - end loop; - - report "test cnttzd/w"; - count_right <= '1'; - for j in 0 to 100 loop - r := rnd.RandSlv(64); - r(0) := '1'; - for i in 0 to 63 loop - rs <= r; - is_32bit <= '0'; - wait for clk_period; - assert to_integer(unsigned(result)) = i - report "bad cnttzd " & to_hstring(rs) & " -> " & to_hstring(result); + assert result = x"0000000000000040" + report "bad cnttzd 0 = " & to_hstring(result); is_32bit <= '1'; + count_right <= '0'; + wait for clk_period; + assert result = x"0000000000000020" + report "bad cntlzw 0 = " & to_hstring(result); + count_right <= '1'; wait for clk_period; - if i < 32 then - assert to_integer(unsigned(result)) = i - report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result); - else - assert to_integer(unsigned(result)) = 32 - report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result); - end if; - r := r(62 downto 0) & '0'; - end loop; + assert result = x"0000000000000020" + report "bad cnttzw 0 = " & to_hstring(result); + + elsif run("Test cntlzd/w") then + count_right <= '0'; + for j in 0 to 100 loop + r := rnd.RandSlv(64); + r(63) := '1'; + for i in 0 to 63 loop + rs <= r; + is_32bit <= '0'; + wait for clk_period; + assert to_integer(unsigned(result)) = i + report "bad cntlzd " & to_hstring(rs) & " -> " & to_hstring(result); + rs <= r(31 downto 0) & r(63 downto 32); + is_32bit <= '1'; + wait for clk_period; + if i < 32 then + assert to_integer(unsigned(result)) = i + report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result); + else + assert to_integer(unsigned(result)) = 32 + report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result); + end if; + r := '0' & r(63 downto 1); + end loop; + end loop; + + elsif run("Test cnttzd/w") then + count_right <= '1'; + for j in 0 to 100 loop + r := rnd.RandSlv(64); + r(0) := '1'; + for i in 0 to 63 loop + rs <= r; + is_32bit <= '0'; + wait for clk_period; + assert to_integer(unsigned(result)) = i + report "bad cnttzd " & to_hstring(rs) & " -> " & to_hstring(result); + is_32bit <= '1'; + wait for clk_period; + if i < 32 then + assert to_integer(unsigned(result)) = i + report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result); + else + assert to_integer(unsigned(result)) = 32 + report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result); + end if; + r := r(62 downto 0) & '0'; + end loop; + end loop; + end if; end loop; test_runner_cleanup(runner); diff --git a/divider_tb.vhdl b/divider_tb.vhdl index e41d80f..4fee8f7 100644 --- a/divider_tb.vhdl +++ b/divider_tb.vhdl @@ -49,513 +49,485 @@ begin test_runner_setup(runner, runner_cfg); - rst <= '1'; - wait for clk_period; - rst <= '0'; - - d1.valid <= '1'; - d1.dividend <= x"0000000010001000"; - d1.divisor <= x"0000000000001111"; - d1.is_signed <= '0'; - d1.is_32bit <= '0'; - d1.is_extended <= '0'; - d1.is_modulus <= '0'; - d1.neg_result <= '0'; - - wait for clk_period; - assert d2.valid = '0'; - - d1.valid <= '0'; - - for j in 0 to 66 loop + while test_suite loop + rst <= '1'; wait for clk_period; - if d2.valid = '1' then - exit; - end if; - end loop; + rst <= '0'; - assert d2.valid = '1'; - assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data); + d1.is_signed <= '0'; + d1.neg_result <= '0'; + d1.is_extended <= '0'; + d1.is_32bit <= '0'; + d1.is_modulus <= '0'; + d1.valid <= '0'; - wait for clk_period; - assert d2.valid = '0' report "valid"; + if run("Test interface") then + d1.valid <= '1'; + d1.dividend <= x"0000000010001000"; + d1.divisor <= x"0000000000001111"; - d1.valid <= '1'; + wait for clk_period; + assert d2.valid = '0'; - wait for clk_period; - assert d2.valid = '0' report "valid"; + d1.valid <= '0'; - d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; - end loop; + assert d2.valid = '1'; + assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data); - assert d2.valid = '1'; - assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data); + wait for clk_period; + assert d2.valid = '0' report "valid"; - wait for clk_period; - assert d2.valid = '0'; + d1.valid <= '1'; - -- test divd - report "test divd"; - divd_loop : for dlength in 1 to 8 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + wait for clk_period; + assert d2.valid = '0' report "valid"; - d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); - d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); - d1.is_signed <= '1'; - d1.neg_result <= ra(63) xor rb(63); - d1.valid <= '1'; + d1.valid <= '0'; + for j in 0 to 66 loop wait for clk_period; - - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; - end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" and (ra /= x"8000000000000000" or rb /= x"ffffffffffffffff") then - behave_rt := ppc_divd(ra, rb); + if d2.valid = '1' then + exit; end if; - assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) - report "bad divd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - -- test divdu - report "test divdu"; - divdu_loop : for dlength in 1 to 8 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra; - d1.divisor <= rb; - d1.is_signed <= '0'; - d1.neg_result <= '0'; - d1.valid <= '1'; - - wait for clk_period; - - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + assert d2.valid = '1'; + assert d2.write_reg_data = x"000000000000f001" report "result " & to_hstring(d2.write_reg_data); + + wait for clk_period; + assert d2.valid = '0'; + + elsif run("Test divd") then + divd_loop : for dlength in 1 to 8 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); + d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); + d1.is_signed <= '1'; + d1.neg_result <= ra(63) xor rb(63); + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" and (ra /= x"8000000000000000" or rb /= x"ffffffffffffffff") then + behave_rt := ppc_divd(ra, rb); + end if; + assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) + report "bad divd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - behave_rt := ppc_divdu(ra, rb); - end if; - assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) - report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - - -- test divde - report "test divde"; - divde_loop : for vlength in 1 to 8 loop - for dlength in 1 to vlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); - d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); - d1.is_signed <= '1'; - d1.neg_result <= ra(63) xor rb(63); - d1.is_extended <= '1'; - d1.valid <= '1'; - - wait for clk_period; - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divdu") then + divdu_loop : for dlength in 1 to 8 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra; + d1.divisor <= rb; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + behave_rt := ppc_divdu(ra, rb); + end if; + assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) + report "bad divdu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - d128 := ra & x"0000000000000000"; - q128 := std_ulogic_vector(signed(d128) / signed(rb)); - if q128(127 downto 63) = x"0000000000000000" & '0' or - q128(127 downto 63) = x"ffffffffffffffff" & '1' then - behave_rt := q128(63 downto 0); - end if; - end if; - assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) - report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); end loop; - end loop; - end loop; - - -- test divdeu - report "test divdeu"; - divdeu_loop : for vlength in 1 to 8 loop - for dlength in 1 to vlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra; - d1.divisor <= rb; - d1.is_signed <= '0'; - d1.neg_result <= '0'; - d1.is_extended <= '1'; - d1.valid <= '1'; - - wait for clk_period; - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divde") then + divde_loop : for vlength in 1 to 8 loop + for dlength in 1 to vlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); + d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); + d1.is_signed <= '1'; + d1.neg_result <= ra(63) xor rb(63); + d1.is_extended <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + d128 := ra & x"0000000000000000"; + q128 := std_ulogic_vector(signed(d128) / signed(rb)); + if q128(127 downto 63) = x"0000000000000000" & '0' or + q128(127 downto 63) = x"ffffffffffffffff" & '1' then + behave_rt := q128(63 downto 0); + end if; + end if; + assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) + report "bad divde expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if unsigned(rb) > unsigned(ra) then - d128 := ra & x"0000000000000000"; - q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb)); - behave_rt := q128(63 downto 0); - end if; - assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) - report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); end loop; - end loop; - end loop; - - -- test divw - report "test divw"; - divw_loop : for dlength in 1 to 4 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); - d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); - d1.is_signed <= '1'; - d1.neg_result <= ra(63) xor rb(63); - d1.is_extended <= '0'; - d1.is_32bit <= '1'; - d1.valid <= '1'; - - wait for clk_period; - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divdeu") then + divdeu_loop : for vlength in 1 to 8 loop + for dlength in 1 to vlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra; + d1.divisor <= rb; + d1.is_extended <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if unsigned(rb) > unsigned(ra) then + d128 := ra & x"0000000000000000"; + q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb)); + behave_rt := q128(63 downto 0); + end if; + assert to_hstring(behave_rt) = to_hstring(d2.write_reg_data) + report "bad divdeu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then - behave_rt := ppc_divw(ra, rb); - end if; - assert behave_rt = d2.write_reg_data - report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - - -- test divwu - report "test divwu"; - divwu_loop : for dlength in 1 to 4 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra; - d1.divisor <= rb; - d1.is_signed <= '0'; - d1.neg_result <= '0'; - d1.is_extended <= '0'; - d1.is_32bit <= '1'; - d1.valid <= '1'; - wait for clk_period; - - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divw") then + divw_loop : for dlength in 1 to 4 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); + d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); + d1.is_signed <= '1'; + d1.neg_result <= ra(63) xor rb(63); + d1.is_32bit <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then + behave_rt := ppc_divw(ra, rb); + end if; + assert behave_rt = d2.write_reg_data + report "bad divw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - behave_rt := ppc_divwu(ra, rb); - end if; - assert behave_rt = d2.write_reg_data - report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - -- test divwe - report "test divwe"; - divwe_loop : for vlength in 1 to 4 loop - for dlength in 1 to vlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 32)) & x"00000000"; - rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); - d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); - d1.is_signed <= '1'; - d1.neg_result <= ra(63) xor rb(63); - d1.is_extended <= '0'; - d1.is_32bit <= '1'; - d1.valid <= '1'; - - wait for clk_period; - - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divwu") then + divwu_loop : for dlength in 1 to 4 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra; + d1.divisor <= rb; + d1.is_32bit <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + behave_rt := ppc_divwu(ra, rb); + end if; + assert behave_rt = d2.write_reg_data + report "bad divwu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - q64 := std_ulogic_vector(signed(ra) / signed(rb)); - if q64(63 downto 31) = x"00000000" & '0' or - q64(63 downto 31) = x"ffffffff" & '1' then - behave_rt := x"00000000" & q64(31 downto 0); - end if; - assert behave_rt = d2.write_reg_data - report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); - end if; end loop; - end loop; - end loop; - -- test divweu - report "test divweu"; - divweu_loop : for vlength in 1 to 4 loop - for dlength in 1 to vlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 32)) & x"00000000"; - rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra; - d1.divisor <= rb; - d1.is_signed <= '0'; - d1.neg_result <= '0'; - d1.is_extended <= '0'; - d1.is_32bit <= '1'; - d1.valid <= '1'; - - wait for clk_period; - - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divwe") then + divwe_loop : for vlength in 1 to 4 loop + for dlength in 1 to vlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 32)) & x"00000000"; + rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); + d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); + d1.is_signed <= '1'; + d1.neg_result <= ra(63) xor rb(63); + d1.is_32bit <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + q64 := std_ulogic_vector(signed(ra) / signed(rb)); + if q64(63 downto 31) = x"00000000" & '0' or + q64(63 downto 31) = x"ffffffff" & '1' then + behave_rt := x"00000000" & q64(31 downto 0); + end if; + assert behave_rt = d2.write_reg_data + report "bad divwe expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); + end if; + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then - behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb)); - end if; - assert behave_rt = d2.write_reg_data - report "bad divweu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); end loop; - end loop; - end loop; - - -- test modsd - report "test modsd"; - modsd_loop : for dlength in 1 to 8 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); - d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); - d1.is_signed <= '1'; - d1.neg_result <= ra(63); - d1.is_extended <= '0'; - d1.is_32bit <= '0'; - d1.is_modulus <= '1'; - d1.valid <= '1'; - wait for clk_period; - - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test divweu") then + divweu_loop : for vlength in 1 to 4 loop + for dlength in 1 to vlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 32)) & x"00000000"; + rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra; + d1.divisor <= rb; + d1.is_32bit <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then + behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb)); + end if; + assert behave_rt = d2.write_reg_data + report "bad divweu expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data) & " for ra = " & to_hstring(ra) & " rb = " & to_hstring(rb); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - behave_rt := std_ulogic_vector(signed(ra) rem signed(rb)); - end if; - assert behave_rt = d2.write_reg_data - report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - - -- test modud - report "test modud"; - modud_loop : for dlength in 1 to 8 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra; - d1.divisor <= rb; - d1.is_signed <= '0'; - d1.neg_result <= '0'; - d1.is_extended <= '0'; - d1.is_32bit <= '0'; - d1.is_modulus <= '1'; - d1.valid <= '1'; - - wait for clk_period; - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test modsd") then + modsd_loop : for dlength in 1 to 8 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); + d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); + d1.is_signed <= '1'; + d1.neg_result <= ra(63); + d1.is_modulus <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + behave_rt := std_ulogic_vector(signed(ra) rem signed(rb)); + end if; + assert behave_rt = d2.write_reg_data + report "bad modsd expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb)); - end if; - assert behave_rt = d2.write_reg_data - report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - - -- test modsw - report "test modsw"; - modsw_loop : for dlength in 1 to 4 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); - d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); - d1.is_signed <= '1'; - d1.neg_result <= ra(63); - d1.is_extended <= '0'; - d1.is_32bit <= '1'; - d1.is_modulus <= '1'; - d1.valid <= '1'; - - wait for clk_period; - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test modud") then + modud_loop : for dlength in 1 to 8 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra; + d1.divisor <= rb; + d1.is_modulus <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb)); + end if; + assert behave_rt = d2.write_reg_data + report "bad modud expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; - - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0))); - if rem32(31) = '0' then - behave_rt := x"00000000" & rem32; - else - behave_rt := x"ffffffff" & rem32; - end if; - end if; - assert behave_rt = d2.write_reg_data - report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); end loop; - end loop; - end loop; - - -- test moduw - report "test moduw"; - moduw_loop : for dlength in 1 to 4 loop - for vlength in 1 to dlength loop - for i in 0 to 100 loop - ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); - rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); - - d1.dividend <= ra; - d1.divisor <= rb; - d1.is_signed <= '0'; - d1.neg_result <= '0'; - d1.is_extended <= '0'; - d1.is_32bit <= '1'; - d1.is_modulus <= '1'; - d1.valid <= '1'; - - wait for clk_period; - d1.valid <= '0'; - for j in 0 to 66 loop - wait for clk_period; - if d2.valid = '1' then - exit; - end if; + elsif run("Test modsw") then + modsw_loop : for dlength in 1 to 4 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra)); + d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb)); + d1.is_signed <= '1'; + d1.neg_result <= ra(63); + d1.is_32bit <= '1'; + d1.is_modulus <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0))); + if rem32(31) = '0' then + behave_rt := x"00000000" & rem32; + else + behave_rt := x"ffffffff" & rem32; + end if; + end if; + assert behave_rt = d2.write_reg_data + report "bad modsw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; end loop; - assert d2.valid = '1'; + end loop; - behave_rt := (others => '0'); - if rb /= x"0000000000000000" then - behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0))); - end if; - assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0) - report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + elsif run("Test moduw") then + moduw_loop : for dlength in 1 to 4 loop + for vlength in 1 to dlength loop + for i in 0 to 100 loop + ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64)); + rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64)); + + d1.dividend <= ra; + d1.divisor <= rb; + d1.is_32bit <= '1'; + d1.is_modulus <= '1'; + d1.valid <= '1'; + + wait for clk_period; + + d1.valid <= '0'; + for j in 0 to 66 loop + wait for clk_period; + if d2.valid = '1' then + exit; + end if; + end loop; + assert d2.valid = '1'; + + behave_rt := (others => '0'); + if rb /= x"0000000000000000" then + behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0))); + end if; + assert behave_rt(31 downto 0) = d2.write_reg_data(31 downto 0) + report "bad moduw expected " & to_hstring(behave_rt) & " got " & to_hstring(d2.write_reg_data); + end loop; + end loop; end loop; - end loop; + end if; end loop; test_runner_cleanup(runner); diff --git a/multiply_tb.vhdl b/multiply_tb.vhdl index 7458c33..57a9386 100644 --- a/multiply_tb.vhdl +++ b/multiply_tb.vhdl @@ -58,228 +58,232 @@ begin test_runner_setup(runner, runner_cfg); - wait for clk_period; + while test_suite loop + if run("Test interface") then + wait for clk_period; - m1.valid <= '1'; - m1.data1 <= x"0000000000001000"; - m1.data2 <= x"0000000000001111"; + m1.valid <= '1'; + m1.data1 <= x"0000000000001000"; + m1.data2 <= x"0000000000001111"; - wait for clk_period; - assert m2.valid = '0'; + wait for clk_period; + assert m2.valid = '0'; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period; - assert m2.valid = '0'; + wait for clk_period; + assert m2.valid = '0'; - wait for clk_period; - assert m2.valid = '0'; + wait for clk_period; + assert m2.valid = '0'; - wait for clk_period; - assert m2.valid = '1'; - assert m2.result = x"00000000000000000000000001111000"; + wait for clk_period; + assert m2.valid = '1'; + assert m2.result = x"00000000000000000000000001111000"; - wait for clk_period; - assert m2.valid = '0'; + wait for clk_period; + assert m2.valid = '0'; - m1.valid <= '1'; + m1.valid <= '1'; - wait for clk_period; - assert m2.valid = '0'; + wait for clk_period; + assert m2.valid = '0'; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; - assert m2.result = x"00000000000000000000000001111000"; + wait for clk_period * (pipeline_depth-1); + assert m2.valid = '1'; + assert m2.result = x"00000000000000000000000001111000"; - -- test mulld - mulld_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - rb := rnd.RandSlv(rb'length); + elsif run("Test mulld") then + mulld_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + rb := rnd.RandSlv(rb'length); - behave_rt := ppc_mulld(ra, rb); + behave_rt := ppc_mulld(ra, rb); - m1.data1 <= absval(ra); - m1.data2 <= absval(rb); - sign := ra(63) xor rb(63); - m1.not_result <= sign; - m1.addend <= (others => sign); - m1.valid <= '1'; + m1.data1 <= absval(ra); + m1.data2 <= absval(rb); + sign := ra(63) xor rb(63); + m1.not_result <= sign; + m1.addend <= (others => sign); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0)) - report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0)); - end loop; + assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0)) + report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0)); + end loop; - -- test mulhdu - mulhdu_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - rb := rnd.RandSlv(rb'length); + elsif run("Test mulhdu") then + mulhdu_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + rb := rnd.RandSlv(rb'length); - behave_rt := ppc_mulhdu(ra, rb); + behave_rt := ppc_mulhdu(ra, rb); - m1.data1 <= ra; - m1.data2 <= rb; - m1.not_result <= '0'; - m1.addend <= (others => '0'); - m1.valid <= '1'; + m1.data1 <= ra; + m1.data2 <= rb; + m1.not_result <= '0'; + m1.addend <= (others => '0'); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64)) - report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64)); - end loop; + assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64)) + report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64)); + end loop; - -- test mulhd - mulhd_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - rb := rnd.RandSlv(rb'length); + elsif run("Test mulhd") then + mulhd_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + rb := rnd.RandSlv(rb'length); - behave_rt := ppc_mulhd(ra, rb); + behave_rt := ppc_mulhd(ra, rb); - m1.data1 <= absval(ra); - m1.data2 <= absval(rb); - sign := ra(63) xor rb(63); - m1.not_result <= sign; - m1.addend <= (others => sign); - m1.valid <= '1'; + m1.data1 <= absval(ra); + m1.data2 <= absval(rb); + sign := ra(63) xor rb(63); + m1.not_result <= sign; + m1.addend <= (others => sign); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64)) - report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64)); - end loop; + assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64)) + report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64)); + end loop; - -- test mullw - mullw_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - rb := rnd.RandSlv(rb'length); + elsif run("Test mullw") then + mullw_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + rb := rnd.RandSlv(rb'length); - behave_rt := ppc_mullw(ra, rb); + behave_rt := ppc_mullw(ra, rb); - m1.data1 <= (others => '0'); - m1.data1(31 downto 0) <= absval(ra(31 downto 0)); - m1.data2 <= (others => '0'); - m1.data2(31 downto 0) <= absval(rb(31 downto 0)); - sign := ra(31) xor rb(31); - m1.not_result <= sign; - m1.addend <= (others => sign); - m1.valid <= '1'; + m1.data1 <= (others => '0'); + m1.data1(31 downto 0) <= absval(ra(31 downto 0)); + m1.data2 <= (others => '0'); + m1.data2(31 downto 0) <= absval(rb(31 downto 0)); + sign := ra(31) xor rb(31); + m1.not_result <= sign; + m1.addend <= (others => sign); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0)) - report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0)); - end loop; + assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0)) + report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0)); + end loop; - -- test mulhw - mulhw_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - rb := rnd.RandSlv(rb'length); + elsif run("Test mulhw") then + mulhw_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + rb := rnd.RandSlv(rb'length); - behave_rt := ppc_mulhw(ra, rb); + behave_rt := ppc_mulhw(ra, rb); - m1.data1 <= (others => '0'); - m1.data1(31 downto 0) <= absval(ra(31 downto 0)); - m1.data2 <= (others => '0'); - m1.data2(31 downto 0) <= absval(rb(31 downto 0)); - sign := ra(31) xor rb(31); - m1.not_result <= sign; - m1.addend <= (others => sign); - m1.valid <= '1'; + m1.data1 <= (others => '0'); + m1.data1(31 downto 0) <= absval(ra(31 downto 0)); + m1.data2 <= (others => '0'); + m1.data2(31 downto 0) <= absval(rb(31 downto 0)); + sign := ra(31) xor rb(31); + m1.not_result <= sign; + m1.addend <= (others => sign); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)) - report "bad mulhw expected " & to_hstring(behave_rt) & " got " & - to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)); - end loop; + assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)) + report "bad mulhw expected " & to_hstring(behave_rt) & " got " & + to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)); + end loop; - -- test mulhwu - mulhwu_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - rb := rnd.RandSlv(rb'length); + elsif run("Test mulhwu") then + mulhwu_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + rb := rnd.RandSlv(rb'length); - behave_rt := ppc_mulhwu(ra, rb); + behave_rt := ppc_mulhwu(ra, rb); - m1.data1 <= (others => '0'); - m1.data1(31 downto 0) <= ra(31 downto 0); - m1.data2 <= (others => '0'); - m1.data2(31 downto 0) <= rb(31 downto 0); - m1.not_result <= '0'; - m1.addend <= (others => '0'); - m1.valid <= '1'; + m1.data1 <= (others => '0'); + m1.data1(31 downto 0) <= ra(31 downto 0); + m1.data2 <= (others => '0'); + m1.data2(31 downto 0) <= rb(31 downto 0); + m1.not_result <= '0'; + m1.addend <= (others => '0'); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)) - report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & - to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)); - end loop; + assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)) + report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & + to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32)); + end loop; - -- test mulli - mulli_loop : for i in 0 to 1000 loop - ra := rnd.RandSlv(ra'length); - si := rnd.RandSlv(si'length); + elsif run("Test mulli") then + mulli_loop : for i in 0 to 1000 loop + ra := rnd.RandSlv(ra'length); + si := rnd.RandSlv(si'length); - behave_rt := ppc_mulli(ra, si); + behave_rt := ppc_mulli(ra, si); - m1.data1 <= absval(ra); - m1.data2 <= (others => '0'); - m1.data2(15 downto 0) <= absval(si); - sign := ra(63) xor si(15); - m1.not_result <= sign; - m1.addend <= (others => sign); - m1.valid <= '1'; + m1.data1 <= absval(ra); + m1.data2 <= (others => '0'); + m1.data2(15 downto 0) <= absval(si); + sign := ra(63) xor si(15); + m1.not_result <= sign; + m1.addend <= (others => sign); + m1.valid <= '1'; - wait for clk_period; + wait for clk_period; - m1.valid <= '0'; + m1.valid <= '0'; - wait for clk_period * (pipeline_depth-1); + wait for clk_period * (pipeline_depth-1); - assert m2.valid = '1'; + assert m2.valid = '1'; - assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0)) - report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0)); + assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0)) + report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0)); + end loop; + end if; end loop; test_runner_cleanup(runner); diff --git a/rotator_tb.vhdl b/rotator_tb.vhdl index 2849ccf..781027f 100644 --- a/rotator_tb.vhdl +++ b/rotator_tb.vhdl @@ -53,255 +53,244 @@ begin test_runner_setup(runner, runner_cfg); - -- rlwinm, rlwnm - report "test rlw[i]nm"; - ra <= (others => '0'); - is_32bit <= '1'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '1'; - clear_right <= '1'; - extsw <= '0'; - rlwnm_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; - wait for clk_period; - behave_ra := ppc_rlwinm(rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn)); - assert behave_ra = result - report "bad rlwnm expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + while test_suite loop + if run("Test rlw[i]nm") then + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + extsw <= '0'; + rlwnm_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; + wait for clk_period; + behave_ra := ppc_rlwinm(rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn)); + assert behave_ra = result + report "bad rlwnm expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- rlwimi - report "test rlwimi"; - is_32bit <= '1'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '1'; - clear_right <= '1'; - rlwimi_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - ra <= rnd.RandSlv(64); - shift <= "00" & rnd.RandSlv(5); - insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; - wait for clk_period; - behave_ra := ppc_rlwimi(ra, rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn)); - assert behave_ra = result - report "bad rlwimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test rlwimi") then + is_32bit <= '1'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rlwimi_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + ra <= rnd.RandSlv(64); + shift <= "00" & rnd.RandSlv(5); + insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; + wait for clk_period; + behave_ra := ppc_rlwimi(ra, rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn)); + assert behave_ra = result + report "bad rlwimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- rldicl, rldcl - report "test rld[i]cl"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '1'; - clear_right <= '0'; - rldicl_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; - wait for clk_period; - behave_ra := ppc_rldicl(rs, shift(5 downto 0), insn_mb(insn)); - assert behave_ra = result - report "bad rldicl expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test rld[i]cl") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '0'; + rldicl_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldicl(rs, shift(5 downto 0), insn_mb(insn)); + assert behave_ra = result + report "bad rldicl expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- rldicr, rldcr - report "test rld[i]cr"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '0'; - clear_right <= '1'; - rldicr_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; - wait for clk_period; - behave_ra := ppc_rldicr(rs, shift(5 downto 0), insn_me(insn)); - --report "rs = " & to_hstring(rs); - --report "ra = " & to_hstring(ra); - --report "shift = " & to_hstring(shift); - --report "insn me = " & to_hstring(insn_me(insn)); - --report "result = " & to_hstring(result); - assert behave_ra = result - report "bad rldicr expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test rld[i]cr") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '1'; + rldicr_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldicr(rs, shift(5 downto 0), insn_me(insn)); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "insn me = " & to_hstring(insn_me(insn)); + --report "result = " & to_hstring(result); + assert behave_ra = result + report "bad rldicr expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- rldic - report "test rldic"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '1'; - clear_right <= '1'; - rldic_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= '0' & rnd.RandSlv(6); - insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; - wait for clk_period; - behave_ra := ppc_rldic(rs, shift(5 downto 0), insn_mb(insn)); - assert behave_ra = result - report "bad rldic expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test rldic") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rldic_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= '0' & rnd.RandSlv(6); + insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldic(rs, shift(5 downto 0), insn_mb(insn)); + assert behave_ra = result + report "bad rldic expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- rldimi - report "test rldimi"; - is_32bit <= '0'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '1'; - clear_right <= '1'; - rldimi_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - ra <= rnd.RandSlv(64); - shift <= '0' & rnd.RandSlv(6); - insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; - wait for clk_period; - behave_ra := ppc_rldimi(ra, rs, shift(5 downto 0), insn_mb(insn)); - assert behave_ra = result - report "bad rldimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test rldimi") then + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rldimi_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + ra <= rnd.RandSlv(64); + shift <= '0' & rnd.RandSlv(6); + insn <= x"00000" & '0' & rnd.RandSlv(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldimi(ra, rs, shift(5 downto 0), insn_mb(insn)); + assert behave_ra = result + report "bad rldimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- slw - report "test slw"; - ra <= (others => '0'); - is_32bit <= '1'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '0'; - clear_right <= '0'; - slw_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - wait for clk_period; - behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); - assert behave_ra = result - report "bad slw expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test slw") then + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + slw_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + wait for clk_period; + behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad slw expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- sld - report "test sld"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '0'; - clear_right <= '0'; - sld_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - wait for clk_period; - behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64))); - assert behave_ra = result - report "bad sld expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test sld") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + sld_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + wait for clk_period; + behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad sld expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- srw - report "test srw"; - ra <= (others => '0'); - is_32bit <= '1'; - right_shift <= '1'; - arith <= '0'; - clear_left <= '0'; - clear_right <= '0'; - srw_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - wait for clk_period; - behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); - assert behave_ra = result - report "bad srw expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test srw") then + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '1'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + srw_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + wait for clk_period; + behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad srw expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- srd - report "test srd"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '1'; - arith <= '0'; - clear_left <= '0'; - clear_right <= '0'; - srd_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - wait for clk_period; - behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64))); - assert behave_ra = result - report "bad srd expected " & to_hstring(behave_ra) & " got " & to_hstring(result); - end loop; + elsif run("Test srd") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '1'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + srd_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + wait for clk_period; + behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad srd expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; - -- sraw[i] - report "test sraw[i]"; - ra <= (others => '0'); - is_32bit <= '1'; - right_shift <= '1'; - arith <= '1'; - clear_left <= '0'; - clear_right <= '0'; - sraw_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= '0' & rnd.RandSlv(6); - wait for clk_period; - behave_ca_ra := ppc_sraw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); - --report "rs = " & to_hstring(rs); - --report "ra = " & to_hstring(ra); - --report "shift = " & to_hstring(shift); - --report "result = " & to_hstring(carry_out & result); - assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out - report "bad sraw expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result); - end loop; + elsif run("Test sraw[i]") then + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '1'; + arith <= '1'; + clear_left <= '0'; + clear_right <= '0'; + sraw_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= '0' & rnd.RandSlv(6); + wait for clk_period; + behave_ca_ra := ppc_sraw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "result = " & to_hstring(carry_out & result); + assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out + report "bad sraw expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result); + end loop; - -- srad[i] - report "test srad[i]"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '1'; - arith <= '1'; - clear_left <= '0'; - clear_right <= '0'; - srad_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= rnd.RandSlv(7); - wait for clk_period; - behave_ca_ra := ppc_srad(rs, std_ulogic_vector(resize(unsigned(shift), 64))); - --report "rs = " & to_hstring(rs); - --report "ra = " & to_hstring(ra); - --report "shift = " & to_hstring(shift); - --report "result = " & to_hstring(carry_out & result); - assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out - report "bad srad expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result); - end loop; + elsif run("Test srad[i]") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '1'; + arith <= '1'; + clear_left <= '0'; + clear_right <= '0'; + srad_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= rnd.RandSlv(7); + wait for clk_period; + behave_ca_ra := ppc_srad(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "result = " & to_hstring(carry_out & result); + assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out + report "bad srad expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result); + end loop; - -- extswsli - report "test extswsli"; - ra <= (others => '0'); - is_32bit <= '0'; - right_shift <= '0'; - arith <= '0'; - clear_left <= '0'; - clear_right <= '0'; - extsw <= '1'; - extswsli_loop : for i in 0 to 1000 loop - rs <= rnd.RandSlv(64); - shift <= '0' & rnd.RandSlv(6); - wait for clk_period; - behave_ra := rs; - behave_ra(63 downto 32) := (others => rs(31)); - behave_ra := std_ulogic_vector(shift_left(unsigned(behave_ra), - to_integer(unsigned(shift)))); - --report "rs = " & to_hstring(rs); - --report "ra = " & to_hstring(ra); - --report "shift = " & to_hstring(shift); - --report "result = " & to_hstring(carry_out & result); - assert behave_ra = result - report "bad extswsli expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + elsif run("Test extswsli") then + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + extsw <= '1'; + extswsli_loop : for i in 0 to 1000 loop + rs <= rnd.RandSlv(64); + shift <= '0' & rnd.RandSlv(6); + wait for clk_period; + behave_ra := rs; + behave_ra(63 downto 32) := (others => rs(31)); + behave_ra := std_ulogic_vector(shift_left(unsigned(behave_ra), + to_integer(unsigned(shift)))); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "result = " & to_hstring(carry_out & result); + assert behave_ra = result + report "bad extswsli expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + end if; end loop; - test_runner_cleanup(runner); end process; end behave;