3 * https://bugs.libre-soc.org/show_bug.cgi?id=361
10 from openpower
.decoder
.power_enums
import XER_bits
, CryIn
, spr_dict
11 from openpower
.util
import fast_reg_to_spr
, slow_reg_to_spr
# HACK!
12 from openpower
.consts
import XERRegsEnum
15 # TODO: make this a util routine (somewhere)
16 def mask_extend(x
, nbits
, repeat
):
18 extended
= (1<<repeat
)-1
19 for i
in range(nbits
):
21 res |
= extended
<< (i
*repeat
)
25 class SkipCase(Exception):
26 """Raise this exception to skip a test case.
28 Usually you'd use one of the skip_case* decorators.
30 For use with TestAccumulatorBase
35 """identity function"""
39 def skip_case(reason
):
41 Unconditionally skip a test case.
44 @skip_case("my reason for skipping")
52 For use with TestAccumulatorBase
55 assert not isinstance(item
, type), \
56 "can't use skip_case to decorate types"
58 @functools.wraps(item
)
59 def wrapper(*args
, **kwargs
):
60 raise SkipCase(reason
)
62 if isinstance(reason
, types
.FunctionType
):
65 return decorator(item
)
69 def skip_case_if(condition
, reason
):
71 Conditionally skip a test case.
74 @skip_case_if(should_i_skip(), "my reason for skipping")
78 For use with TestAccumulatorBase
81 return skip_case(reason
)
85 class TestAccumulatorBase
:
89 # automatically identifies anything starting with "case_" and
90 # runs it. very similar to unittest auto-identification except
91 # we need a different system
92 for n
, v
in self
.__class
__.__dict
__.items():
93 if n
.startswith("case_") and callable(v
):
97 # TODO(programmerjake): translate to final test sending
98 # skip signal to unittest. for now, just print the skipped
100 print(f
"SKIPPED({n}):", str(e
))
102 def add_case(self
, prog
, initial_regs
=None, initial_sprs
=None,
103 initial_cr
=0, initial_msr
=0,
107 test_name
= inspect
.stack()[1][3] # name of caller of this function
108 tc
= TestCase(prog
, test_name
,
109 regs
=initial_regs
, sprs
=initial_sprs
, cr
=initial_cr
,
112 svstate
=initial_svstate
)
114 self
.test_data
.append(tc
)
118 def __init__(self
, program
, name
, regs
=None, sprs
=None, cr
=0, mem
=None,
121 extra_break_addr
=None,
124 self
.program
= program
139 self
.extra_break_addr
= extra_break_addr
140 self
.svstate
= svstate
145 def get_sim_fast_reg(res
, sim
, dec2
, reg
, name
):
146 spr_sel
= fast_reg_to_spr(reg
)
147 spr_data
= sim
.spr
[spr_sel
].value
150 def get_sim_cia(res
, sim
, dec2
):
151 res
['cia'] = sim
.pc
.CIA
.value
153 # use this *after* the simulation has run a step (it returns CIA)
154 def get_sim_nia(res
, sim
, dec2
):
155 res
['nia'] = sim
.pc
.CIA
.value
157 def get_sim_msr(res
, sim
, dec2
):
158 res
['msr'] = sim
.msr
.value
160 def get_sim_slow_spr1(res
, sim
, dec2
):
161 spr1_en
= yield dec2
.e
.read_spr1
.ok
163 spr1_sel
= yield dec2
.e
.read_spr1
.data
164 spr1_sel
= slow_reg_to_spr(spr1_sel
)
165 spr1_data
= sim
.spr
[spr1_sel
].value
166 res
['spr1'] = spr1_data
168 def get_sim_fast_spr1(res
, sim
, dec2
):
169 fast1_en
= yield dec2
.e
.read_fast1
.ok
171 fast1_sel
= yield dec2
.e
.read_fast1
.data
172 spr1_sel
= fast_reg_to_spr(fast1_sel
)
173 spr1_data
= sim
.spr
[spr1_sel
].value
174 res
['fast1'] = spr1_data
176 def get_sim_fast_spr2(res
, sim
, dec2
):
177 fast2_en
= yield dec2
.e
.read_fast2
.ok
179 fast2_sel
= yield dec2
.e
.read_fast2
.data
180 spr2_sel
= fast_reg_to_spr(fast2_sel
)
181 spr2_data
= sim
.spr
[spr2_sel
].value
182 res
['fast2'] = spr2_data
184 def get_sim_fast_spr3(res
, sim
, dec2
):
185 fast3_en
= yield dec2
.e
.read_fast3
.ok
187 fast3_sel
= yield dec2
.e
.read_fast3
.data
188 spr3_sel
= fast_reg_to_spr(fast3_sel
)
189 spr3_data
= sim
.spr
[spr3_sel
].value
190 res
['fast3'] = spr3_data
192 def get_sim_cr_a(res
, sim
, dec2
):
193 cridx_ok
= yield dec2
.e
.read_cr1
.ok
195 cridx
= yield dec2
.e
.read_cr1
.data
196 res
['cr_a'] = sim
.crl
[cridx
].get_range().value
198 def get_sim_cr_b(res
, sim
, dec2
):
199 cridx_ok
= yield dec2
.e
.read_cr2
.ok
201 cridx
= yield dec2
.e
.read_cr2
.data
202 res
['cr_b'] = sim
.crl
[cridx
].get_range().value
204 def get_sim_cr_c(res
, sim
, dec2
):
205 cridx_ok
= yield dec2
.e
.read_cr3
.ok
207 cridx
= yield dec2
.e
.read_cr3
.data
208 res
['cr_c'] = sim
.crl
[cridx
].get_range().value
210 def get_sim_int_ra(res
, sim
, dec2
):
211 # TODO: immediate RA zero
212 reg1_ok
= yield dec2
.e
.read_reg1
.ok
214 data1
= yield dec2
.e
.read_reg1
.data
215 res
['ra'] = sim
.gpr(data1
).value
217 def get_sim_int_rb(res
, sim
, dec2
):
218 reg2_ok
= yield dec2
.e
.read_reg2
.ok
220 data
= yield dec2
.e
.read_reg2
.data
221 res
['rb'] = sim
.gpr(data
).value
223 def get_sim_int_rc(res
, sim
, dec2
):
224 reg3_ok
= yield dec2
.e
.read_reg3
.ok
226 data
= yield dec2
.e
.read_reg3
.data
227 res
['rc'] = sim
.gpr(data
).value
229 def get_rd_sim_xer_ca(res
, sim
, dec2
):
230 cry_in
= yield dec2
.e
.do
.input_carry
231 xer_in
= yield dec2
.e
.xer_in
232 if (xer_in
& (1<<XERRegsEnum
.CA
)) or cry_in
== CryIn
.CA
.value
:
233 expected_carry
= 1 if sim
.spr
['XER'][XER_bits
['CA']] else 0
234 expected_carry32
= 1 if sim
.spr
['XER'][XER_bits
['CA32']] else 0
235 res
['xer_ca'] = expected_carry |
(expected_carry32
<< 1)
237 def set_int_ra(alu
, dec2
, inp
):
238 # TODO: immediate RA zero.
240 yield alu
.p
.i_data
.ra
.eq(inp
['ra'])
242 yield alu
.p
.i_data
.ra
.eq(0)
244 def set_int_rb(alu
, dec2
, inp
):
245 yield alu
.p
.i_data
.rb
.eq(0)
247 yield alu
.p
.i_data
.rb
.eq(inp
['rb'])
248 if not hasattr(dec2
.e
.do
, "imm_data"):
250 # If there's an immediate, set the B operand to that
251 imm_ok
= yield dec2
.e
.do
.imm_data
.ok
253 data2
= yield dec2
.e
.do
.imm_data
.data
254 yield alu
.p
.i_data
.rb
.eq(data2
)
256 def set_int_rc(alu
, dec2
, inp
):
258 yield alu
.p
.i_data
.rc
.eq(inp
['rc'])
260 yield alu
.p
.i_data
.rc
.eq(0)
262 def set_xer_ca(alu
, dec2
, inp
):
264 yield alu
.p
.i_data
.xer_ca
.eq(inp
['xer_ca'])
265 print("extra inputs: CA/32", bin(inp
['xer_ca']))
267 def set_xer_ov(alu
, dec2
, inp
):
269 yield alu
.p
.i_data
.xer_ov
.eq(inp
['xer_ov'])
270 print("extra inputs: OV/32", bin(inp
['xer_ov']))
272 def set_xer_so(alu
, dec2
, inp
):
275 print("extra inputs: so", so
)
276 yield alu
.p
.i_data
.xer_so
.eq(so
)
278 def set_msr(alu
, dec2
, inp
):
279 print("TODO: deprecate set_msr")
281 yield alu
.p
.i_data
.msr
.eq(inp
['msr'])
283 def set_cia(alu
, dec2
, inp
):
284 print("TODO: deprecate set_cia")
286 yield alu
.p
.i_data
.cia
.eq(inp
['cia'])
288 def set_slow_spr1(alu
, dec2
, inp
):
290 yield alu
.p
.i_data
.spr1
.eq(inp
['spr1'])
292 def set_slow_spr2(alu
, dec2
, inp
):
294 yield alu
.p
.i_data
.spr2
.eq(inp
['spr2'])
296 def set_fast_spr1(alu
, dec2
, inp
):
298 yield alu
.p
.i_data
.fast1
.eq(inp
['fast1'])
300 def set_fast_spr2(alu
, dec2
, inp
):
302 yield alu
.p
.i_data
.fast2
.eq(inp
['fast2'])
304 def set_fast_spr3(alu
, dec2
, inp
):
306 yield alu
.p
.i_data
.fast3
.eq(inp
['fast3'])
308 def set_cr_a(alu
, dec2
, inp
):
310 yield alu
.p
.i_data
.cr_a
.eq(inp
['cr_a'])
312 def set_cr_b(alu
, dec2
, inp
):
314 yield alu
.p
.i_data
.cr_b
.eq(inp
['cr_b'])
316 def set_cr_c(alu
, dec2
, inp
):
318 yield alu
.p
.i_data
.cr_c
.eq(inp
['cr_c'])
320 def set_full_cr(alu
, dec2
, inp
):
322 full_reg
= yield dec2
.dec_cr_in
.whole_reg
.data
323 full_reg_ok
= yield dec2
.dec_cr_in
.whole_reg
.ok
324 full_cr_mask
= mask_extend(full_reg
, 8, 4)
325 yield alu
.p
.i_data
.full_cr
.eq(inp
['full_cr'] & full_cr_mask
)
327 yield alu
.p
.i_data
.full_cr
.eq(0)
329 def get_slow_spr1(res
, alu
, dec2
):
330 spr1_valid
= yield alu
.n
.o_data
.spr1
.ok
332 res
['spr1'] = yield alu
.n
.o_data
.spr1
.data
334 def get_slow_spr2(res
, alu
, dec2
):
335 spr2_valid
= yield alu
.n
.o_data
.spr2
.ok
337 res
['spr2'] = yield alu
.n
.o_data
.spr2
.data
339 def get_fast_spr1(res
, alu
, dec2
):
340 spr1_valid
= yield alu
.n
.o_data
.fast1
.ok
342 res
['fast1'] = yield alu
.n
.o_data
.fast1
.data
344 def get_fast_spr2(res
, alu
, dec2
):
345 spr2_valid
= yield alu
.n
.o_data
.fast2
.ok
347 res
['fast2'] = yield alu
.n
.o_data
.fast2
.data
349 def get_fast_spr3(res
, alu
, dec2
):
350 spr3_valid
= yield alu
.n
.o_data
.fast3
.ok
352 res
['fast3'] = yield alu
.n
.o_data
.fast3
.data
354 def get_cia(res
, alu
, dec2
):
355 res
['cia'] = yield alu
.p
.i_data
.cia
357 def get_nia(res
, alu
, dec2
):
358 nia_valid
= yield alu
.n
.o_data
.nia
.ok
360 res
['nia'] = yield alu
.n
.o_data
.nia
.data
362 def get_msr(res
, alu
, dec2
):
363 msr_valid
= yield alu
.n
.o_data
.msr
.ok
365 res
['msr'] = yield alu
.n
.o_data
.msr
.data
367 def get_int_o1(res
, alu
, dec2
):
368 out_reg_valid
= yield dec2
.e
.write_ea
.ok
370 res
['o1'] = yield alu
.n
.o_data
.o1
.data
372 def get_int_o(res
, alu
, dec2
):
373 out_reg_valid
= yield dec2
.e
.write_reg
.ok
375 res
['o'] = yield alu
.n
.o_data
.o
.data
377 def get_cr_a(res
, alu
, dec2
):
378 cridx_ok
= yield dec2
.e
.write_cr
.ok
380 res
['cr_a'] = yield alu
.n
.o_data
.cr0
.data
382 def get_xer_so(res
, alu
, dec2
):
383 oe
= yield dec2
.e
.do
.oe
.oe
384 oe_ok
= yield dec2
.e
.do
.oe
.ok
385 xer_out
= yield dec2
.e
.xer_out
386 if not (yield alu
.n
.o_data
.xer_so
.ok
):
388 if xer_out
or (oe
and oe_ok
):
389 res
['xer_so'] = yield alu
.n
.o_data
.xer_so
.data
[0]
391 def get_xer_ov(res
, alu
, dec2
):
392 oe
= yield dec2
.e
.do
.oe
.oe
393 oe_ok
= yield dec2
.e
.do
.oe
.ok
394 xer_out
= yield dec2
.e
.xer_out
395 if not (yield alu
.n
.o_data
.xer_ov
.ok
):
397 if xer_out
or (oe
and oe_ok
):
398 res
['xer_ov'] = yield alu
.n
.o_data
.xer_ov
.data
400 def get_xer_ca(res
, alu
, dec2
):
401 cry_out
= yield dec2
.e
.do
.output_carry
402 xer_out
= yield dec2
.e
.xer_out
403 if not (yield alu
.n
.o_data
.xer_ca
.ok
):
405 if xer_out
or (cry_out
):
406 res
['xer_ca'] = yield alu
.n
.o_data
.xer_ca
.data
408 def get_sim_int_o(res
, sim
, dec2
):
409 out_reg_valid
= yield dec2
.e
.write_reg
.ok
411 write_reg_idx
= yield dec2
.e
.write_reg
.data
412 res
['o'] = sim
.gpr(write_reg_idx
).value
414 def get_sim_int_o1(res
, sim
, dec2
):
415 out_reg_valid
= yield dec2
.e
.write_ea
.ok
417 write_reg_idx
= yield dec2
.e
.write_ea
.data
418 res
['o1'] = sim
.gpr(write_reg_idx
).value
420 def get_wr_sim_cr_a(res
, sim
, dec2
):
421 cridx_ok
= yield dec2
.e
.write_cr
.ok
423 cridx
= yield dec2
.e
.write_cr
.data
424 res
['cr_a'] = sim
.crl
[cridx
].get_range().value
426 def get_wr_fast_spr3(res
, sim
, dec2
):
427 ok
= yield dec2
.e
.write_fast3
.ok
429 spr_num
= yield dec2
.e
.write_fast3
.data
430 spr_num
= fast_reg_to_spr(spr_num
)
431 spr_name
= spr_dict
[spr_num
].SPR
432 res
['fast3'] = sim
.spr
[spr_name
].value
434 def get_wr_fast_spr2(res
, sim
, dec2
):
435 ok
= yield dec2
.e
.write_fast2
.ok
437 spr_num
= yield dec2
.e
.write_fast2
.data
438 spr_num
= fast_reg_to_spr(spr_num
)
439 spr_name
= spr_dict
[spr_num
].SPR
440 res
['fast2'] = sim
.spr
[spr_name
].value
442 def get_wr_fast_spr1(res
, sim
, dec2
):
443 ok
= yield dec2
.e
.write_fast1
.ok
445 spr_num
= yield dec2
.e
.write_fast1
.data
446 spr_num
= fast_reg_to_spr(spr_num
)
447 spr_name
= spr_dict
[spr_num
].SPR
448 res
['fast1'] = sim
.spr
[spr_name
].value
450 def get_wr_slow_spr1(res
, sim
, dec2
):
451 ok
= yield dec2
.e
.write_spr
.ok
453 spr_num
= yield dec2
.e
.write_spr
.data
454 spr_num
= slow_reg_to_spr(spr_num
)
455 spr_name
= spr_dict
[spr_num
].SPR
456 res
['spr1'] = sim
.spr
[spr_name
].value
458 def get_wr_sim_xer_ca(res
, sim
, dec2
):
459 # if not (yield alu.n.o_data.xer_ca.ok):
461 cry_out
= yield dec2
.e
.do
.output_carry
462 xer_out
= yield dec2
.e
.xer_out
463 if cry_out
or xer_out
:
464 expected_carry
= 1 if sim
.spr
['XER'][XER_bits
['CA']] else 0
465 expected_carry32
= 1 if sim
.spr
['XER'][XER_bits
['CA32']] else 0
466 res
['xer_ca'] = expected_carry |
(expected_carry32
<< 1)
468 def get_wr_sim_xer_ov(res
, sim
, alu
, dec2
):
469 oe
= yield dec2
.e
.do
.oe
.oe
470 oe_ok
= yield dec2
.e
.do
.oe
.ok
471 xer_out
= yield dec2
.e
.xer_out
472 print("get_wr_sim_xer_ov", xer_out
)
473 if not (yield alu
.n
.o_data
.xer_ov
.ok
):
475 if xer_out
or (oe
and oe_ok
):
476 expected_ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
477 expected_ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
478 res
['xer_ov'] = expected_ov |
(expected_ov32
<< 1)
480 def get_wr_sim_xer_so(res
, sim
, alu
, dec2
):
481 oe
= yield dec2
.e
.do
.oe
.oe
482 oe_ok
= yield dec2
.e
.do
.oe
.ok
483 xer_out
= yield dec2
.e
.xer_out
484 if not (yield alu
.n
.o_data
.xer_so
.ok
):
486 if xer_out
or (oe
and oe_ok
):
487 res
['xer_so'] = 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
489 def get_sim_xer_ov(res
, sim
, dec2
):
490 oe
= yield dec2
.e
.do
.oe
.oe
491 oe_ok
= yield dec2
.e
.do
.oe
.ok
492 xer_in
= yield dec2
.e
.xer_in
493 print("get_sim_xer_ov", xer_in
)
494 if (xer_in
& (1<<XERRegsEnum
.OV
)) or (oe
and oe_ok
):
495 expected_ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
496 expected_ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
497 res
['xer_ov'] = expected_ov |
(expected_ov32
<< 1)
499 def get_sim_xer_so(res
, sim
, dec2
):
500 print ("XER", sim
.spr
.__class
__, sim
.spr
, sim
.spr
['XER'])
501 oe
= yield dec2
.e
.do
.oe
.oe
502 oe_ok
= yield dec2
.e
.do
.oe
.ok
503 xer_in
= yield dec2
.e
.xer_in
504 rc
= yield dec2
.e
.do
.rc
.rc
505 rc_ok
= yield dec2
.e
.do
.rc
.ok
506 if (xer_in
& (1<<XERRegsEnum
.SO
)) or (oe
and oe_ok
) or (rc
and rc_ok
):
507 res
['xer_so'] = 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
509 def check_slow_spr1(dut
, res
, sim_o
, msg
):
511 expected
= sim_o
['spr1']
512 alu_out
= res
['spr1']
513 print(f
"expected {expected:x}, actual: {alu_out:x}")
514 dut
.assertEqual(expected
, alu_out
, msg
)
516 def check_fast_spr1(dut
, res
, sim_o
, msg
):
518 expected
= sim_o
['fast1']
519 alu_out
= res
['fast1']
520 print(f
"expected {expected:x}, actual: {alu_out:x}")
521 dut
.assertEqual(expected
, alu_out
, msg
)
523 def check_fast_spr2(dut
, res
, sim_o
, msg
):
525 expected
= sim_o
['fast2']
526 alu_out
= res
['fast2']
527 print(f
"expected {expected:x}, actual: {alu_out:x}")
528 dut
.assertEqual(expected
, alu_out
, msg
)
530 def check_fast_spr3(dut
, res
, sim_o
, msg
):
532 expected
= sim_o
['fast3']
533 alu_out
= res
['fast3']
534 print(f
"expected {expected:x}, actual: {alu_out:x}")
535 dut
.assertEqual(expected
, alu_out
, msg
)
537 def check_int_o1(dut
, res
, sim_o
, msg
):
539 expected
= sim_o
['o1']
541 print(f
"expected {expected:x}, actual: {alu_out:x}")
542 dut
.assertEqual(expected
, alu_out
, msg
)
544 def check_int_o(dut
, res
, sim_o
, msg
):
546 expected
= sim_o
['o']
548 print(f
"expected int sim {expected:x}, actual: {alu_out:x}")
549 dut
.assertEqual(expected
, alu_out
, msg
)
551 def check_msr(dut
, res
, sim_o
, msg
):
553 expected
= sim_o
['msr']
555 print(f
"expected {expected:x}, actual: {alu_out:x}")
556 dut
.assertEqual(expected
, alu_out
, msg
)
558 def check_nia(dut
, res
, sim_o
, msg
):
560 expected
= sim_o
['nia']
562 print(f
"expected {expected:x}, actual: {alu_out:x}")
563 dut
.assertEqual(expected
, alu_out
, msg
)
565 def check_cr_a(dut
, res
, sim_o
, msg
):
567 cr_expected
= sim_o
['cr_a']
568 cr_actual
= res
['cr_a']
569 print("CR", cr_expected
, cr_actual
)
570 dut
.assertEqual(cr_expected
, cr_actual
, msg
)
572 def check_xer_ca(dut
, res
, sim_o
, msg
):
574 ca_expected
= sim_o
['xer_ca']
575 ca_actual
= res
['xer_ca']
576 print("CA", ca_expected
, ca_actual
)
577 dut
.assertEqual(ca_expected
, ca_actual
, msg
)
579 def check_xer_ov(dut
, res
, sim_o
, msg
):
581 ov_expected
= sim_o
['xer_ov']
582 ov_actual
= res
['xer_ov']
583 print("OV", ov_expected
, ov_actual
)
584 dut
.assertEqual(ov_expected
, ov_actual
, msg
)
586 def check_xer_so(dut
, res
, sim_o
, msg
):
588 so_expected
= sim_o
['xer_so']
589 so_actual
= res
['xer_so']
590 print("SO", so_expected
, so_actual
)
591 dut
.assertEqual(so_expected
, so_actual
, msg
)