Merge pull request #208 from paulusmack/faster
[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 : Execute1ToMultiplyType := Execute1ToMultiplyInit;
21 signal m2 : MultiplyToExecute1Type;
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 begin
49 wait for clk_period;
50
51 m1.valid <= '1';
52 m1.data1 <= x"0000000000001000";
53 m1.data2 <= x"0000000000001111";
54
55 wait for clk_period;
56 assert m2.valid = '0';
57
58 m1.valid <= '0';
59
60 wait for clk_period;
61 assert m2.valid = '0';
62
63 wait for clk_period;
64 assert m2.valid = '0';
65
66 wait for clk_period;
67 assert m2.valid = '1';
68 assert m2.result = x"00000000000000000000000001111000";
69
70 wait for clk_period;
71 assert m2.valid = '0';
72
73 m1.valid <= '1';
74
75 wait for clk_period;
76 assert m2.valid = '0';
77
78 m1.valid <= '0';
79
80 wait for clk_period * (pipeline_depth-1);
81 assert m2.valid = '1';
82 assert m2.result = x"00000000000000000000000001111000";
83
84 -- test mulld
85 mulld_loop : for i in 0 to 1000 loop
86 ra := pseudorand(ra'length);
87 rb := pseudorand(rb'length);
88
89 behave_rt := ppc_mulld(ra, rb);
90
91 m1.data1 <= absval(ra);
92 m1.data2 <= absval(rb);
93 m1.neg_result <= ra(63) xor rb(63);
94 m1.valid <= '1';
95
96 wait for clk_period;
97
98 m1.valid <= '0';
99
100 wait for clk_period * (pipeline_depth-1);
101
102 assert m2.valid = '1';
103
104 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
105 report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
106 end loop;
107
108 -- test mulhdu
109 mulhdu_loop : for i in 0 to 1000 loop
110 ra := pseudorand(ra'length);
111 rb := pseudorand(rb'length);
112
113 behave_rt := ppc_mulhdu(ra, rb);
114
115 m1.data1 <= ra;
116 m1.data2 <= rb;
117 m1.neg_result <= '0';
118 m1.valid <= '1';
119
120 wait for clk_period;
121
122 m1.valid <= '0';
123
124 wait for clk_period * (pipeline_depth-1);
125
126 assert m2.valid = '1';
127
128 assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64))
129 report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64));
130 end loop;
131
132 -- test mulhd
133 mulhd_loop : for i in 0 to 1000 loop
134 ra := pseudorand(ra'length);
135 rb := pseudorand(rb'length);
136
137 behave_rt := ppc_mulhd(ra, rb);
138
139 m1.data1 <= absval(ra);
140 m1.data2 <= absval(rb);
141 m1.neg_result <= ra(63) xor rb(63);
142 m1.valid <= '1';
143
144 wait for clk_period;
145
146 m1.valid <= '0';
147
148 wait for clk_period * (pipeline_depth-1);
149
150 assert m2.valid = '1';
151
152 assert to_hstring(behave_rt) = to_hstring(m2.result(127 downto 64))
153 report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64));
154 end loop;
155
156 -- test mullw
157 mullw_loop : for i in 0 to 1000 loop
158 ra := pseudorand(ra'length);
159 rb := pseudorand(rb'length);
160
161 behave_rt := ppc_mullw(ra, rb);
162
163 m1.data1 <= (others => '0');
164 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
165 m1.data2 <= (others => '0');
166 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
167 m1.neg_result <= ra(31) xor rb(31);
168 m1.valid <= '1';
169
170 wait for clk_period;
171
172 m1.valid <= '0';
173
174 wait for clk_period * (pipeline_depth-1);
175
176 assert m2.valid = '1';
177
178 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
179 report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
180 end loop;
181
182 -- test mulhw
183 mulhw_loop : for i in 0 to 1000 loop
184 ra := pseudorand(ra'length);
185 rb := pseudorand(rb'length);
186
187 behave_rt := ppc_mulhw(ra, rb);
188
189 m1.data1 <= (others => '0');
190 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
191 m1.data2 <= (others => '0');
192 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
193 m1.neg_result <= ra(31) xor rb(31);
194 m1.valid <= '1';
195
196 wait for clk_period;
197
198 m1.valid <= '0';
199
200 wait for clk_period * (pipeline_depth-1);
201
202 assert m2.valid = '1';
203
204 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32))
205 report "bad mulhw expected " & to_hstring(behave_rt) & " got " &
206 to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32));
207 end loop;
208
209 -- test mulhwu
210 mulhwu_loop : for i in 0 to 1000 loop
211 ra := pseudorand(ra'length);
212 rb := pseudorand(rb'length);
213
214 behave_rt := ppc_mulhwu(ra, rb);
215
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);
220 m1.neg_result <= '0';
221 m1.valid <= '1';
222
223 wait for clk_period;
224
225 m1.valid <= '0';
226
227 wait for clk_period * (pipeline_depth-1);
228
229 assert m2.valid = '1';
230
231 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32))
232 report "bad mulhwu expected " & to_hstring(behave_rt) & " got " &
233 to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32));
234 end loop;
235
236 -- test mulli
237 mulli_loop : for i in 0 to 1000 loop
238 ra := pseudorand(ra'length);
239 si := pseudorand(si'length);
240
241 behave_rt := ppc_mulli(ra, si);
242
243 m1.data1 <= absval(ra);
244 m1.data2 <= (others => '0');
245 m1.data2(15 downto 0) <= absval(si);
246 m1.neg_result <= ra(63) xor si(15);
247 m1.valid <= '1';
248
249 wait for clk_period;
250
251 m1.valid <= '0';
252
253 wait for clk_period * (pipeline_depth-1);
254
255 assert m2.valid = '1';
256
257 assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
258 report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
259 end loop;
260
261 std.env.finish;
262 wait;
263 end process;
264 end behave;