add code-comments explaining that setvl, svstep svremap and svshape are
[openpower-isa.git] / src / openpower / test / common.py
1 """
2 Bugreports:
3 * https://bugs.libre-soc.org/show_bug.cgi?id=361
4 """
5
6 import inspect
7 import functools
8 import types
9 import os
10
11 from openpower.decoder.power_enums import XER_bits, CryIn, spr_dict
12 from openpower.util import fast_reg_to_spr, slow_reg_to_spr # HACK!
13 from openpower.consts import XERRegsEnum
14
15
16 # TODO: make this a util routine (somewhere)
17 def mask_extend(x, nbits, repeat):
18 res = 0
19 extended = (1<<repeat)-1
20 for i in range(nbits):
21 if x & (1<<i):
22 res |= extended << (i*repeat)
23 return res
24
25
26 class SkipCase(Exception):
27 """Raise this exception to skip a test case.
28
29 Usually you'd use one of the skip_case* decorators.
30
31 For use with TestAccumulatorBase
32 """
33
34
35 def _id(obj):
36 """identity function"""
37 return obj
38
39
40 def skip_case(reason):
41 """
42 Unconditionally skip a test case.
43
44 Use like:
45 @skip_case("my reason for skipping")
46 def case_abc(self):
47 ...
48 or:
49 @skip_case
50 def case_def(self):
51 ...
52
53 For use with TestAccumulatorBase
54 """
55 def decorator(item):
56 assert not isinstance(item, type), \
57 "can't use skip_case to decorate types"
58
59 @functools.wraps(item)
60 def wrapper(*args, **kwargs):
61 raise SkipCase(reason)
62 return wrapper
63 if isinstance(reason, types.FunctionType):
64 item = reason
65 reason = ""
66 return decorator(item)
67 return decorator
68
69
70 def skip_case_if(condition, reason):
71 """
72 Conditionally skip a test case.
73
74 Use like:
75 @skip_case_if(should_i_skip(), "my reason for skipping")
76 def case_abc(self):
77 ...
78
79 For use with TestAccumulatorBase
80 """
81 if condition:
82 return skip_case(reason)
83 return _id
84
85
86 class TestAccumulatorBase:
87
88 def __init__(self):
89 self.test_data = []
90 # automatically identifies anything starting with "case_" and
91 # runs it. very similar to unittest auto-identification except
92 # we need a different system
93 for n, v in self.__class__.__dict__.items():
94 if n.startswith("case_") and callable(v):
95 try:
96 v(self)
97 except SkipCase as e:
98 # TODO(programmerjake): translate to final test sending
99 # skip signal to unittest. for now, just print the skipped
100 # reason and ignore
101 print(f"SKIPPED({n}):", str(e))
102
103 def add_case(self, prog, initial_regs=None, initial_sprs=None,
104 initial_cr=0, initial_msr=0,
105 initial_mem=None,
106 initial_svstate=0,
107 expected=None,
108 stop_at_pc=None):
109
110 test_name = inspect.stack()[1][3] # name of caller of this function
111 # name of file containing test case
112 test_file = os.path.splitext(os.path.basename(
113 inspect.stack()[1][1]))[0]
114 tc = TestCase(prog, test_name,
115 regs=initial_regs, sprs=initial_sprs, cr=initial_cr,
116 msr=initial_msr,
117 mem=initial_mem,
118 svstate=initial_svstate,
119 expected=expected,
120 stop_at_pc=stop_at_pc,
121 test_file=test_file)
122
123 self.test_data.append(tc)
124
125
126 class TestCase:
127 def __init__(self, program, name, regs=None, sprs=None, cr=0, mem=None,
128 msr=0,
129 do_sim=True,
130 extra_break_addr=None,
131 svstate=0,
132 expected=None,
133 stop_at_pc=None,
134 test_file=None):
135
136 self.program = program
137 self.name = name
138
139 if regs is None:
140 regs = [0] * 32
141 if sprs is None:
142 sprs = {}
143 if mem is None:
144 mem = {}
145 self.regs = regs
146 self.sprs = sprs
147 self.cr = cr
148 self.mem = mem
149 self.msr = msr
150 self.do_sim = do_sim
151 self.extra_break_addr = extra_break_addr
152 self.svstate = svstate
153 self.expected = expected # expected results from the test
154 self.stop_at_pc = stop_at_pc # hard-stop address (do not attempt to run)
155 self.test_file = test_file
156
157
158 class ALUHelpers:
159
160 def get_sim_fast_reg(res, sim, dec2, reg, name):
161 spr_sel = fast_reg_to_spr(reg)
162 spr_data = sim.spr[spr_sel].value
163 res[name] = spr_data
164
165 def get_sim_cia(res, sim, dec2):
166 res['cia'] = sim.pc.CIA.value
167
168 # use this *after* the simulation has run a step (it returns CIA)
169 def get_sim_nia(res, sim, dec2):
170 res['nia'] = sim.pc.CIA.value
171
172 def get_sim_msr(res, sim, dec2):
173 res['msr'] = sim.msr.value
174
175 def get_sim_slow_spr1(res, sim, dec2):
176 spr1_en = yield dec2.e.read_spr1.ok
177 if spr1_en:
178 spr1_sel = yield dec2.e.read_spr1.data
179 spr1_sel = slow_reg_to_spr(spr1_sel)
180 spr1_data = sim.spr[spr1_sel].value
181 res['spr1'] = spr1_data
182
183 def get_sim_fast_spr1(res, sim, dec2):
184 fast1_en = yield dec2.e.read_fast1.ok
185 if fast1_en:
186 fast1_sel = yield dec2.e.read_fast1.data
187 spr1_sel = fast_reg_to_spr(fast1_sel)
188 spr1_data = sim.spr[spr1_sel].value
189 res['fast1'] = spr1_data
190
191 def get_sim_fast_spr2(res, sim, dec2):
192 fast2_en = yield dec2.e.read_fast2.ok
193 if fast2_en:
194 fast2_sel = yield dec2.e.read_fast2.data
195 spr2_sel = fast_reg_to_spr(fast2_sel)
196 spr2_data = sim.spr[spr2_sel].value
197 res['fast2'] = spr2_data
198
199 def get_sim_fast_spr3(res, sim, dec2):
200 fast3_en = yield dec2.e.read_fast3.ok
201 if fast3_en:
202 fast3_sel = yield dec2.e.read_fast3.data
203 spr3_sel = fast_reg_to_spr(fast3_sel)
204 spr3_data = sim.spr[spr3_sel].value
205 res['fast3'] = spr3_data
206
207 def get_sim_cr_a(res, sim, dec2):
208 cridx_ok = yield dec2.e.read_cr1.ok
209 if cridx_ok:
210 cridx = yield dec2.e.read_cr1.data
211 res['cr_a'] = sim.crl[cridx].get_range().value
212
213 def get_sim_cr_b(res, sim, dec2):
214 cridx_ok = yield dec2.e.read_cr2.ok
215 if cridx_ok:
216 cridx = yield dec2.e.read_cr2.data
217 res['cr_b'] = sim.crl[cridx].get_range().value
218
219 def get_sim_cr_c(res, sim, dec2):
220 cridx_ok = yield dec2.e.read_cr3.ok
221 if cridx_ok:
222 cridx = yield dec2.e.read_cr3.data
223 res['cr_c'] = sim.crl[cridx].get_range().value
224
225 def get_sim_int_ra(res, sim, dec2):
226 # TODO: immediate RA zero
227 reg1_ok = yield dec2.e.read_reg1.ok
228 if reg1_ok:
229 data1 = yield dec2.e.read_reg1.data
230 res['ra'] = sim.gpr(data1).value
231
232 def get_sim_int_rb(res, sim, dec2):
233 reg2_ok = yield dec2.e.read_reg2.ok
234 if reg2_ok:
235 data = yield dec2.e.read_reg2.data
236 res['rb'] = sim.gpr(data).value
237
238 def get_sim_int_rc(res, sim, dec2):
239 reg3_ok = yield dec2.e.read_reg3.ok
240 if reg3_ok:
241 data = yield dec2.e.read_reg3.data
242 res['rc'] = sim.gpr(data).value
243
244 def get_rd_sim_xer_ca(res, sim, dec2):
245 cry_in = yield dec2.e.do.input_carry
246 xer_in = yield dec2.e.xer_in
247 if (xer_in & (1<<XERRegsEnum.CA)) or cry_in == CryIn.CA.value:
248 expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
249 expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
250 res['xer_ca'] = expected_carry | (expected_carry32 << 1)
251
252 def set_int_ra(alu, dec2, inp):
253 # TODO: immediate RA zero.
254 if 'ra' in inp:
255 yield alu.p.i_data.ra.eq(inp['ra'])
256 else:
257 yield alu.p.i_data.ra.eq(0)
258
259 def set_int_rb(alu, dec2, inp):
260 yield alu.p.i_data.rb.eq(0)
261 if 'rb' in inp:
262 yield alu.p.i_data.rb.eq(inp['rb'])
263 if not hasattr(dec2.e.do, "imm_data"):
264 return
265 # If there's an immediate, set the B operand to that
266 imm_ok = yield dec2.e.do.imm_data.ok
267 if imm_ok:
268 data2 = yield dec2.e.do.imm_data.data
269 yield alu.p.i_data.rb.eq(data2)
270
271 def set_int_rc(alu, dec2, inp):
272 if 'rc' in inp:
273 yield alu.p.i_data.rc.eq(inp['rc'])
274 else:
275 yield alu.p.i_data.rc.eq(0)
276
277 def set_xer_ca(alu, dec2, inp):
278 if 'xer_ca' in inp:
279 yield alu.p.i_data.xer_ca.eq(inp['xer_ca'])
280 print("extra inputs: CA/32", bin(inp['xer_ca']))
281
282 def set_xer_ov(alu, dec2, inp):
283 if 'xer_ov' in inp:
284 yield alu.p.i_data.xer_ov.eq(inp['xer_ov'])
285 print("extra inputs: OV/32", bin(inp['xer_ov']))
286
287 def set_xer_so(alu, dec2, inp):
288 if 'xer_so' in inp:
289 so = inp['xer_so']
290 print("extra inputs: so", so)
291 yield alu.p.i_data.xer_so.eq(so)
292
293 def set_msr(alu, dec2, inp):
294 print("TODO: deprecate set_msr")
295 if 'msr' in inp:
296 yield alu.p.i_data.msr.eq(inp['msr'])
297
298 def set_cia(alu, dec2, inp):
299 print("TODO: deprecate set_cia")
300 if 'cia' in inp:
301 yield alu.p.i_data.cia.eq(inp['cia'])
302
303 def set_slow_spr1(alu, dec2, inp):
304 if 'spr1' in inp:
305 yield alu.p.i_data.spr1.eq(inp['spr1'])
306
307 def set_slow_spr2(alu, dec2, inp):
308 if 'spr2' in inp:
309 yield alu.p.i_data.spr2.eq(inp['spr2'])
310
311 def set_fast_spr1(alu, dec2, inp):
312 if 'fast1' in inp:
313 yield alu.p.i_data.fast1.eq(inp['fast1'])
314
315 def set_fast_spr2(alu, dec2, inp):
316 if 'fast2' in inp:
317 yield alu.p.i_data.fast2.eq(inp['fast2'])
318
319 def set_fast_spr3(alu, dec2, inp):
320 if 'fast3' in inp:
321 yield alu.p.i_data.fast3.eq(inp['fast3'])
322
323 def set_cr_a(alu, dec2, inp):
324 if 'cr_a' in inp:
325 yield alu.p.i_data.cr_a.eq(inp['cr_a'])
326
327 def set_cr_b(alu, dec2, inp):
328 if 'cr_b' in inp:
329 yield alu.p.i_data.cr_b.eq(inp['cr_b'])
330
331 def set_cr_c(alu, dec2, inp):
332 if 'cr_c' in inp:
333 yield alu.p.i_data.cr_c.eq(inp['cr_c'])
334
335 def set_full_cr(alu, dec2, inp):
336 if 'full_cr' in inp:
337 full_reg = yield dec2.dec_cr_in.whole_reg.data
338 full_reg_ok = yield dec2.dec_cr_in.whole_reg.ok
339 full_cr_mask = mask_extend(full_reg, 8, 4)
340 yield alu.p.i_data.full_cr.eq(inp['full_cr'] & full_cr_mask)
341 else:
342 yield alu.p.i_data.full_cr.eq(0)
343
344 def get_slow_spr1(res, alu, dec2):
345 spr1_valid = yield alu.n.o_data.spr1.ok
346 if spr1_valid:
347 res['spr1'] = yield alu.n.o_data.spr1.data
348
349 def get_slow_spr2(res, alu, dec2):
350 spr2_valid = yield alu.n.o_data.spr2.ok
351 if spr2_valid:
352 res['spr2'] = yield alu.n.o_data.spr2.data
353
354 def get_fast_spr1(res, alu, dec2):
355 spr1_valid = yield alu.n.o_data.fast1.ok
356 if spr1_valid:
357 res['fast1'] = yield alu.n.o_data.fast1.data
358
359 def get_fast_spr2(res, alu, dec2):
360 spr2_valid = yield alu.n.o_data.fast2.ok
361 if spr2_valid:
362 res['fast2'] = yield alu.n.o_data.fast2.data
363
364 def get_fast_spr3(res, alu, dec2):
365 spr3_valid = yield alu.n.o_data.fast3.ok
366 if spr3_valid:
367 res['fast3'] = yield alu.n.o_data.fast3.data
368
369 def get_cia(res, alu, dec2):
370 res['cia'] = yield alu.p.i_data.cia
371
372 def get_nia(res, alu, dec2):
373 nia_valid = yield alu.n.o_data.nia.ok
374 if nia_valid:
375 res['nia'] = yield alu.n.o_data.nia.data
376
377 def get_msr(res, alu, dec2):
378 msr_valid = yield alu.n.o_data.msr.ok
379 if msr_valid:
380 res['msr'] = yield alu.n.o_data.msr.data
381
382 def get_int_o1(res, alu, dec2):
383 out_reg_valid = yield dec2.e.write_ea.ok
384 if out_reg_valid:
385 res['o1'] = yield alu.n.o_data.o1.data
386
387 def get_int_o(res, alu, dec2):
388 out_reg_valid = yield dec2.e.write_reg.ok
389 if out_reg_valid:
390 res['o'] = yield alu.n.o_data.o.data
391
392 def get_cr_a(res, alu, dec2):
393 cridx_ok = yield dec2.e.write_cr.ok
394 if cridx_ok:
395 res['cr_a'] = yield alu.n.o_data.cr0.data
396
397 def get_xer_so(res, alu, dec2):
398 oe = yield dec2.e.do.oe.oe
399 oe_ok = yield dec2.e.do.oe.ok
400 xer_out = yield dec2.e.xer_out
401 if not (yield alu.n.o_data.xer_so.ok):
402 return
403 if xer_out or (oe and oe_ok):
404 res['xer_so'] = yield alu.n.o_data.xer_so.data[0]
405
406 def get_xer_ov(res, alu, dec2):
407 oe = yield dec2.e.do.oe.oe
408 oe_ok = yield dec2.e.do.oe.ok
409 xer_out = yield dec2.e.xer_out
410 if not (yield alu.n.o_data.xer_ov.ok):
411 return
412 if xer_out or (oe and oe_ok):
413 res['xer_ov'] = yield alu.n.o_data.xer_ov.data
414
415 def get_xer_ca(res, alu, dec2):
416 cry_out = yield dec2.e.do.output_carry
417 xer_out = yield dec2.e.xer_out
418 if not (yield alu.n.o_data.xer_ca.ok):
419 return
420 if xer_out or (cry_out):
421 res['xer_ca'] = yield alu.n.o_data.xer_ca.data
422
423 def get_sim_int_o(res, sim, dec2):
424 out_reg_valid = yield dec2.e.write_reg.ok
425 if out_reg_valid:
426 write_reg_idx = yield dec2.e.write_reg.data
427 res['o'] = sim.gpr(write_reg_idx).value
428
429 def get_sim_int_o1(res, sim, dec2):
430 out_reg_valid = yield dec2.e.write_ea.ok
431 if out_reg_valid:
432 write_reg_idx = yield dec2.e.write_ea.data
433 res['o1'] = sim.gpr(write_reg_idx).value
434
435 def get_wr_sim_cr_a(res, sim, dec2):
436 cridx_ok = yield dec2.e.write_cr.ok
437 if cridx_ok:
438 cridx = yield dec2.e.write_cr.data
439 res['cr_a'] = sim.crl[cridx].get_range().value
440
441 def get_wr_fast_spr3(res, sim, dec2):
442 ok = yield dec2.e.write_fast3.ok
443 if ok:
444 spr_num = yield dec2.e.write_fast3.data
445 spr_num = fast_reg_to_spr(spr_num)
446 spr_name = spr_dict[spr_num].SPR
447 res['fast3'] = sim.spr[spr_name].value
448
449 def get_wr_fast_spr2(res, sim, dec2):
450 ok = yield dec2.e.write_fast2.ok
451 if ok:
452 spr_num = yield dec2.e.write_fast2.data
453 spr_num = fast_reg_to_spr(spr_num)
454 spr_name = spr_dict[spr_num].SPR
455 res['fast2'] = sim.spr[spr_name].value
456
457 def get_wr_fast_spr1(res, sim, dec2):
458 ok = yield dec2.e.write_fast1.ok
459 if ok:
460 spr_num = yield dec2.e.write_fast1.data
461 spr_num = fast_reg_to_spr(spr_num)
462 spr_name = spr_dict[spr_num].SPR
463 res['fast1'] = sim.spr[spr_name].value
464
465 def get_wr_slow_spr1(res, sim, dec2):
466 ok = yield dec2.e.write_spr.ok
467 if ok:
468 spr_num = yield dec2.e.write_spr.data
469 spr_num = slow_reg_to_spr(spr_num)
470 spr_name = spr_dict[spr_num].SPR
471 res['spr1'] = sim.spr[spr_name].value
472
473 def get_wr_sim_xer_ca(res, sim, dec2):
474 # if not (yield alu.n.o_data.xer_ca.ok):
475 # return
476 cry_out = yield dec2.e.do.output_carry
477 xer_out = yield dec2.e.xer_out
478 if cry_out or xer_out:
479 expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
480 expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
481 res['xer_ca'] = expected_carry | (expected_carry32 << 1)
482
483 def get_wr_sim_xer_ov(res, sim, alu, dec2):
484 oe = yield dec2.e.do.oe.oe
485 oe_ok = yield dec2.e.do.oe.ok
486 xer_out = yield dec2.e.xer_out
487 print("get_wr_sim_xer_ov", xer_out)
488 if not (yield alu.n.o_data.xer_ov.ok):
489 return
490 if xer_out or (oe and oe_ok):
491 expected_ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
492 expected_ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
493 res['xer_ov'] = expected_ov | (expected_ov32 << 1)
494
495 def get_wr_sim_xer_so(res, sim, alu, dec2):
496 oe = yield dec2.e.do.oe.oe
497 oe_ok = yield dec2.e.do.oe.ok
498 xer_out = yield dec2.e.xer_out
499 if not (yield alu.n.o_data.xer_so.ok):
500 return
501 if xer_out or (oe and oe_ok):
502 res['xer_so'] = 1 if sim.spr['XER'][XER_bits['SO']] else 0
503
504 def get_sim_xer_ov(res, sim, dec2):
505 oe = yield dec2.e.do.oe.oe
506 oe_ok = yield dec2.e.do.oe.ok
507 xer_in = yield dec2.e.xer_in
508 print("get_sim_xer_ov", xer_in)
509 if (xer_in & (1<<XERRegsEnum.OV)) or (oe and oe_ok):
510 expected_ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
511 expected_ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
512 res['xer_ov'] = expected_ov | (expected_ov32 << 1)
513
514 def get_sim_xer_so(res, sim, dec2):
515 print ("XER", sim.spr.__class__, sim.spr, sim.spr['XER'])
516 oe = yield dec2.e.do.oe.oe
517 oe_ok = yield dec2.e.do.oe.ok
518 xer_in = yield dec2.e.xer_in
519 rc = yield dec2.e.do.rc.rc
520 rc_ok = yield dec2.e.do.rc.ok
521 if (xer_in & (1<<XERRegsEnum.SO)) or (oe and oe_ok) or (rc and rc_ok):
522 res['xer_so'] = 1 if sim.spr['XER'][XER_bits['SO']] else 0
523
524 def check_slow_spr1(dut, res, sim_o, msg):
525 if 'spr1' in res:
526 expected = sim_o['spr1']
527 alu_out = res['spr1']
528 print(f"expected {expected:x}, actual: {alu_out:x}")
529 dut.assertEqual(expected, alu_out, msg)
530
531 def check_fast_spr1(dut, res, sim_o, msg):
532 if 'fast1' in res:
533 expected = sim_o['fast1']
534 alu_out = res['fast1']
535 print(f"expected {expected:x}, actual: {alu_out:x}")
536 dut.assertEqual(expected, alu_out, msg)
537
538 def check_fast_spr2(dut, res, sim_o, msg):
539 if 'fast2' in res:
540 expected = sim_o['fast2']
541 alu_out = res['fast2']
542 print(f"expected {expected:x}, actual: {alu_out:x}")
543 dut.assertEqual(expected, alu_out, msg)
544
545 def check_fast_spr3(dut, res, sim_o, msg):
546 if 'fast3' in res:
547 expected = sim_o['fast3']
548 alu_out = res['fast3']
549 print(f"expected {expected:x}, actual: {alu_out:x}")
550 dut.assertEqual(expected, alu_out, msg)
551
552 def check_int_o1(dut, res, sim_o, msg):
553 if 'o1' in res:
554 expected = sim_o['o1']
555 alu_out = res['o1']
556 print(f"expected {expected:x}, actual: {alu_out:x}")
557 dut.assertEqual(expected, alu_out, msg)
558
559 def check_int_o(dut, res, sim_o, msg):
560 if 'o' in res:
561 expected = sim_o['o']
562 alu_out = res['o']
563 print(f"expected int sim {expected:x}, actual: {alu_out:x}")
564 dut.assertEqual(expected, alu_out, msg)
565
566 def check_msr(dut, res, sim_o, msg):
567 if 'msr' in res:
568 expected = sim_o['msr']
569 alu_out = res['msr']
570 print(f"expected {expected:x}, actual: {alu_out:x}")
571 dut.assertEqual(expected, alu_out, msg)
572
573 def check_nia(dut, res, sim_o, msg):
574 if 'nia' in res:
575 expected = sim_o['nia']
576 alu_out = res['nia']
577 print(f"expected {expected:x}, actual: {alu_out:x}")
578 dut.assertEqual(expected, alu_out, msg)
579
580 def check_cr_a(dut, res, sim_o, msg):
581 if 'cr_a' in res:
582 cr_expected = sim_o['cr_a']
583 cr_actual = res['cr_a']
584 print("CR", cr_expected, cr_actual)
585 dut.assertEqual(cr_expected, cr_actual, msg)
586
587 def check_xer_ca(dut, res, sim_o, msg):
588 if 'xer_ca' in res:
589 ca_expected = sim_o['xer_ca']
590 ca_actual = res['xer_ca']
591 print("CA", ca_expected, ca_actual)
592 dut.assertEqual(ca_expected, ca_actual, msg)
593
594 def check_xer_ov(dut, res, sim_o, msg):
595 if 'xer_ov' in res:
596 ov_expected = sim_o['xer_ov']
597 ov_actual = res['xer_ov']
598 print("OV", ov_expected, ov_actual)
599 dut.assertEqual(ov_expected, ov_actual, msg)
600
601 def check_xer_so(dut, res, sim_o, msg):
602 if 'xer_so' in res:
603 so_expected = sim_o['xer_so']
604 so_actual = res['xer_so']
605 print("SO", so_expected, so_actual)
606 dut.assertEqual(so_expected, so_actual, msg)