2 context vunit_lib.vunit_context;
5 use ieee.std_logic_1164.all;
6 use ieee.numeric_std.all;
9 use work.decode_types.all;
11 use work.ppc_fx_insns.all;
14 use osvvm.RandomPkg.all;
17 generic (runner_cfg : string := runner_cfg_default);
20 architecture behave of multiply_tb is
21 signal clk : std_ulogic;
22 constant clk_period : time := 10 ns;
24 constant pipeline_depth : integer := 4;
26 signal m1 : MultiplyInputType := MultiplyInputInit;
27 signal m2 : MultiplyOutputType;
29 function absval(x: std_ulogic_vector) return std_ulogic_vector is
31 if x(x'left) = '1' then
32 return std_ulogic_vector(- signed(x));
39 multiply_0: entity work.multiply
40 generic map (PIPELINE_DEPTH => pipeline_depth)
41 port map (clk => clk, m_in => m1, m_out => m2);
46 wait for clk_period/2;
48 wait for clk_period/2;
52 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
53 variable si: std_ulogic_vector(15 downto 0);
54 variable sign: std_ulogic;
55 variable rnd : RandomPType;
57 rnd.InitSeed(stim_process'path_name);
59 test_runner_setup(runner, runner_cfg);
62 if run("Test interface") then
66 m1.data1 <= x"0000000000001000";
67 m1.data2 <= x"0000000000001111";
70 check_false(?? m2.valid, result("for valid"));
75 check_false(?? m2.valid, result("for valid"));
78 check_false(?? m2.valid, result("for valid"));
81 check_true(?? m2.valid, result("for valid"));
82 check_equal(m2.result, 16#1111000#);
85 check_false(?? m2.valid, result("for valid"));
90 check_false(?? m2.valid, result("for valid"));
94 wait for clk_period * (pipeline_depth-1);
95 check_true(?? m2.valid, result("for valid"));
96 check_equal(m2.result, 16#1111000#);
98 elsif run("Test mulld") then
99 mulld_loop : for i in 0 to 1000 loop
100 ra := rnd.RandSlv(ra'length);
101 rb := rnd.RandSlv(rb'length);
103 behave_rt := ppc_mulld(ra, rb);
105 m1.data1 <= absval(ra);
106 m1.data2 <= absval(rb);
107 sign := ra(63) xor rb(63);
108 m1.not_result <= sign;
109 m1.addend <= (others => sign);
116 wait for clk_period * (pipeline_depth-1);
118 check_true(?? m2.valid, result("for valid"));
119 check_equal(m2.result(63 downto 0), behave_rt, result("for mulld " & to_hstring(behave_rt)));
122 elsif run("Test mulhdu") then
123 mulhdu_loop : for i in 0 to 1000 loop
124 ra := rnd.RandSlv(ra'length);
125 rb := rnd.RandSlv(rb'length);
127 behave_rt := ppc_mulhdu(ra, rb);
131 m1.not_result <= '0';
132 m1.addend <= (others => '0');
139 wait for clk_period * (pipeline_depth-1);
141 check_true(?? m2.valid, result("for valid"));
142 check_equal(m2.result(127 downto 64), behave_rt, result("for mulhdu " & to_hstring(behave_rt)));
145 elsif run("Test mulhd") then
146 mulhd_loop : for i in 0 to 1000 loop
147 ra := rnd.RandSlv(ra'length);
148 rb := rnd.RandSlv(rb'length);
150 behave_rt := ppc_mulhd(ra, rb);
152 m1.data1 <= absval(ra);
153 m1.data2 <= absval(rb);
154 sign := ra(63) xor rb(63);
155 m1.not_result <= sign;
156 m1.addend <= (others => sign);
163 wait for clk_period * (pipeline_depth-1);
165 check_true(?? m2.valid, result("for valid"));
166 check_equal(m2.result(127 downto 64), behave_rt, result("for mulhd " & to_hstring(behave_rt)));
169 elsif run("Test mullw") then
170 mullw_loop : for i in 0 to 1000 loop
171 ra := rnd.RandSlv(ra'length);
172 rb := rnd.RandSlv(rb'length);
174 behave_rt := ppc_mullw(ra, rb);
176 m1.data1 <= (others => '0');
177 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
178 m1.data2 <= (others => '0');
179 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
180 sign := ra(31) xor rb(31);
181 m1.not_result <= sign;
182 m1.addend <= (others => sign);
189 wait for clk_period * (pipeline_depth-1);
191 check_true(?? m2.valid, result("for valid"));
192 check_equal(m2.result(63 downto 0), behave_rt, result("for mullw " & to_hstring(behave_rt)));
195 elsif run("Test mulhw") then
196 mulhw_loop : for i in 0 to 1000 loop
197 ra := rnd.RandSlv(ra'length);
198 rb := rnd.RandSlv(rb'length);
200 behave_rt := ppc_mulhw(ra, rb);
202 m1.data1 <= (others => '0');
203 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
204 m1.data2 <= (others => '0');
205 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
206 sign := ra(31) xor rb(31);
207 m1.not_result <= sign;
208 m1.addend <= (others => sign);
215 wait for clk_period * (pipeline_depth-1);
217 check_true(?? m2.valid, result("for valid"));
218 check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhw " & to_hstring(behave_rt)));
221 elsif run("Test mulhwu") then
222 mulhwu_loop : for i in 0 to 1000 loop
223 ra := rnd.RandSlv(ra'length);
224 rb := rnd.RandSlv(rb'length);
226 behave_rt := ppc_mulhwu(ra, rb);
228 m1.data1 <= (others => '0');
229 m1.data1(31 downto 0) <= ra(31 downto 0);
230 m1.data2 <= (others => '0');
231 m1.data2(31 downto 0) <= rb(31 downto 0);
232 m1.not_result <= '0';
233 m1.addend <= (others => '0');
240 wait for clk_period * (pipeline_depth-1);
242 check_true(?? m2.valid, result("for valid"));
243 check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhwu " & to_hstring(behave_rt)));
246 elsif run("Test mulli") then
247 mulli_loop : for i in 0 to 1000 loop
248 ra := rnd.RandSlv(ra'length);
249 si := rnd.RandSlv(si'length);
251 behave_rt := ppc_mulli(ra, si);
253 m1.data1 <= absval(ra);
254 m1.data2 <= (others => '0');
255 m1.data2(15 downto 0) <= absval(si);
256 sign := ra(63) xor si(15);
257 m1.not_result <= sign;
258 m1.addend <= (others => sign);
265 wait for clk_period * (pipeline_depth-1);
267 check_true(?? m2.valid, result("for valid"));
268 check_equal(m2.result(63 downto 0), behave_rt, result("for mulli " & to_hstring(behave_rt)));
273 test_runner_cleanup(runner);