3 This module implements the creation, inspection and comparison
4 of test states from different sources.
6 The basic premise is to create a test state using the TestState method.
7 The TestState method returns a test state object initialized with a
8 basic set of registers pulled from the 'to_test' object. The
9 state created can then be tested against other test states using the
12 The SimState class provides an example of needed registers and naming.
14 The TestState method relies on the 'state_factory' dictionary for lookup
15 of associated test class creation. The dictionary can be added to using
18 Also note when creating and accessing test state classes and object
19 methods, the use of yield from/yield is required.
25 from openpower
.decoder
.power_enums
import XER_bits
26 from openpower
.util
import log
28 global staterunner_factory
29 staterunner_factory
= {}
32 def staterunner_add(name
, kls
):
33 log("staterunner_add", name
, kls
)
34 staterunner_factory
[name
] = kls
38 # TBD an Abstract Base Class
40 """StateRunner: an Abstract Base Class for preparing and running "State".
41 near-identical in concept to python unittest.TestCase
43 def __init__(self
, name
, kls
):
44 staterunner_add(name
, kls
)
47 def setup_for_test(self
):
49 def setup_during_test(self
):
51 def prepare_for_test(self
, test
):
61 class SimRunner(StateRunner
):
62 def __init__(self
, dut
, **kwargs
):
63 super().__init
__("sim", SimRunner
)
64 self
.pspec
= kwargs
['pspec']
70 yield from self
.get_intregs()
71 yield from self
.get_crregs()
72 yield from self
.get_xregs()
73 yield from self
.get_pc()
74 yield from self
.get_mem()
76 def compare(self
, s2
):
77 # Compare int registers
78 for i
, (self
.intregs
, s2
.intregs
) in enumerate(
79 zip(self
.intregs
, s2
.intregs
)):
80 log("asserting...reg", i
, self
.intregs
, s2
.intregs
)
81 log("code, frepr(code)", self
.code
, repr(self
.code
))
82 self
.dut
.assertEqual(self
.intregs
, s2
.intregs
,
83 "int reg %d (%s) not equal (%s) %s. got %x expected %x" %
84 (i
, self
.state_type
, s2
.state_type
, repr(self
.code
),
85 self
.intregs
, s2
.intregs
))
88 for i
, (self
.crregs
, s2
.crregs
) in enumerate(
89 zip(self
.crregs
, s2
.crregs
)):
90 log("asserting...cr", i
, self
.crregs
, s2
.crregs
)
91 self
.dut
.assertEqual(self
.crregs
, s2
.crregs
,
92 "cr reg %d (%s) not equal (%s) %s. got %x expected %x" %
93 (i
, self
.state_type
, s2
.state_type
, repr(self
.code
),
94 self
.crregs
, s2
.crregs
))
97 self
.dut
.assertEqual(self
.so
, s2
.so
, "so mismatch (%s != %s) %s" %
98 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
99 self
.dut
.assertEqual(self
.ov
, s2
.ov
, "ov mismatch (%s != %s) %s" %
100 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
101 self
.dut
.assertEqual(self
.ca
, s2
.ca
, "ca mismatch (%s != %s) %s" %
102 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
105 self
.dut
.assertEqual(self
.pc
, s2
.pc
, "pc mismatch (%s != %s) %s" %
106 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
108 def compare_mem(self
, s2
):
109 # copy dics to preserve state mem then pad empty locs
110 s1mem
, s2mem
= self
.mem
.copy(), s2
.mem
.copy()
111 for i
in set(self
.mem
).difference(set(s2
.mem
)):
113 for i
in set(s2
.mem
).difference(set(self
.mem
)):
116 self
.dut
.assertEqual(s1mem
[i
], s2mem
[i
],
117 "mem mismatch location %d %s" % (i
, self
.code
))
120 class SimState(State
):
121 def __init__(self
, sim
):
124 def get_intregs(self
):
129 simregval
= self
.sim
.gpr
[i
].asint()
130 self
.intregs
.append(simregval
)
131 log("class sim int regs", list(map(hex, self
.intregs
)))
133 def get_crregs(self
):
138 cri
= self
.sim
.crl
[7 - i
].get_range().value
139 self
.crregs
.append(cri
)
140 log("class sim cr regs", list(map(hex, self
.crregs
)))
146 self
.so
= self
.sim
.spr
['XER'][XER_bits
['SO']].value
147 self
.ov
= self
.sim
.spr
['XER'][XER_bits
['OV']].value
148 self
.ov32
= self
.sim
.spr
['XER'][XER_bits
['OV32']].value
149 self
.ca
= self
.sim
.spr
['XER'][XER_bits
['CA']].value
150 self
.ca32
= self
.sim
.spr
['XER'][XER_bits
['CA32']].value
151 self
.ov
= self
.ov |
(self
.ov32
<< 1)
152 self
.ca
= self
.ca |
(self
.ca32
<< 1)
153 self
.xregs
.extend((self
.so
, self
.ov
, self
.ca
))
154 log("class sim xregs", list(map(hex, self
.xregs
)))
160 self
.pc
= self
.sim
.pc
.CIA
.value
161 self
.pcl
.append(self
.pc
)
162 log("class sim pc", hex(self
.pc
))
167 keys
= list(self
.sim
.mem
.mem
.keys())
169 # from each address in the underlying mem-simulated dictionary
170 # issue a 64-bit LD (with no byte-swapping)
172 data
= self
.sim
.mem
.ld(k
*8, 8, False)
176 class ExpectedState(State
):
177 def __init__(self
, int_regs
=None, pc
=0, crregs
=None,
181 if isinstance(int_regs
, int):
182 int_regs
= [0] * int_regs
183 self
.intregs
= int_regs
187 if isinstance(crregs
, int):
188 crregs
= [0] * crregs
194 def get_intregs(self
):
196 def get_crregs(self
):
207 state_factory
= {'sim': SimState
, 'expected': ExpectedState
}
210 def state_add(name
, kls
):
211 log("state_add", name
, kls
)
212 state_factory
[name
] = kls
215 def TestState(state_type
, to_test
, dut
, code
=0):
216 state_class
= state_factory
[state_type
]
217 state
= state_class(to_test
)
218 state
.to_test
= to_test
220 state
.state_type
= state_type
222 yield from state
.get_state()
226 def teststate_check_regs(dut
, states
, test
, code
):
227 """teststate_check_regs: compares a set of Power ISA objects
228 to check if they have the same "state" (registers only, at the moment)
231 # create one TestState per "thing"
232 for stype
, totest
in states
.items():
233 state
= yield from TestState(stype
, totest
, dut
, code
)
235 # compare each "thing" against the next "thing" in the list.
236 # (no need to do an O(N^2) comparison here, they *all* have to be the same
237 for i
in range(len(slist
)-1):
238 state
, against
= slist
[i
], slist
[i
+1]
239 state
.compare(against
)
242 def teststate_check_mem(dut
, states
, test
, code
):
243 """teststate_check_mem: compares a set of Power ISA objects
244 to check if they have the same "state" (memory)
247 # create one TestState per "thing"
248 for stype
, totest
in states
.items():
249 state
= yield from TestState(stype
, totest
, dut
, code
)
251 # compare each "thing" against the next "thing" in the list.
252 # (no need to do an O(N^2) comparison here, they *all* have to be the same
253 for i
in range(len(slist
)-1):
254 state
, against
= slist
[i
], slist
[i
+1]
255 state
.compare_mem(against
)