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 multiply_tb is
15 signal clk : std_ulogic;
16 constant clk_period : time := 10 ns;
18 constant pipeline_depth : integer := 4;
20 signal m1 : MultiplyInputType := MultiplyInputInit;
21 signal m2 : MultiplyOutputType;
23 function absval(x: std_ulogic_vector) return std_ulogic_vector is
25 if x(x'left) = '1' then
26 return std_ulogic_vector(- signed(x));
33 multiply_0: entity work.multiply
34 generic map (PIPELINE_DEPTH => pipeline_depth)
35 port map (clk => clk, m_in => m1, m_out => m2);
40 wait for clk_period/2;
42 wait for clk_period/2;
46 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
47 variable si: std_ulogic_vector(15 downto 0);
48 variable sign: std_ulogic;
53 m1.data1 <= x"0000000000001000";
54 m1.data2 <= x"0000000000001111";
57 assert m2.valid = '0';
62 assert m2.valid = '0';
65 assert m2.valid = '0';
68 assert m2.valid = '1';
69 assert m2.result = x"00000000000000000000000001111000";
72 assert m2.valid = '0';
77 assert m2.valid = '0';
81 wait for clk_period * (pipeline_depth-1);
82 assert m2.valid = '1';
83 assert m2.result = x"00000000000000000000000001111000";
86 mulld_loop : for i in 0 to 1000 loop
87 ra := pseudorand(ra'length);
88 rb := pseudorand(rb'length);
90 behave_rt := ppc_mulld(ra, rb);
92 m1.data1 <= absval(ra);
93 m1.data2 <= absval(rb);
94 sign := ra(63) xor rb(63);
95 m1.not_result <= sign;
96 m1.addend <= (others => sign);
103 wait for clk_period * (pipeline_depth-1);
105 assert m2.valid = '1';
107 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
108 report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
112 mulhdu_loop : for i in 0 to 1000 loop
113 ra := pseudorand(ra'length);
114 rb := pseudorand(rb'length);
116 behave_rt := ppc_mulhdu(ra, rb);
120 m1.not_result <= '0';
121 m1.addend <= (others => '0');
128 wait for clk_period * (pipeline_depth-1);
130 assert m2.valid = '1';
132 assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64))
133 report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64));
137 mulhd_loop : for i in 0 to 1000 loop
138 ra := pseudorand(ra'length);
139 rb := pseudorand(rb'length);
141 behave_rt := ppc_mulhd(ra, rb);
143 m1.data1 <= absval(ra);
144 m1.data2 <= absval(rb);
145 sign := ra(63) xor rb(63);
146 m1.not_result <= sign;
147 m1.addend <= (others => sign);
154 wait for clk_period * (pipeline_depth-1);
156 assert m2.valid = '1';
158 assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64))
159 report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64));
163 mullw_loop : for i in 0 to 1000 loop
164 ra := pseudorand(ra'length);
165 rb := pseudorand(rb'length);
167 behave_rt := ppc_mullw(ra, rb);
169 m1.data1 <= (others => '0');
170 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
171 m1.data2 <= (others => '0');
172 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
173 sign := ra(31) xor rb(31);
174 m1.not_result <= sign;
175 m1.addend <= (others => sign);
182 wait for clk_period * (pipeline_depth-1);
184 assert m2.valid = '1';
186 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
187 report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
191 mulhw_loop : for i in 0 to 1000 loop
192 ra := pseudorand(ra'length);
193 rb := pseudorand(rb'length);
195 behave_rt := ppc_mulhw(ra, rb);
197 m1.data1 <= (others => '0');
198 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
199 m1.data2 <= (others => '0');
200 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
201 sign := ra(31) xor rb(31);
202 m1.not_result <= sign;
203 m1.addend <= (others => sign);
210 wait for clk_period * (pipeline_depth-1);
212 assert m2.valid = '1';
214 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32))
215 report "bad mulhw expected " & to_hstring(behave_rt) & " got " &
216 to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32));
220 mulhwu_loop : for i in 0 to 1000 loop
221 ra := pseudorand(ra'length);
222 rb := pseudorand(rb'length);
224 behave_rt := ppc_mulhwu(ra, rb);
226 m1.data1 <= (others => '0');
227 m1.data1(31 downto 0) <= ra(31 downto 0);
228 m1.data2 <= (others => '0');
229 m1.data2(31 downto 0) <= rb(31 downto 0);
230 m1.not_result <= '0';
231 m1.addend <= (others => '0');
238 wait for clk_period * (pipeline_depth-1);
240 assert m2.valid = '1';
242 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32))
243 report "bad mulhwu expected " & to_hstring(behave_rt) & " got " &
244 to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32));
248 mulli_loop : for i in 0 to 1000 loop
249 ra := pseudorand(ra'length);
250 si := pseudorand(si'length);
252 behave_rt := ppc_mulli(ra, si);
254 m1.data1 <= absval(ra);
255 m1.data2 <= (others => '0');
256 m1.data2(15 downto 0) <= absval(si);
257 sign := ra(63) xor si(15);
258 m1.not_result <= sign;
259 m1.addend <= (others => sign);
266 wait for clk_period * (pipeline_depth-1);
268 assert m2.valid = '1';
270 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
271 report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));