ignore /abc.history
[microwatt.git] / multiply_tb.vhdl
1 library vunit_lib;
2 context vunit_lib.vunit_context;
3
4 library ieee;
5 use ieee.std_logic_1164.all;
6 use ieee.numeric_std.all;
7
8 library work;
9 use work.decode_types.all;
10 use work.common.all;
11 use work.ppc_fx_insns.all;
12
13 library osvvm;
14 use osvvm.RandomPkg.all;
15
16 entity multiply_tb is
17 generic (runner_cfg : string := runner_cfg_default);
18 end multiply_tb;
19
20 architecture behave of multiply_tb is
21 signal clk : std_ulogic;
22 constant clk_period : time := 10 ns;
23
24 constant pipeline_depth : integer := 4;
25
26 signal m1 : MultiplyInputType := MultiplyInputInit;
27 signal m2 : MultiplyOutputType;
28
29 begin
30 multiply_0: entity work.multiply
31 generic map (PIPELINE_DEPTH => pipeline_depth)
32 port map (clk => clk, m_in => m1, m_out => m2);
33
34 clk_process: process
35 begin
36 clk <= '0';
37 wait for clk_period/2;
38 clk <= '1';
39 wait for clk_period/2;
40 end process;
41
42 stim_process: process
43 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
44 variable si: std_ulogic_vector(15 downto 0);
45 variable rnd : RandomPType;
46 begin
47 rnd.InitSeed(stim_process'path_name);
48
49 test_runner_setup(runner, runner_cfg);
50
51 while test_suite loop
52 if run("Test interface") then
53 wait for clk_period;
54
55 m1.valid <= '1';
56 m1.data1 <= x"0000000000001000";
57 m1.data2 <= x"0000000000001111";
58
59 wait for clk_period;
60 check_false(?? m2.valid, result("for valid"));
61
62 m1.valid <= '0';
63
64 wait for clk_period;
65 check_false(?? m2.valid, result("for valid"));
66
67 wait for clk_period;
68 check_false(?? m2.valid, result("for valid"));
69
70 wait for clk_period;
71 check_true(?? m2.valid, result("for valid"));
72 check_equal(m2.result, 16#1111000#);
73
74 wait for clk_period;
75 check_false(?? m2.valid, result("for valid"));
76
77 m1.valid <= '1';
78
79 wait for clk_period;
80 check_false(?? m2.valid, result("for valid"));
81
82 m1.valid <= '0';
83
84 wait for clk_period * (pipeline_depth-1);
85 check_true(?? m2.valid, result("for valid"));
86 check_equal(m2.result, 16#1111000#);
87
88 elsif run("Test mulld") then
89 mulld_loop : for i in 0 to 1000 loop
90 ra := rnd.RandSlv(ra'length);
91 rb := rnd.RandSlv(rb'length);
92
93 behave_rt := ppc_mulld(ra, rb);
94
95 m1.data1 <= ra;
96 m1.data2 <= rb;
97 m1.is_signed <= '1';
98 m1.subtract <= '0';
99 m1.addend <= (others => '0');
100 m1.valid <= '1';
101
102 wait for clk_period;
103
104 m1.valid <= '0';
105
106 wait for clk_period * (pipeline_depth-1);
107
108 check_true(?? m2.valid, result("for valid"));
109 check_equal(m2.result(63 downto 0), behave_rt, result("for mulld " & to_hstring(behave_rt)));
110 end loop;
111
112 elsif run("Test mulhdu") then
113 mulhdu_loop : for i in 0 to 1000 loop
114 ra := rnd.RandSlv(ra'length);
115 rb := rnd.RandSlv(rb'length);
116
117 behave_rt := ppc_mulhdu(ra, rb);
118
119 m1.data1 <= ra;
120 m1.data2 <= rb;
121 m1.is_signed <= '0';
122 m1.subtract <= '0';
123 m1.addend <= (others => '0');
124 m1.valid <= '1';
125
126 wait for clk_period;
127
128 m1.valid <= '0';
129
130 wait for clk_period * (pipeline_depth-1);
131
132 check_true(?? m2.valid, result("for valid"));
133 check_equal(m2.result(127 downto 64), behave_rt, result("for mulhdu " & to_hstring(behave_rt)));
134 end loop;
135
136 elsif run("Test mulhd") then
137 mulhd_loop : for i in 0 to 1000 loop
138 ra := rnd.RandSlv(ra'length);
139 rb := rnd.RandSlv(rb'length);
140
141 behave_rt := ppc_mulhd(ra, rb);
142
143 m1.data1 <= ra;
144 m1.data2 <= rb;
145 m1.is_signed <= '1';
146 m1.subtract <= '0';
147 m1.addend <= (others => '0');
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 check_true(?? m2.valid, result("for valid"));
157 check_equal(m2.result(127 downto 64), behave_rt, result("for mulhd " & to_hstring(behave_rt)));
158 end loop;
159
160 elsif run("Test mullw") then
161 mullw_loop : for i in 0 to 1000 loop
162 ra := rnd.RandSlv(ra'length);
163 rb := rnd.RandSlv(rb'length);
164
165 behave_rt := ppc_mullw(ra, rb);
166
167 m1.data1 <= (others => ra(31));
168 m1.data1(31 downto 0) <= ra(31 downto 0);
169 m1.data2 <= (others => rb(31));
170 m1.data2(31 downto 0) <= rb(31 downto 0);
171 m1.is_signed <= '1';
172 m1.subtract <= '0';
173 m1.addend <= (others => '0');
174 m1.valid <= '1';
175
176 wait for clk_period;
177
178 m1.valid <= '0';
179
180 wait for clk_period * (pipeline_depth-1);
181
182 check_true(?? m2.valid, result("for valid"));
183 check_equal(m2.result(63 downto 0), behave_rt, result("for mullw " & to_hstring(behave_rt)));
184 end loop;
185
186 elsif run("Test mulhw") then
187 mulhw_loop : for i in 0 to 1000 loop
188 ra := rnd.RandSlv(ra'length);
189 rb := rnd.RandSlv(rb'length);
190
191 behave_rt := ppc_mulhw(ra, rb);
192
193 m1.data1 <= (others => ra(31));
194 m1.data1(31 downto 0) <= ra(31 downto 0);
195 m1.data2 <= (others => rb(31));
196 m1.data2(31 downto 0) <= rb(31 downto 0);
197 m1.is_signed <= '1';
198 m1.subtract <= '0';
199 m1.addend <= (others => '0');
200 m1.valid <= '1';
201
202 wait for clk_period;
203
204 m1.valid <= '0';
205
206 wait for clk_period * (pipeline_depth-1);
207
208 check_true(?? m2.valid, result("for valid"));
209 check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhw " & to_hstring(behave_rt)));
210 end loop;
211
212 elsif run("Test mulhwu") then
213 mulhwu_loop : for i in 0 to 1000 loop
214 ra := rnd.RandSlv(ra'length);
215 rb := rnd.RandSlv(rb'length);
216
217 behave_rt := ppc_mulhwu(ra, rb);
218
219 m1.data1 <= (others => '0');
220 m1.data1(31 downto 0) <= ra(31 downto 0);
221 m1.data2 <= (others => '0');
222 m1.data2(31 downto 0) <= rb(31 downto 0);
223 m1.is_signed <= '0';
224 m1.subtract <= '0';
225 m1.addend <= (others => '0');
226 m1.valid <= '1';
227
228 wait for clk_period;
229
230 m1.valid <= '0';
231
232 wait for clk_period * (pipeline_depth-1);
233
234 check_true(?? m2.valid, result("for valid"));
235 check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhwu " & to_hstring(behave_rt)));
236 end loop;
237
238 elsif run("Test mulli") then
239 mulli_loop : for i in 0 to 1000 loop
240 ra := rnd.RandSlv(ra'length);
241 si := rnd.RandSlv(si'length);
242
243 behave_rt := ppc_mulli(ra, si);
244
245 m1.data1 <= ra;
246 m1.data2 <= (others => si(15));
247 m1.data2(15 downto 0) <= si;
248 m1.is_signed <= '1';
249 m1.subtract <= '0';
250 m1.addend <= (others => '0');
251 m1.valid <= '1';
252
253 wait for clk_period;
254
255 m1.valid <= '0';
256
257 wait for clk_period * (pipeline_depth-1);
258
259 check_true(?? m2.valid, result("for valid"));
260 check_equal(m2.result(63 downto 0), behave_rt, result("for mulli " & to_hstring(behave_rt)));
261 end loop;
262 end if;
263 end loop;
264
265 test_runner_cleanup(runner);
266 wait;
267 end process;
268 end behave;