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 : Decode2ToMultiplyType;
21 signal m2 : MultiplyToWritebackType;
23 multiply_0: entity work.multiply
24 generic map (PIPELINE_DEPTH => pipeline_depth)
25 port map (clk => clk, m_in => m1, m_out => m2);
30 wait for clk_period/2;
32 wait for clk_period/2;
36 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
37 variable si: std_ulogic_vector(15 downto 0);
42 m1.insn_type <= OP_MUL_L64;
43 m1.write_reg <= "10001";
44 m1.data1 <= '0' & x"0000000000001000";
45 m1.data2 <= '0' & x"0000000000001111";
49 assert m2.valid = '0';
54 assert m2.valid = '0';
57 assert m2.valid = '0';
60 assert m2.valid = '1';
61 assert m2.write_reg_enable = '1';
62 assert m2.write_reg_nr = "10001";
63 assert m2.write_reg_data = x"0000000001111000";
64 assert m2.write_cr_enable = '0';
67 assert m2.valid = '0';
73 assert m2.valid = '0';
77 wait for clk_period * (pipeline_depth-1);
78 assert m2.valid = '1';
79 assert m2.write_reg_enable = '1';
80 assert m2.write_reg_nr = "10001";
81 assert m2.write_reg_data = x"0000000001111000";
82 assert m2.write_cr_enable = '1';
83 assert m2.write_cr_data = x"40000000";
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);
95 m1.insn_type <= OP_MUL_L64;
101 wait for clk_period * (pipeline_depth-1);
103 assert m2.valid = '1';
105 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
106 report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
110 mulhdu_loop : for i in 0 to 1000 loop
111 ra := pseudorand(ra'length);
112 rb := pseudorand(rb'length);
114 behave_rt := ppc_mulhdu(ra, rb);
116 m1.data1 <= '0' & ra;
117 m1.data2 <= '0' & rb;
119 m1.insn_type <= OP_MUL_H64;
125 wait for clk_period * (pipeline_depth-1);
127 assert m2.valid = '1';
129 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
130 report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
134 mulhd_loop : for i in 0 to 1000 loop
135 ra := pseudorand(ra'length);
136 rb := pseudorand(rb'length);
138 behave_rt := ppc_mulhd(ra, rb);
140 m1.data1 <= ra(63) & ra;
141 m1.data2 <= rb(63) & rb;
143 m1.insn_type <= OP_MUL_H64;
149 wait for clk_period * (pipeline_depth-1);
151 assert m2.valid = '1';
153 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
154 report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
158 mullw_loop : for i in 0 to 1000 loop
159 ra := pseudorand(ra'length);
160 rb := pseudorand(rb'length);
162 behave_rt := ppc_mullw(ra, rb);
164 m1.data1 <= (others => ra(31));
165 m1.data1(31 downto 0) <= ra(31 downto 0);
166 m1.data2 <= (others => rb(31));
167 m1.data2(31 downto 0) <= rb(31 downto 0);
169 m1.insn_type <= OP_MUL_L64;
175 wait for clk_period * (pipeline_depth-1);
177 assert m2.valid = '1';
179 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
180 report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
184 mulhw_loop : for i in 0 to 1000 loop
185 ra := pseudorand(ra'length);
186 rb := pseudorand(rb'length);
188 behave_rt := ppc_mulhw(ra, rb);
190 m1.data1 <= (others => ra(31));
191 m1.data1(31 downto 0) <= ra(31 downto 0);
192 m1.data2 <= (others => rb(31));
193 m1.data2(31 downto 0) <= rb(31 downto 0);
195 m1.insn_type <= OP_MUL_H32;
201 wait for clk_period * (pipeline_depth-1);
203 assert m2.valid = '1';
205 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
206 report "bad mulhw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
210 mulhwu_loop : for i in 0 to 1000 loop
211 ra := pseudorand(ra'length);
212 rb := pseudorand(rb'length);
214 behave_rt := ppc_mulhwu(ra, rb);
216 m1.data1 <= (others => '0');
217 m1.data1(31 downto 0) <= ra(31 downto 0);
218 m1.data2 <= (others => '0');
219 m1.data2(31 downto 0) <= rb(31 downto 0);
221 m1.insn_type <= OP_MUL_H32;
227 wait for clk_period * (pipeline_depth-1);
229 assert m2.valid = '1';
231 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
232 report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
236 mulli_loop : for i in 0 to 1000 loop
237 ra := pseudorand(ra'length);
238 si := pseudorand(si'length);
240 behave_rt := ppc_mulli(ra, si);
242 m1.data1 <= ra(63) & ra;
243 m1.data2 <= (others => si(15));
244 m1.data2(15 downto 0) <= si;
246 m1.insn_type <= OP_MUL_L64;
252 wait for clk_period * (pipeline_depth-1);
254 assert m2.valid = '1';
256 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
257 report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
260 assert false report "end of test" severity failure;