begin working on linux verilator simulation
[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 function absval(x: std_ulogic_vector) return std_ulogic_vector is
30 begin
31 if x(x'left) = '1' then
32 return std_ulogic_vector(- signed(x));
33 else
34 return x;
35 end if;
36 end;
37
38 begin
39 multiply_0: entity work.multiply
40 generic map (PIPELINE_DEPTH => pipeline_depth)
41 port map (clk => clk, m_in => m1, m_out => m2);
42
43 clk_process: process
44 begin
45 clk <= '0';
46 wait for clk_period/2;
47 clk <= '1';
48 wait for clk_period/2;
49 end process;
50
51 stim_process: process
52 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
53 variable si: std_ulogic_vector(15 downto 0);
54 variable sign: std_ulogic;
55 variable rnd : RandomPType;
56 begin
57 rnd.InitSeed(stim_process'path_name);
58
59 test_runner_setup(runner, runner_cfg);
60
61 while test_suite loop
62 if run("Test interface") then
63 wait for clk_period;
64
65 m1.valid <= '1';
66 m1.data1 <= x"0000000000001000";
67 m1.data2 <= x"0000000000001111";
68
69 wait for clk_period;
70 check_false(?? m2.valid, result("for valid"));
71
72 m1.valid <= '0';
73
74 wait for clk_period;
75 check_false(?? m2.valid, result("for valid"));
76
77 wait for clk_period;
78 check_false(?? m2.valid, result("for valid"));
79
80 wait for clk_period;
81 check_true(?? m2.valid, result("for valid"));
82 check_equal(m2.result, 16#1111000#);
83
84 wait for clk_period;
85 check_false(?? m2.valid, result("for valid"));
86
87 m1.valid <= '1';
88
89 wait for clk_period;
90 check_false(?? m2.valid, result("for valid"));
91
92 m1.valid <= '0';
93
94 wait for clk_period * (pipeline_depth-1);
95 check_true(?? m2.valid, result("for valid"));
96 check_equal(m2.result, 16#1111000#);
97
98 elsif run("Test mulld") then
99 mulld_loop : for i in 0 to 1000 loop
100 ra := rnd.RandSlv(ra'length);
101 rb := rnd.RandSlv(rb'length);
102
103 behave_rt := ppc_mulld(ra, rb);
104
105 m1.data1 <= absval(ra);
106 m1.data2 <= absval(rb);
107 sign := ra(63) xor rb(63);
108 m1.not_result <= sign;
109 m1.addend <= (others => sign);
110 m1.valid <= '1';
111
112 wait for clk_period;
113
114 m1.valid <= '0';
115
116 wait for clk_period * (pipeline_depth-1);
117
118 check_true(?? m2.valid, result("for valid"));
119 check_equal(m2.result(63 downto 0), behave_rt, result("for mulld " & to_hstring(behave_rt)));
120 end loop;
121
122 elsif run("Test mulhdu") then
123 mulhdu_loop : for i in 0 to 1000 loop
124 ra := rnd.RandSlv(ra'length);
125 rb := rnd.RandSlv(rb'length);
126
127 behave_rt := ppc_mulhdu(ra, rb);
128
129 m1.data1 <= ra;
130 m1.data2 <= rb;
131 m1.not_result <= '0';
132 m1.addend <= (others => '0');
133 m1.valid <= '1';
134
135 wait for clk_period;
136
137 m1.valid <= '0';
138
139 wait for clk_period * (pipeline_depth-1);
140
141 check_true(?? m2.valid, result("for valid"));
142 check_equal(m2.result(127 downto 64), behave_rt, result("for mulhdu " & to_hstring(behave_rt)));
143 end loop;
144
145 elsif run("Test mulhd") then
146 mulhd_loop : for i in 0 to 1000 loop
147 ra := rnd.RandSlv(ra'length);
148 rb := rnd.RandSlv(rb'length);
149
150 behave_rt := ppc_mulhd(ra, rb);
151
152 m1.data1 <= absval(ra);
153 m1.data2 <= absval(rb);
154 sign := ra(63) xor rb(63);
155 m1.not_result <= sign;
156 m1.addend <= (others => sign);
157 m1.valid <= '1';
158
159 wait for clk_period;
160
161 m1.valid <= '0';
162
163 wait for clk_period * (pipeline_depth-1);
164
165 check_true(?? m2.valid, result("for valid"));
166 check_equal(m2.result(127 downto 64), behave_rt, result("for mulhd " & to_hstring(behave_rt)));
167 end loop;
168
169 elsif run("Test mullw") then
170 mullw_loop : for i in 0 to 1000 loop
171 ra := rnd.RandSlv(ra'length);
172 rb := rnd.RandSlv(rb'length);
173
174 behave_rt := ppc_mullw(ra, rb);
175
176 m1.data1 <= (others => '0');
177 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
178 m1.data2 <= (others => '0');
179 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
180 sign := ra(31) xor rb(31);
181 m1.not_result <= sign;
182 m1.addend <= (others => sign);
183 m1.valid <= '1';
184
185 wait for clk_period;
186
187 m1.valid <= '0';
188
189 wait for clk_period * (pipeline_depth-1);
190
191 check_true(?? m2.valid, result("for valid"));
192 check_equal(m2.result(63 downto 0), behave_rt, result("for mullw " & to_hstring(behave_rt)));
193 end loop;
194
195 elsif run("Test mulhw") then
196 mulhw_loop : for i in 0 to 1000 loop
197 ra := rnd.RandSlv(ra'length);
198 rb := rnd.RandSlv(rb'length);
199
200 behave_rt := ppc_mulhw(ra, rb);
201
202 m1.data1 <= (others => '0');
203 m1.data1(31 downto 0) <= absval(ra(31 downto 0));
204 m1.data2 <= (others => '0');
205 m1.data2(31 downto 0) <= absval(rb(31 downto 0));
206 sign := ra(31) xor rb(31);
207 m1.not_result <= sign;
208 m1.addend <= (others => sign);
209 m1.valid <= '1';
210
211 wait for clk_period;
212
213 m1.valid <= '0';
214
215 wait for clk_period * (pipeline_depth-1);
216
217 check_true(?? m2.valid, result("for valid"));
218 check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhw " & to_hstring(behave_rt)));
219 end loop;
220
221 elsif run("Test mulhwu") then
222 mulhwu_loop : for i in 0 to 1000 loop
223 ra := rnd.RandSlv(ra'length);
224 rb := rnd.RandSlv(rb'length);
225
226 behave_rt := ppc_mulhwu(ra, rb);
227
228 m1.data1 <= (others => '0');
229 m1.data1(31 downto 0) <= ra(31 downto 0);
230 m1.data2 <= (others => '0');
231 m1.data2(31 downto 0) <= rb(31 downto 0);
232 m1.not_result <= '0';
233 m1.addend <= (others => '0');
234 m1.valid <= '1';
235
236 wait for clk_period;
237
238 m1.valid <= '0';
239
240 wait for clk_period * (pipeline_depth-1);
241
242 check_true(?? m2.valid, result("for valid"));
243 check_equal(m2.result(63 downto 32) & m2.result(63 downto 32), behave_rt, result("for mulhwu " & to_hstring(behave_rt)));
244 end loop;
245
246 elsif run("Test mulli") then
247 mulli_loop : for i in 0 to 1000 loop
248 ra := rnd.RandSlv(ra'length);
249 si := rnd.RandSlv(si'length);
250
251 behave_rt := ppc_mulli(ra, si);
252
253 m1.data1 <= absval(ra);
254 m1.data2 <= (others => '0');
255 m1.data2(15 downto 0) <= absval(si);
256 sign := ra(63) xor si(15);
257 m1.not_result <= sign;
258 m1.addend <= (others => sign);
259 m1.valid <= '1';
260
261 wait for clk_period;
262
263 m1.valid <= '0';
264
265 wait for clk_period * (pipeline_depth-1);
266
267 check_true(?? m2.valid, result("for valid"));
268 check_equal(m2.result(63 downto 0), behave_rt, result("for mulli " & to_hstring(behave_rt)));
269 end loop;
270 end if;
271 end loop;
272
273 test_runner_cleanup(runner);
274 wait;
275 end process;
276 end behave;