Add Tercel PHY reset synchronization
[microwatt.git] / multiply_tb.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.decode_types.all;
7 use work.common.all;
8 use work.glibc_random.all;
9 use work.ppc_fx_insns.all;
10
11 entity multiply_tb is
12 end multiply_tb;
13
14 architecture behave of multiply_tb is
15 signal clk : std_ulogic;
16 constant clk_period : time := 10 ns;
17
18 constant pipeline_depth : integer := 4;
19
20 signal m1 : MultiplyInputType := MultiplyInputInit;
21 signal m2 : MultiplyOutputType;
22
23 function absval(x: std_ulogic_vector) return std_ulogic_vector is
24 begin
25 if x(x'left) = '1' then
26 return std_ulogic_vector(- signed(x));
27 else
28 return x;
29 end if;
30 end;
31
32 begin
33 multiply_0: entity work.multiply
34 generic map (PIPELINE_DEPTH => pipeline_depth)
35 port map (clk => clk, m_in => m1, m_out => m2);
36
37 clk_process: process
38 begin
39 clk <= '0';
40 wait for clk_period/2;
41 clk <= '1';
42 wait for clk_period/2;
43 end process;
44
45 stim_process: process
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;
49 begin
50 wait for clk_period;
51
52 m1.valid <= '1';
53 m1.data1 <= x"0000000000001000";
54 m1.data2 <= x"0000000000001111";
55
56 wait for clk_period;
57 assert m2.valid = '0';
58
59 m1.valid <= '0';
60
61 wait for clk_period;
62 assert m2.valid = '0';
63
64 wait for clk_period;
65 assert m2.valid = '0';
66
67 wait for clk_period;
68 assert m2.valid = '1';
69 assert m2.result = x"00000000000000000000000001111000";
70
71 wait for clk_period;
72 assert m2.valid = '0';
73
74 m1.valid <= '1';
75
76 wait for clk_period;
77 assert m2.valid = '0';
78
79 m1.valid <= '0';
80
81 wait for clk_period * (pipeline_depth-1);
82 assert m2.valid = '1';
83 assert m2.result = x"00000000000000000000000001111000";
84
85 -- test mulld
86 mulld_loop : for i in 0 to 1000 loop
87 ra := pseudorand(ra'length);
88 rb := pseudorand(rb'length);
89
90 behave_rt := ppc_mulld(ra, rb);
91
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);
97 m1.valid <= '1';
98
99 wait for clk_period;
100
101 m1.valid <= '0';
102
103 wait for clk_period * (pipeline_depth-1);
104
105 assert m2.valid = '1';
106
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));
109 end loop;
110
111 -- test mulhdu
112 mulhdu_loop : for i in 0 to 1000 loop
113 ra := pseudorand(ra'length);
114 rb := pseudorand(rb'length);
115
116 behave_rt := ppc_mulhdu(ra, rb);
117
118 m1.data1 <= ra;
119 m1.data2 <= rb;
120 m1.not_result <= '0';
121 m1.addend <= (others => '0');
122 m1.valid <= '1';
123
124 wait for clk_period;
125
126 m1.valid <= '0';
127
128 wait for clk_period * (pipeline_depth-1);
129
130 assert m2.valid = '1';
131
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));
134 end loop;
135
136 -- test mulhd
137 mulhd_loop : for i in 0 to 1000 loop
138 ra := pseudorand(ra'length);
139 rb := pseudorand(rb'length);
140
141 behave_rt := ppc_mulhd(ra, rb);
142
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);
148 m1.valid <= '1';
149
150 wait for clk_period;
151
152 m1.valid <= '0';
153
154 wait for clk_period * (pipeline_depth-1);
155
156 assert m2.valid = '1';
157
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));
160 end loop;
161
162 -- test mullw
163 mullw_loop : for i in 0 to 1000 loop
164 ra := pseudorand(ra'length);
165 rb := pseudorand(rb'length);
166
167 behave_rt := ppc_mullw(ra, rb);
168
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);
176 m1.valid <= '1';
177
178 wait for clk_period;
179
180 m1.valid <= '0';
181
182 wait for clk_period * (pipeline_depth-1);
183
184 assert m2.valid = '1';
185
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));
188 end loop;
189
190 -- test mulhw
191 mulhw_loop : for i in 0 to 1000 loop
192 ra := pseudorand(ra'length);
193 rb := pseudorand(rb'length);
194
195 behave_rt := ppc_mulhw(ra, rb);
196
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);
204 m1.valid <= '1';
205
206 wait for clk_period;
207
208 m1.valid <= '0';
209
210 wait for clk_period * (pipeline_depth-1);
211
212 assert m2.valid = '1';
213
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));
217 end loop;
218
219 -- test mulhwu
220 mulhwu_loop : for i in 0 to 1000 loop
221 ra := pseudorand(ra'length);
222 rb := pseudorand(rb'length);
223
224 behave_rt := ppc_mulhwu(ra, rb);
225
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');
232 m1.valid <= '1';
233
234 wait for clk_period;
235
236 m1.valid <= '0';
237
238 wait for clk_period * (pipeline_depth-1);
239
240 assert m2.valid = '1';
241
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));
245 end loop;
246
247 -- test mulli
248 mulli_loop : for i in 0 to 1000 loop
249 ra := pseudorand(ra'length);
250 si := pseudorand(si'length);
251
252 behave_rt := ppc_mulli(ra, si);
253
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);
260 m1.valid <= '1';
261
262 wait for clk_period;
263
264 m1.valid <= '0';
265
266 wait for clk_period * (pipeline_depth-1);
267
268 assert m2.valid = '1';
269
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));
272 end loop;
273
274 std.env.finish;
275 wait;
276 end process;
277 end behave;