You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
8.8 KiB
268 lines
8.8 KiB
library vunit_lib; |
|
context vunit_lib.vunit_context; |
|
|
|
library ieee; |
|
use ieee.std_logic_1164.all; |
|
use ieee.numeric_std.all; |
|
|
|
library work; |
|
use work.decode_types.all; |
|
use work.common.all; |
|
use work.ppc_fx_insns.all; |
|
|
|
library osvvm; |
|
use osvvm.RandomPkg.all; |
|
|
|
entity multiply_tb is |
|
generic (runner_cfg : string := runner_cfg_default); |
|
end multiply_tb; |
|
|
|
architecture behave of multiply_tb is |
|
signal clk : std_ulogic; |
|
constant clk_period : time := 10 ns; |
|
|
|
constant pipeline_depth : integer := 4; |
|
|
|
signal m1 : MultiplyInputType := MultiplyInputInit; |
|
signal m2 : MultiplyOutputType; |
|
|
|
begin |
|
multiply_0: entity work.multiply |
|
generic map (PIPELINE_DEPTH => pipeline_depth) |
|
port map (clk => clk, m_in => m1, m_out => m2); |
|
|
|
clk_process: process |
|
begin |
|
clk <= '0'; |
|
wait for clk_period/2; |
|
clk <= '1'; |
|
wait for clk_period/2; |
|
end process; |
|
|
|
stim_process: process |
|
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0); |
|
variable si: std_ulogic_vector(15 downto 0); |
|
variable rnd : RandomPType; |
|
begin |
|
rnd.InitSeed(stim_process'path_name); |
|
|
|
test_runner_setup(runner, runner_cfg); |
|
|
|
while test_suite loop |
|
if run("Test interface") then |
|
wait for clk_period; |
|
|
|
m1.valid <= '1'; |
|
m1.data1 <= x"0000000000001000"; |
|
m1.data2 <= x"0000000000001111"; |
|
|
|
wait for clk_period; |
|
check_false(?? m2.valid, result("for valid")); |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period; |
|
check_false(?? m2.valid, result("for valid")); |
|
|
|
wait for clk_period; |
|
check_false(?? m2.valid, result("for valid")); |
|
|
|
wait for clk_period; |
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result, 16#1111000#); |
|
|
|
wait for clk_period; |
|
check_false(?? m2.valid, result("for valid")); |
|
|
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
check_false(?? m2.valid, result("for valid")); |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result, 16#1111000#); |
|
|
|
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); |
|
|
|
m1.data1 <= ra; |
|
m1.data2 <= rb; |
|
m1.is_signed <= '1'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(63 downto 0), behave_rt, result("for mulld " & to_hstring(behave_rt))); |
|
end loop; |
|
|
|
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); |
|
|
|
m1.data1 <= ra; |
|
m1.data2 <= rb; |
|
m1.is_signed <= '0'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(127 downto 64), behave_rt, result("for mulhdu " & to_hstring(behave_rt))); |
|
end loop; |
|
|
|
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); |
|
|
|
m1.data1 <= ra; |
|
m1.data2 <= rb; |
|
m1.is_signed <= '1'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(127 downto 64), behave_rt, result("for mulhd " & to_hstring(behave_rt))); |
|
end loop; |
|
|
|
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); |
|
|
|
m1.data1 <= (others => ra(31)); |
|
m1.data1(31 downto 0) <= ra(31 downto 0); |
|
m1.data2 <= (others => rb(31)); |
|
m1.data2(31 downto 0) <= rb(31 downto 0); |
|
m1.is_signed <= '1'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(63 downto 0), behave_rt, result("for mullw " & to_hstring(behave_rt))); |
|
end loop; |
|
|
|
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); |
|
|
|
m1.data1 <= (others => ra(31)); |
|
m1.data1(31 downto 0) <= ra(31 downto 0); |
|
m1.data2 <= (others => rb(31)); |
|
m1.data2(31 downto 0) <= rb(31 downto 0); |
|
m1.is_signed <= '1'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhw " & to_hstring(behave_rt))); |
|
end loop; |
|
|
|
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); |
|
|
|
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.is_signed <= '0'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhwu " & to_hstring(behave_rt))); |
|
end loop; |
|
|
|
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); |
|
|
|
m1.data1 <= ra; |
|
m1.data2 <= (others => si(15)); |
|
m1.data2(15 downto 0) <= si; |
|
m1.is_signed <= '1'; |
|
m1.subtract <= '0'; |
|
m1.addend <= (others => '0'); |
|
m1.valid <= '1'; |
|
|
|
wait for clk_period; |
|
|
|
m1.valid <= '0'; |
|
|
|
wait for clk_period * (pipeline_depth-1); |
|
|
|
check_true(?? m2.valid, result("for valid")); |
|
check_equal(m2.result(63 downto 0), behave_rt, result("for mulli " & to_hstring(behave_rt))); |
|
end loop; |
|
end if; |
|
end loop; |
|
|
|
test_runner_cleanup(runner); |
|
wait; |
|
end process; |
|
end behave;
|
|
|