Merge pull request #144 from antonblanchard/update-README
[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 : Decode2ToMultiplyType;
21 signal m2 : MultiplyToWritebackType;
22 begin
23 multiply_0: entity work.multiply
24 generic map (PIPELINE_DEPTH => pipeline_depth)
25 port map (clk => clk, m_in => m1, m_out => m2);
26
27 clk_process: process
28 begin
29 clk <= '0';
30 wait for clk_period/2;
31 clk <= '1';
32 wait for clk_period/2;
33 end process;
34
35 stim_process: process
36 variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
37 variable si: std_ulogic_vector(15 downto 0);
38 begin
39 wait for clk_period;
40
41 m1.valid <= '1';
42 m1.insn_type <= OP_MUL_L64;
43 m1.write_reg <= "10001";
44 m1.data1 <= '0' & x"0000000000001000";
45 m1.data2 <= '0' & x"0000000000001111";
46 m1.rc <= '0';
47
48 wait for clk_period;
49 assert m2.valid = '0';
50
51 m1.valid <= '0';
52
53 wait for clk_period;
54 assert m2.valid = '0';
55
56 wait for clk_period;
57 assert m2.valid = '0';
58
59 wait for clk_period;
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.rc = '0';
65
66 wait for clk_period;
67 assert m2.valid = '0';
68
69 m1.valid <= '1';
70 m1.rc <= '1';
71
72 wait for clk_period;
73 assert m2.valid = '0';
74
75 m1.valid <= '0';
76
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.rc = '1';
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 <= '0' & ra;
92 m1.data2 <= '0' & rb;
93 m1.valid <= '1';
94 m1.insn_type <= OP_MUL_L64;
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.write_reg_data)
105 report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
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 <= '0' & ra;
116 m1.data2 <= '0' & rb;
117 m1.valid <= '1';
118 m1.insn_type <= OP_MUL_H64;
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.write_reg_data)
129 report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
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 <= ra(63) & ra;
140 m1.data2 <= rb(63) & rb;
141 m1.valid <= '1';
142 m1.insn_type <= OP_MUL_H64;
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.write_reg_data)
153 report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
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 => ra(31));
164 m1.data1(31 downto 0) <= ra(31 downto 0);
165 m1.data2 <= (others => rb(31));
166 m1.data2(31 downto 0) <= rb(31 downto 0);
167 m1.valid <= '1';
168 m1.insn_type <= OP_MUL_L64;
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.write_reg_data)
179 report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
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 => ra(31));
190 m1.data1(31 downto 0) <= ra(31 downto 0);
191 m1.data2 <= (others => rb(31));
192 m1.data2(31 downto 0) <= rb(31 downto 0);
193 m1.valid <= '1';
194 m1.insn_type <= OP_MUL_H32;
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.write_reg_data)
205 report "bad mulhw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
206 end loop;
207
208 -- test mulhwu
209 mulhwu_loop : for i in 0 to 1000 loop
210 ra := pseudorand(ra'length);
211 rb := pseudorand(rb'length);
212
213 behave_rt := ppc_mulhwu(ra, rb);
214
215 m1.data1 <= (others => '0');
216 m1.data1(31 downto 0) <= ra(31 downto 0);
217 m1.data2 <= (others => '0');
218 m1.data2(31 downto 0) <= rb(31 downto 0);
219 m1.valid <= '1';
220 m1.insn_type <= OP_MUL_H32;
221
222 wait for clk_period;
223
224 m1.valid <= '0';
225
226 wait for clk_period * (pipeline_depth-1);
227
228 assert m2.valid = '1';
229
230 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
231 report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
232 end loop;
233
234 -- test mulli
235 mulli_loop : for i in 0 to 1000 loop
236 ra := pseudorand(ra'length);
237 si := pseudorand(si'length);
238
239 behave_rt := ppc_mulli(ra, si);
240
241 m1.data1 <= ra(63) & ra;
242 m1.data2 <= (others => si(15));
243 m1.data2(15 downto 0) <= si;
244 m1.valid <= '1';
245 m1.insn_type <= OP_MUL_L64;
246
247 wait for clk_period;
248
249 m1.valid <= '0';
250
251 wait for clk_period * (pipeline_depth-1);
252
253 assert m2.valid = '1';
254
255 assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
256 report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
257 end loop;
258
259 assert false report "end of test" severity failure;
260 wait;
261 end process;
262 end behave;