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