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
)
46 def setup_for_test(self
):
48 def setup_during_test(self
):
50 def prepare_for_test(self
, test
):
60 class SimRunner(StateRunner
):
61 def __init__(self
, dut
, **kwargs
):
62 super().__init
__("sim", SimRunner
)
63 self
.pspec
= kwargs
['pspec']
69 yield from self
.get_intregs()
70 yield from self
.get_crregs()
71 yield from self
.get_xregs()
72 yield from self
.get_pc()
73 yield from self
.get_mem()
75 def compare(self
, s2
):
76 # Compare int registers
77 for i
, (self
.intregs
, s2
.intregs
) in enumerate(
78 zip(self
.intregs
, s2
.intregs
)):
79 log("asserting...reg", i
, self
.intregs
, s2
.intregs
)
80 log("code, frepr(code)", self
.code
, repr(self
.code
))
81 self
.dut
.assertEqual(self
.intregs
, s2
.intregs
,
82 "int reg %d (%s) not equal (%s) %s. got %x expected %x" %
83 (i
, self
.state_type
, s2
.state_type
, repr(self
.code
),
84 self
.intregs
, s2
.intregs
))
87 for i
, (self
.crregs
, s2
.crregs
) in enumerate(
88 zip(self
.crregs
, s2
.crregs
)):
89 log("asserting...cr", i
, self
.crregs
, s2
.crregs
)
90 self
.dut
.assertEqual(self
.crregs
, s2
.crregs
,
91 "cr reg %d (%s) not equal (%s) %s. got %x expected %x" %
92 (i
, self
.state_type
, s2
.state_type
, repr(self
.code
),
93 self
.crregs
, s2
.crregs
))
96 self
.dut
.assertEqual(self
.so
, s2
.so
, "so mismatch (%s != %s) %s" %
97 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
98 self
.dut
.assertEqual(self
.ov
, s2
.ov
, "ov mismatch (%s != %s) %s" %
99 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
100 self
.dut
.assertEqual(self
.ca
, s2
.ca
, "ca mismatch (%s != %s) %s" %
101 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
104 self
.dut
.assertEqual(self
.pc
, s2
.pc
, "pc mismatch (%s != %s) %s" %
105 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
107 def compare_mem(self
, s2
):
108 # copy dics to preserve state mem then pad empty locs
109 s1mem
, s2mem
= self
.mem
.copy(), s2
.mem
.copy()
110 for i
in set(self
.mem
).difference(set(s2
.mem
)):
112 for i
in set(s2
.mem
).difference(set(self
.mem
)):
115 self
.dut
.assertEqual(s1mem
[i
], s2mem
[i
],
116 "mem mismatch location %d %s" % (i
, self
.code
))
119 class SimState(State
):
120 def __init__(self
, sim
):
123 def get_intregs(self
):
128 simregval
= self
.sim
.gpr
[i
].asint()
129 self
.intregs
.append(simregval
)
130 log("class sim int regs", list(map(hex, self
.intregs
)))
132 def get_crregs(self
):
137 cri
= self
.sim
.crl
[7 - i
].get_range().value
138 self
.crregs
.append(cri
)
139 log("class sim cr regs", list(map(hex, self
.crregs
)))
145 self
.so
= self
.sim
.spr
['XER'][XER_bits
['SO']].value
146 self
.ov
= self
.sim
.spr
['XER'][XER_bits
['OV']].value
147 self
.ov32
= self
.sim
.spr
['XER'][XER_bits
['OV32']].value
148 self
.ca
= self
.sim
.spr
['XER'][XER_bits
['CA']].value
149 self
.ca32
= self
.sim
.spr
['XER'][XER_bits
['CA32']].value
150 self
.ov
= self
.ov |
(self
.ov32
<< 1)
151 self
.ca
= self
.ca |
(self
.ca32
<< 1)
152 self
.xregs
.extend((self
.so
, self
.ov
, self
.ca
))
153 log("class sim xregs", list(map(hex, self
.xregs
)))
159 self
.pc
= self
.sim
.pc
.CIA
.value
160 self
.pcl
.append(self
.pc
)
161 log("class sim pc", hex(self
.pc
))
166 keys
= list(self
.sim
.mem
.mem
.keys())
168 # from each address in the underlying mem-simulated dictionary
169 # issue a 64-bit LD (with no byte-swapping)
171 data
= self
.sim
.mem
.ld(k
*8, 8, False)
175 class ExpectedState(State
):
176 def __init__(self
, int_regs
=None, pc
=0, crregs
=None,
180 if isinstance(int_regs
, int):
181 int_regs
= [0] * int_regs
182 self
.intregs
= int_regs
186 if isinstance(crregs
, int):
187 crregs
= [0] * crregs
193 def get_intregs(self
):
195 def get_crregs(self
):
206 state_factory
= {'sim': SimState
, 'expected': ExpectedState
}
209 def state_add(name
, kls
):
210 log("state_add", name
, kls
)
211 state_factory
[name
] = kls
214 def TestState(state_type
, to_test
, dut
, code
=0):
215 state_class
= state_factory
[state_type
]
216 state
= state_class(to_test
)
217 state
.to_test
= to_test
219 state
.state_type
= state_type
221 yield from state
.get_state()
225 def teststate_check_regs(dut
, states
, test
, code
):
226 """teststate_check_regs: compares a set of Power ISA objects
227 to check if they have the same "state" (registers only, at the moment)
230 # create one TestState per "thing"
231 for stype
, totest
in states
.items():
232 state
= yield from TestState(stype
, totest
, dut
, code
)
234 # compare each "thing" against the next "thing" in the list.
235 # (no need to do an O(N^2) comparison here, they *all* have to be the same
236 for i
in range(len(slist
)-1):
237 state
, against
= slist
[i
], slist
[i
+1]
238 state
.compare(against
)
241 def teststate_check_mem(dut
, states
, test
, code
):
242 """teststate_check_mem: compares a set of Power ISA objects
243 to check if they have the same "state" (memory)
246 # create one TestState per "thing"
247 for stype
, totest
in states
.items():
248 state
= yield from TestState(stype
, totest
, dut
, code
)
250 # compare each "thing" against the next "thing" in the list.
251 # (no need to do an O(N^2) comparison here, they *all* have to be the same
252 for i
in range(len(slist
)-1):
253 state
, against
= slist
[i
], slist
[i
+1]
254 state
.compare_mem(against
)