3 * https://bugs.libre-soc.org/show_bug.cgi?id=361
6 from contextlib
import contextmanager
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
, DEFAULT_MSR
18 # TODO: make this a util routine (somewhere)
19 def mask_extend(x
, nbits
, repeat
):
21 extended
= (1<<repeat
)-1
22 for i
in range(nbits
):
24 res |
= extended
<< (i
*repeat
)
28 class SkipCase(Exception):
29 """Raise this exception to skip a test case.
31 Usually you'd use one of the skip_case* decorators.
33 For use with TestAccumulatorBase
38 """identity function"""
42 def skip_case(reason
):
44 Unconditionally skip a test case.
47 @skip_case("my reason for skipping")
55 For use with TestAccumulatorBase
58 assert not isinstance(item
, type), \
59 "can't use skip_case to decorate types"
61 @functools.wraps(item
)
62 def wrapper(*args
, **kwargs
):
63 raise SkipCase(reason
)
65 if isinstance(reason
, types
.FunctionType
):
68 return decorator(item
)
72 def skip_case_if(condition
, reason
):
74 Conditionally skip a test case.
77 @skip_case_if(should_i_skip(), "my reason for skipping")
81 For use with TestAccumulatorBase
84 return skip_case(reason
)
88 class TestAccumulatorBase
:
89 __test__
= False # pytest should ignore this class
92 self
.__subtest
_args
= {}
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
):
102 except SkipCase
as e
:
103 # TODO(programmerjake): translate to final test sending
104 # skip signal to unittest. for now, just print the skipped
106 log(f
"SKIPPED({n}):", str(e
), kind
=LogKind
.SkipCase
)
109 def subTest(self
, **kwargs
):
110 old_subtest_args
= self
.__subtest
_args
112 self
.__subtest
_args
= old_subtest_args
.copy()
113 self
.__subtest
_args
.update(**kwargs
)
116 self
.__subtest
_args
= old_subtest_args
118 def add_case(self
, prog
, initial_regs
=None, initial_sprs
=None,
119 initial_cr
=0, initial_msr
=DEFAULT_MSR
,
128 c
= sys
._getframe
(1 + src_loc_at
).f_code
129 # name of caller of this function
130 test_name
= c
.co_name
131 # name of file containing test case
132 test_file
= os
.path
.splitext(os
.path
.basename(c
.co_filename
))[0]
133 tc
= TestCase(prog
, test_name
,
134 regs
=initial_regs
, sprs
=initial_sprs
, cr
=initial_cr
,
137 svstate
=initial_svstate
,
139 stop_at_pc
=stop_at_pc
,
141 subtest_args
=self
.__subtest
_args
.copy(),
143 initial_fpscr
=initial_fpscr
)
145 self
.test_data
.append(tc
)
149 __test__
= False # pytest should ignore this class
151 def __init__(self
, program
, name
, regs
=None, sprs
=None, cr
=0, mem
=None,
154 extra_break_addr
=None,
163 self
.program
= program
181 self
.extra_break_addr
= extra_break_addr
182 self
.svstate
= svstate
183 self
.expected
= expected
# expected results from the test
184 self
.stop_at_pc
= stop_at_pc
# hard-stop address (do not attempt to run)
185 self
.test_file
= test_file
186 self
.subtest_args
= {} if subtest_args
is None else dict(subtest_args
)
187 if initial_fpscr
is None:
189 self
.initial_fpscr
= initial_fpscr
194 def get_sim_fast_reg(res
, sim
, dec2
, reg
, name
):
195 spr_sel
= fast_reg_to_spr(reg
)
196 spr_data
= sim
.spr
[spr_sel
].value
199 def get_sim_cia(res
, sim
, dec2
):
200 res
['cia'] = sim
.pc
.CIA
.value
202 # use this *after* the simulation has run a step (it returns CIA)
203 def get_sim_nia(res
, sim
, dec2
):
204 res
['nia'] = sim
.pc
.CIA
.value
206 def get_sim_msr(res
, sim
, dec2
):
207 res
['msr'] = sim
.msr
.value
209 def get_sim_slow_spr1(res
, sim
, dec2
):
210 spr1_en
= yield dec2
.e
.read_spr1
.ok
212 spr1_sel
= yield dec2
.e
.read_spr1
.data
213 spr1_sel
= slow_reg_to_spr(spr1_sel
)
214 spr1_data
= sim
.spr
[spr1_sel
].value
215 res
['spr1'] = spr1_data
217 def get_sim_fast_spr1(res
, sim
, dec2
):
218 fast1_en
= yield dec2
.e
.read_fast1
.ok
220 fast1_sel
= yield dec2
.e
.read_fast1
.data
221 spr1_sel
= fast_reg_to_spr(fast1_sel
)
222 spr1_data
= sim
.spr
[spr1_sel
].value
223 res
['fast1'] = spr1_data
225 def get_sim_fast_spr2(res
, sim
, dec2
):
226 fast2_en
= yield dec2
.e
.read_fast2
.ok
228 fast2_sel
= yield dec2
.e
.read_fast2
.data
229 spr2_sel
= fast_reg_to_spr(fast2_sel
)
230 spr2_data
= sim
.spr
[spr2_sel
].value
231 res
['fast2'] = spr2_data
233 def get_sim_fast_spr3(res
, sim
, dec2
):
234 fast3_en
= yield dec2
.e
.read_fast3
.ok
236 fast3_sel
= yield dec2
.e
.read_fast3
.data
237 spr3_sel
= fast_reg_to_spr(fast3_sel
)
238 spr3_data
= sim
.spr
[spr3_sel
].value
239 res
['fast3'] = spr3_data
241 def get_sim_cr_a(res
, sim
, dec2
):
242 cridx_ok
= yield dec2
.e
.read_cr1
.ok
244 cridx
= yield dec2
.e
.read_cr1
.data
245 res
['cr_a'] = sim
.crl
[cridx
].get_range().value
247 def get_sim_cr_b(res
, sim
, dec2
):
248 cridx_ok
= yield dec2
.e
.read_cr2
.ok
250 cridx
= yield dec2
.e
.read_cr2
.data
251 res
['cr_b'] = sim
.crl
[cridx
].get_range().value
253 def get_sim_cr_c(res
, sim
, dec2
):
254 cridx_ok
= yield dec2
.e
.read_cr3
.ok
256 cridx
= yield dec2
.e
.read_cr3
.data
257 res
['cr_c'] = sim
.crl
[cridx
].get_range().value
259 def get_sim_int_ra(res
, sim
, dec2
):
260 # TODO: immediate RA zero
261 reg1_ok
= yield dec2
.e
.read_reg1
.ok
263 data1
= yield dec2
.e
.read_reg1
.data
264 res
['ra'] = sim
.gpr(data1
).value
266 def get_sim_int_rb(res
, sim
, dec2
):
267 reg2_ok
= yield dec2
.e
.read_reg2
.ok
269 data
= yield dec2
.e
.read_reg2
.data
270 res
['rb'] = sim
.gpr(data
).value
272 def get_sim_int_rc(res
, sim
, dec2
):
273 reg3_ok
= yield dec2
.e
.read_reg3
.ok
275 data
= yield dec2
.e
.read_reg3
.data
276 res
['rc'] = sim
.gpr(data
).value
278 def get_rd_sim_xer_ca(res
, sim
, dec2
):
279 cry_in
= yield dec2
.e
.do
.input_carry
280 xer_in
= yield dec2
.e
.xer_in
281 if (xer_in
& (1<<XERRegsEnum
.CA
)) or cry_in
== CryIn
.CA
.value
:
282 expected_carry
= 1 if sim
.spr
['XER'][XER_bits
['CA']] else 0
283 expected_carry32
= 1 if sim
.spr
['XER'][XER_bits
['CA32']] else 0
284 res
['xer_ca'] = expected_carry |
(expected_carry32
<< 1)
286 def set_int_ra(alu
, dec2
, inp
):
287 # TODO: immediate RA zero.
289 yield alu
.p
.i_data
.ra
.eq(inp
['ra'])
291 yield alu
.p
.i_data
.ra
.eq(0)
293 def set_int_rb(alu
, dec2
, inp
):
294 yield alu
.p
.i_data
.rb
.eq(0)
296 yield alu
.p
.i_data
.rb
.eq(inp
['rb'])
297 if not hasattr(dec2
.e
.do
, "imm_data"):
299 # If there's an immediate, set the B operand to that
300 imm_ok
= yield dec2
.e
.do
.imm_data
.ok
302 data2
= yield dec2
.e
.do
.imm_data
.data
303 yield alu
.p
.i_data
.rb
.eq(data2
)
305 def set_int_rc(alu
, dec2
, inp
):
307 yield alu
.p
.i_data
.rc
.eq(inp
['rc'])
309 yield alu
.p
.i_data
.rc
.eq(0)
311 def set_xer_ca(alu
, dec2
, inp
):
313 yield alu
.p
.i_data
.xer_ca
.eq(inp
['xer_ca'])
314 print("extra inputs: CA/32", bin(inp
['xer_ca']))
316 def set_xer_ov(alu
, dec2
, inp
):
318 yield alu
.p
.i_data
.xer_ov
.eq(inp
['xer_ov'])
319 print("extra inputs: OV/32", bin(inp
['xer_ov']))
321 def set_xer_so(alu
, dec2
, inp
):
324 print("extra inputs: so", so
)
325 yield alu
.p
.i_data
.xer_so
.eq(so
)
327 def set_msr(alu
, dec2
, inp
):
328 print("TODO: deprecate set_msr")
330 yield alu
.p
.i_data
.msr
.eq(inp
['msr'])
332 def set_cia(alu
, dec2
, inp
):
333 print("TODO: deprecate set_cia")
335 yield alu
.p
.i_data
.cia
.eq(inp
['cia'])
337 def set_slow_spr1(alu
, dec2
, inp
):
339 yield alu
.p
.i_data
.spr1
.eq(inp
['spr1'])
341 def set_slow_spr2(alu
, dec2
, inp
):
343 yield alu
.p
.i_data
.spr2
.eq(inp
['spr2'])
345 def set_fast_spr1(alu
, dec2
, inp
):
347 yield alu
.p
.i_data
.fast1
.eq(inp
['fast1'])
349 def set_fast_spr2(alu
, dec2
, inp
):
351 yield alu
.p
.i_data
.fast2
.eq(inp
['fast2'])
353 def set_fast_spr3(alu
, dec2
, inp
):
355 yield alu
.p
.i_data
.fast3
.eq(inp
['fast3'])
357 def set_cr_a(alu
, dec2
, inp
):
359 yield alu
.p
.i_data
.cr_a
.eq(inp
['cr_a'])
361 def set_cr_b(alu
, dec2
, inp
):
363 yield alu
.p
.i_data
.cr_b
.eq(inp
['cr_b'])
365 def set_cr_c(alu
, dec2
, inp
):
367 yield alu
.p
.i_data
.cr_c
.eq(inp
['cr_c'])
369 def set_full_cr(alu
, dec2
, inp
):
371 full_reg
= yield dec2
.dec_cr_in
.whole_reg
.data
372 full_reg_ok
= yield dec2
.dec_cr_in
.whole_reg
.ok
373 full_cr_mask
= mask_extend(full_reg
, 8, 4)
374 yield alu
.p
.i_data
.full_cr
.eq(inp
['full_cr'] & full_cr_mask
)
376 yield alu
.p
.i_data
.full_cr
.eq(0)
378 def get_slow_spr1(res
, alu
, dec2
):
379 spr1_valid
= yield alu
.n
.o_data
.spr1
.ok
381 res
['spr1'] = yield alu
.n
.o_data
.spr1
.data
383 def get_slow_spr2(res
, alu
, dec2
):
384 spr2_valid
= yield alu
.n
.o_data
.spr2
.ok
386 res
['spr2'] = yield alu
.n
.o_data
.spr2
.data
388 def get_fast_spr1(res
, alu
, dec2
):
389 spr1_valid
= yield alu
.n
.o_data
.fast1
.ok
391 res
['fast1'] = yield alu
.n
.o_data
.fast1
.data
393 def get_fast_spr2(res
, alu
, dec2
):
394 spr2_valid
= yield alu
.n
.o_data
.fast2
.ok
396 res
['fast2'] = yield alu
.n
.o_data
.fast2
.data
398 def get_fast_spr3(res
, alu
, dec2
):
399 spr3_valid
= yield alu
.n
.o_data
.fast3
.ok
401 res
['fast3'] = yield alu
.n
.o_data
.fast3
.data
403 def get_cia(res
, alu
, dec2
):
404 res
['cia'] = yield alu
.p
.i_data
.cia
406 def get_nia(res
, alu
, dec2
):
407 nia_valid
= yield alu
.n
.o_data
.nia
.ok
409 res
['nia'] = yield alu
.n
.o_data
.nia
.data
411 def get_msr(res
, alu
, dec2
):
412 msr_valid
= yield alu
.n
.o_data
.msr
.ok
414 res
['msr'] = yield alu
.n
.o_data
.msr
.data
416 def get_int_o1(res
, alu
, dec2
):
417 out_reg_valid
= yield dec2
.e
.write_ea
.ok
419 res
['o1'] = yield alu
.n
.o_data
.o1
.data
421 def get_int_o(res
, alu
, dec2
):
422 out_reg_valid
= yield dec2
.e
.write_reg
.ok
424 res
['o'] = yield alu
.n
.o_data
.o
.data
426 def get_cr_a(res
, alu
, dec2
):
427 cridx_ok
= yield dec2
.e
.write_cr
.ok
429 res
['cr_a'] = yield alu
.n
.o_data
.cr0
.data
431 def get_xer_so(res
, alu
, dec2
):
432 oe
= yield dec2
.e
.do
.oe
.oe
433 oe_ok
= yield dec2
.e
.do
.oe
.ok
434 xer_out
= yield dec2
.e
.xer_out
435 if not (yield alu
.n
.o_data
.xer_so
.ok
):
437 if xer_out
or (oe
and oe_ok
):
438 res
['xer_so'] = yield alu
.n
.o_data
.xer_so
.data
[0]
440 def get_xer_ov(res
, alu
, dec2
):
441 oe
= yield dec2
.e
.do
.oe
.oe
442 oe_ok
= yield dec2
.e
.do
.oe
.ok
443 xer_out
= yield dec2
.e
.xer_out
444 if not (yield alu
.n
.o_data
.xer_ov
.ok
):
446 if xer_out
or (oe
and oe_ok
):
447 res
['xer_ov'] = yield alu
.n
.o_data
.xer_ov
.data
449 def get_xer_ca(res
, alu
, dec2
):
450 cry_out
= yield dec2
.e
.do
.output_carry
451 xer_out
= yield dec2
.e
.xer_out
452 if not (yield alu
.n
.o_data
.xer_ca
.ok
):
454 if xer_out
or (cry_out
):
455 res
['xer_ca'] = yield alu
.n
.o_data
.xer_ca
.data
457 def get_sim_int_o(res
, sim
, dec2
):
458 out_reg_valid
= yield dec2
.e
.write_reg
.ok
460 write_reg_idx
= yield dec2
.e
.write_reg
.data
461 res
['o'] = sim
.gpr(write_reg_idx
).value
463 def get_sim_int_o1(res
, sim
, dec2
):
464 out_reg_valid
= yield dec2
.e
.write_ea
.ok
466 write_reg_idx
= yield dec2
.e
.write_ea
.data
467 res
['o1'] = sim
.gpr(write_reg_idx
).value
469 def get_wr_sim_cr_a(res
, sim
, dec2
):
470 cridx_ok
= yield dec2
.e
.write_cr
.ok
472 cridx
= yield dec2
.e
.write_cr
.data
473 res
['cr_a'] = sim
.crl
[cridx
].get_range().value
475 def get_wr_fast_spr3(res
, sim
, dec2
):
476 ok
= yield dec2
.e
.write_fast3
.ok
478 spr_num
= yield dec2
.e
.write_fast3
.data
479 spr_num
= fast_reg_to_spr(spr_num
)
480 spr_name
= spr_dict
[spr_num
].SPR
481 res
['fast3'] = sim
.spr
[spr_name
].value
483 def get_wr_fast_spr2(res
, sim
, dec2
):
484 ok
= yield dec2
.e
.write_fast2
.ok
486 spr_num
= yield dec2
.e
.write_fast2
.data
487 spr_num
= fast_reg_to_spr(spr_num
)
488 spr_name
= spr_dict
[spr_num
].SPR
489 res
['fast2'] = sim
.spr
[spr_name
].value
491 def get_wr_fast_spr1(res
, sim
, dec2
):
492 ok
= yield dec2
.e
.write_fast1
.ok
494 spr_num
= yield dec2
.e
.write_fast1
.data
495 spr_num
= fast_reg_to_spr(spr_num
)
496 spr_name
= spr_dict
[spr_num
].SPR
497 res
['fast1'] = sim
.spr
[spr_name
].value
499 def get_wr_slow_spr1(res
, sim
, dec2
):
500 ok
= yield dec2
.e
.write_spr
.ok
502 spr_num
= yield dec2
.e
.write_spr
.data
503 spr_num
= slow_reg_to_spr(spr_num
)
504 spr_name
= spr_dict
[spr_num
].SPR
505 res
['spr1'] = sim
.spr
[spr_name
].value
507 def get_wr_sim_xer_ca(res
, sim
, dec2
):
508 # if not (yield alu.n.o_data.xer_ca.ok):
510 cry_out
= yield dec2
.e
.do
.output_carry
511 xer_out
= yield dec2
.e
.xer_out
512 if cry_out
or xer_out
:
513 expected_carry
= 1 if sim
.spr
['XER'][XER_bits
['CA']] else 0
514 expected_carry32
= 1 if sim
.spr
['XER'][XER_bits
['CA32']] else 0
515 res
['xer_ca'] = expected_carry |
(expected_carry32
<< 1)
517 def get_wr_sim_xer_ov(res
, sim
, alu
, dec2
):
518 oe
= yield dec2
.e
.do
.oe
.oe
519 oe_ok
= yield dec2
.e
.do
.oe
.ok
520 xer_out
= yield dec2
.e
.xer_out
521 print("get_wr_sim_xer_ov", xer_out
)
522 if not (yield alu
.n
.o_data
.xer_ov
.ok
):
524 if xer_out
or (oe
and oe_ok
):
525 expected_ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
526 expected_ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
527 res
['xer_ov'] = expected_ov |
(expected_ov32
<< 1)
529 def get_wr_sim_xer_so(res
, sim
, alu
, dec2
):
530 oe
= yield dec2
.e
.do
.oe
.oe
531 oe_ok
= yield dec2
.e
.do
.oe
.ok
532 xer_out
= yield dec2
.e
.xer_out
533 if not (yield alu
.n
.o_data
.xer_so
.ok
):
535 if xer_out
or (oe
and oe_ok
):
536 res
['xer_so'] = 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
538 def get_sim_xer_ov(res
, sim
, dec2
):
539 oe
= yield dec2
.e
.do
.oe
.oe
540 oe_ok
= yield dec2
.e
.do
.oe
.ok
541 xer_in
= yield dec2
.e
.xer_in
542 print("get_sim_xer_ov", xer_in
)
543 if (xer_in
& (1<<XERRegsEnum
.OV
)) or (oe
and oe_ok
):
544 expected_ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
545 expected_ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
546 res
['xer_ov'] = expected_ov |
(expected_ov32
<< 1)
548 def get_sim_xer_so(res
, sim
, dec2
):
549 print ("XER", sim
.spr
.__class
__, sim
.spr
, sim
.spr
['XER'])
550 oe
= yield dec2
.e
.do
.oe
.oe
551 oe_ok
= yield dec2
.e
.do
.oe
.ok
552 xer_in
= yield dec2
.e
.xer_in
553 rc
= yield dec2
.e
.do
.rc
.rc
554 rc_ok
= yield dec2
.e
.do
.rc
.ok
555 if (xer_in
& (1<<XERRegsEnum
.SO
)) or (oe
and oe_ok
) or (rc
and rc_ok
):
556 res
['xer_so'] = 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
558 def check_slow_spr1(dut
, res
, sim_o
, msg
):
560 expected
= sim_o
['spr1']
561 alu_out
= res
['spr1']
562 print(f
"expected {expected:x}, actual: {alu_out:x}")
563 dut
.assertEqual(expected
, alu_out
, msg
)
565 def check_fast_spr1(dut
, res
, sim_o
, msg
):
567 expected
= sim_o
['fast1']
568 alu_out
= res
['fast1']
569 print(f
"expected {expected:x}, actual: {alu_out:x}")
570 dut
.assertEqual(expected
, alu_out
, msg
)
572 def check_fast_spr2(dut
, res
, sim_o
, msg
):
574 expected
= sim_o
['fast2']
575 alu_out
= res
['fast2']
576 print(f
"expected {expected:x}, actual: {alu_out:x}")
577 dut
.assertEqual(expected
, alu_out
, msg
)
579 def check_fast_spr3(dut
, res
, sim_o
, msg
):
581 expected
= sim_o
['fast3']
582 alu_out
= res
['fast3']
583 print(f
"expected {expected:x}, actual: {alu_out:x}")
584 dut
.assertEqual(expected
, alu_out
, msg
)
586 def check_int_o1(dut
, res
, sim_o
, msg
):
588 expected
= sim_o
['o1']
590 print(f
"expected {expected:x}, actual: {alu_out:x}")
591 dut
.assertEqual(expected
, alu_out
, msg
)
593 def check_int_o(dut
, res
, sim_o
, msg
):
595 expected
= sim_o
['o']
597 print(f
"expected int sim {expected:x}, actual: {alu_out:x}")
598 dut
.assertEqual(expected
, alu_out
, msg
)
600 def check_msr(dut
, res
, sim_o
, msg
):
602 expected
= sim_o
['msr']
604 print(f
"expected {expected:x}, actual: {alu_out:x}")
605 dut
.assertEqual(expected
, alu_out
, msg
)
607 def check_nia(dut
, res
, sim_o
, msg
):
609 expected
= sim_o
['nia']
611 print(f
"expected {expected:x}, actual: {alu_out:x}")
612 dut
.assertEqual(expected
, alu_out
, msg
)
614 def check_cr_a(dut
, res
, sim_o
, msg
):
616 cr_expected
= sim_o
['cr_a']
617 cr_actual
= res
['cr_a']
618 print("CR", cr_expected
, cr_actual
)
619 dut
.assertEqual(cr_expected
, cr_actual
, msg
)
621 def check_xer_ca(dut
, res
, sim_o
, msg
):
623 ca_expected
= sim_o
['xer_ca']
624 ca_actual
= res
['xer_ca']
625 print("CA", ca_expected
, ca_actual
)
626 dut
.assertEqual(ca_expected
, ca_actual
, msg
)
628 def check_xer_ov(dut
, res
, sim_o
, msg
):
630 ov_expected
= sim_o
['xer_ov']
631 ov_actual
= res
['xer_ov']
632 print("OV", ov_expected
, ov_actual
)
633 dut
.assertEqual(ov_expected
, ov_actual
, msg
)
635 def check_xer_so(dut
, res
, sim_o
, msg
):
637 so_expected
= sim_o
['xer_so']
638 so_actual
= res
['xer_so']
639 print("SO", so_expected
, so_actual
)
640 dut
.assertEqual(so_expected
, so_actual
, msg
)