1 from nmigen
import Module
, Signal
2 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
3 from nmutil
.formaltest
import FHDLTestCase
5 from openpower
.decoder
.isa
.caller
import ISACaller
6 from openpower
.decoder
.power_decoder
import (create_pdecode
)
7 from openpower
.decoder
.power_decoder2
import (PowerDecode2
)
8 from openpower
.simulator
.program
import Program
9 from openpower
.decoder
.isa
.caller
import ISACaller
, SVP64State
, CRFields
10 from openpower
.decoder
.selectable_int
import SelectableInt
11 from openpower
.decoder
.orderedset
import OrderedSet
12 from openpower
.decoder
.isa
.all
import ISA
13 from openpower
.decoder
.isa
.test_caller
import Register
, run_tst
14 from openpower
.sv
.trans
.svp64
import SVP64Asm
15 from openpower
.consts
import SVP64CROffs
16 from copy
import deepcopy
18 class DecoderTestCase(FHDLTestCase
):
20 def _check_regs(self
, sim
, expected
):
24 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
26 def test_svstep_1(self
):
27 lst
= SVP64Asm(["setvl 0, 0, 10, 1, 1, 1", # actual setvl (VF mode)
28 "setvl 0, 0, 1, 1, 0, 0", # svstep
29 "setvl 0, 0, 1, 1, 0, 0" # svstep
33 # SVSTATE (in this case, VL=4) which is going to get erased by setvl
34 svstate
= SVP64State()
36 svstate
.maxvl
= 4 # MAXVL
37 print ("SVSTATE", bin(svstate
.asint()))
39 with
Program(lst
, bigendian
=False) as program
:
40 sim
= self
.run_tst_program(program
, svstate
=svstate
)
41 print ("SVSTATE after", bin(sim
.svstate
.asint()))
42 print (" vl", bin(sim
.svstate
.vl
))
43 print (" mvl", bin(sim
.svstate
.maxvl
))
44 print (" srcstep", bin(sim
.svstate
.srcstep
))
45 print (" dststep", bin(sim
.svstate
.dststep
))
46 print (" vfirst", bin(sim
.svstate
.vfirst
))
47 self
.assertEqual(sim
.svstate
.vl
, 10)
48 self
.assertEqual(sim
.svstate
.maxvl
, 10)
49 self
.assertEqual(sim
.svstate
.srcstep
, 2)
50 self
.assertEqual(sim
.svstate
.dststep
, 2)
51 self
.assertEqual(sim
.svstate
.vfirst
, 1)
52 print(" gpr1", sim
.gpr(0))
53 self
.assertEqual(sim
.gpr(0), SelectableInt(0, 64))
55 def test_svstep_2(self
):
56 """tests svstep when it reaches VL
58 lst
= SVP64Asm(["setvl 0, 0, 2, 1, 1, 1", # actual setvl (VF mode)
59 "setvl. 0, 0, 1, 1, 0, 0", # svstep (Rc=1)
60 "setvl. 0, 0, 1, 1, 0, 0" # svstep (Rc=1)
64 # SVSTATE (in this case, VL=2)
65 svstate
= SVP64State()
67 svstate
.maxvl
= 2 # MAXVL
68 print ("SVSTATE", bin(svstate
.asint()))
70 with
Program(lst
, bigendian
=False) as program
:
71 sim
= self
.run_tst_program(program
, svstate
=svstate
)
72 print ("SVSTATE after", bin(sim
.svstate
.asint()))
73 print (" vl", bin(sim
.svstate
.vl
))
74 print (" mvl", bin(sim
.svstate
.maxvl
))
75 print (" srcstep", bin(sim
.svstate
.srcstep
))
76 print (" dststep", bin(sim
.svstate
.dststep
))
77 print (" vfirst", bin(sim
.svstate
.vfirst
))
78 self
.assertEqual(sim
.svstate
.vl
, 2)
79 self
.assertEqual(sim
.svstate
.maxvl
, 2)
80 self
.assertEqual(sim
.svstate
.srcstep
, 0)
81 self
.assertEqual(sim
.svstate
.dststep
, 0)
82 # when end reached, vertical mode is exited
83 self
.assertEqual(sim
.svstate
.vfirst
, 0)
84 print(" gpr1", sim
.gpr(0))
85 self
.assertEqual(sim
.gpr(0), SelectableInt(0, 64))
87 print(" CR0", bin(CR0
.get_range().value
))
88 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
89 self
.assertEqual(CR0
[CRFields
.LT
], 0)
90 self
.assertEqual(CR0
[CRFields
.GT
], 0)
91 self
.assertEqual(CR0
[CRFields
.SO
], 1)
93 def test_svstep_3(self
):
94 """tests svstep when it *doesn't* reach VL
96 lst
= SVP64Asm(["setvl 0, 0, 3, 1, 1, 1", # actual setvl (VF mode)
97 "setvl. 0, 0, 1, 1, 0, 0", # svstep (Rc=1)
98 "setvl. 0, 0, 1, 1, 0, 0" # svstep (Rc=1)
102 # SVSTATE (in this case, VL=2)
103 svstate
= SVP64State()
105 svstate
.maxvl
= 2 # MAXVL
106 print ("SVSTATE", bin(svstate
.asint()))
108 with
Program(lst
, bigendian
=False) as program
:
109 sim
= self
.run_tst_program(program
, svstate
=svstate
)
110 print ("SVSTATE after", bin(sim
.svstate
.asint()))
111 print (" vl", bin(sim
.svstate
.vl
))
112 print (" mvl", bin(sim
.svstate
.maxvl
))
113 print (" srcstep", bin(sim
.svstate
.srcstep
))
114 print (" dststep", bin(sim
.svstate
.dststep
))
115 print (" vfirst", bin(sim
.svstate
. vfirst
))
116 self
.assertEqual(sim
.svstate
.vl
, 3)
117 self
.assertEqual(sim
.svstate
.maxvl
, 3)
118 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
119 self
.assertEqual(sim
.svstate
.srcstep
, 2)
120 self
.assertEqual(sim
.svstate
.dststep
, 2)
121 print(" gpr1", sim
.gpr(0))
122 self
.assertEqual(sim
.gpr(0), SelectableInt(0, 64))
123 self
.assertEqual(sim
.svstate
.vfirst
, 1)
125 print(" CR0", bin(CR0
.get_range().value
))
126 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
127 self
.assertEqual(CR0
[CRFields
.LT
], 0)
128 self
.assertEqual(CR0
[CRFields
.GT
], 0)
129 self
.assertEqual(CR0
[CRFields
.SO
], 0)
132 def test_setvl_1(self
):
133 """straight setvl, testing if VL and MVL are over-ridden
135 lst
= SVP64Asm(["setvl 1, 0, 10, 0, 1, 1",
139 # SVSTATE (in this case, VL=2), want to see if these get changed
140 svstate
= SVP64State()
142 svstate
.maxvl
= 2 # MAXVL
143 print ("SVSTATE", bin(svstate
.asint()))
145 with
Program(lst
, bigendian
=False) as program
:
146 sim
= self
.run_tst_program(program
, svstate
=svstate
)
147 print ("SVSTATE after", bin(sim
.svstate
.asint()))
148 print (" vl", bin(sim
.svstate
.vl
))
149 print (" mvl", bin(sim
.svstate
.maxvl
))
150 self
.assertEqual(sim
.svstate
.vl
, 10)
151 self
.assertEqual(sim
.svstate
.maxvl
, 10)
152 self
.assertEqual(sim
.svstate
.maxvl
, 10)
153 print(" gpr1", sim
.gpr(1))
154 self
.assertEqual(sim
.gpr(1), SelectableInt(10, 64))
156 def test_svstep_inner_loop_6(self
):
157 """tests svstep inner loop, running 6 times, looking for "k"
160 # set triple butterfly mode with persistent "REMAP"
161 "svshape 8, 1, 1, 1, 1",
162 "svremap 31, 1, 0, 2, 0, 1, 1",
163 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
164 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
165 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
166 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
167 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
168 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
173 svstate
= SVP64State()
175 #svstate.maxvl = 2 # MAXVL
176 print ("SVSTATE", bin(svstate
.asint()))
178 with
Program(lst
, bigendian
=False) as program
:
179 sim
= self
.run_tst_program(program
, svstate
=svstate
)
180 print ("SVSTATE after", bin(sim
.svstate
.asint()))
181 print (" vl", bin(sim
.svstate
.vl
))
182 print (" mvl", bin(sim
.svstate
.maxvl
))
183 print (" srcstep", bin(sim
.svstate
.srcstep
))
184 print (" dststep", bin(sim
.svstate
.dststep
))
185 print (" vfirst", bin(sim
.svstate
. vfirst
))
186 self
.assertEqual(sim
.svstate
.vl
, 12)
187 self
.assertEqual(sim
.svstate
.maxvl
, 12)
188 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
189 self
.assertEqual(sim
.svstate
.srcstep
, 6)
190 self
.assertEqual(sim
.svstate
.dststep
, 6)
191 self
.assertEqual(sim
.gpr(0), SelectableInt(0, 64))
192 self
.assertEqual(sim
.svstate
.vfirst
, 1)
194 print(" CR0", bin(CR0
.get_range().value
))
195 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
196 self
.assertEqual(CR0
[CRFields
.LT
], 1)
197 self
.assertEqual(CR0
[CRFields
.GT
], 1)
198 self
.assertEqual(CR0
[CRFields
.SO
], 0)
200 def test_svstep_inner_loop_3(self
):
201 """tests svstep inner loop, running 3 times
204 # set triple butterfly mode with persistent "REMAP"
205 "svshape 8, 1, 1, 1, 1",
206 "svremap 31, 1, 0, 2, 0, 1, 1",
207 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
208 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
209 "setvl. 0, 0, 2, 1, 0, 0", # svstep (Rc=1)
214 svstate
= SVP64State()
216 #svstate.maxvl = 2 # MAXVL
217 print ("SVSTATE", bin(svstate
.asint()))
219 with
Program(lst
, bigendian
=False) as program
:
220 sim
= self
.run_tst_program(program
, svstate
=svstate
)
221 print ("SVSTATE after", bin(sim
.svstate
.asint()))
222 print (" vl", bin(sim
.svstate
.vl
))
223 print (" mvl", bin(sim
.svstate
.maxvl
))
224 print (" srcstep", bin(sim
.svstate
.srcstep
))
225 print (" dststep", bin(sim
.svstate
.dststep
))
226 print (" vfirst", bin(sim
.svstate
. vfirst
))
227 self
.assertEqual(sim
.svstate
.vl
, 12)
228 self
.assertEqual(sim
.svstate
.maxvl
, 12)
229 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
230 self
.assertEqual(sim
.svstate
.srcstep
, 3)
231 self
.assertEqual(sim
.svstate
.dststep
, 3)
232 self
.assertEqual(sim
.gpr(0), SelectableInt(0, 64))
233 self
.assertEqual(sim
.svstate
.vfirst
, 1)
235 print(" CR0", bin(CR0
.get_range().value
))
236 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
237 self
.assertEqual(CR0
[CRFields
.LT
], 1)
238 self
.assertEqual(CR0
[CRFields
.GT
], 1)
239 self
.assertEqual(CR0
[CRFields
.SO
], 0)
241 def test_svstep_inner_loop_4(self
):
242 """tests svstep inner loop, running 4 times
245 # set triple butterfly mode with persistent "REMAP"
246 "svshape 8, 1, 1, 1, 1",
247 "svremap 31, 1, 0, 2, 0, 1, 1",
248 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
249 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
250 "setvl. 0, 0, 2, 1, 0, 0", # svstep (Rc=1)
251 "setvl. 0, 0, 2, 1, 0, 0", # svstep (Rc=1)
256 svstate
= SVP64State()
258 #svstate.maxvl = 2 # MAXVL
259 print ("SVSTATE", bin(svstate
.asint()))
261 with
Program(lst
, bigendian
=False) as program
:
262 sim
= self
.run_tst_program(program
, svstate
=svstate
)
263 print ("SVSTATE after", bin(sim
.svstate
.asint()))
264 print (" vl", bin(sim
.svstate
.vl
))
265 print (" mvl", bin(sim
.svstate
.maxvl
))
266 print (" srcstep", bin(sim
.svstate
.srcstep
))
267 print (" dststep", bin(sim
.svstate
.dststep
))
268 print (" vfirst", bin(sim
.svstate
. vfirst
))
269 self
.assertEqual(sim
.svstate
.vl
, 12)
270 self
.assertEqual(sim
.svstate
.maxvl
, 12)
271 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
272 self
.assertEqual(sim
.svstate
.srcstep
, 4)
273 self
.assertEqual(sim
.svstate
.dststep
, 4)
274 self
.assertEqual(sim
.gpr(0), SelectableInt(0, 64))
275 self
.assertEqual(sim
.svstate
.vfirst
, 1)
277 print(" CR0", bin(CR0
.get_range().value
))
278 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
279 self
.assertEqual(CR0
[CRFields
.LT
], 1)
280 self
.assertEqual(CR0
[CRFields
.GT
], 0)
281 self
.assertEqual(CR0
[CRFields
.SO
], 0)
283 def test_sv_add(self
):
284 """sets VL=2 then adds:
285 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
286 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
288 isa
= SVP64Asm(["setvl 3, 0, 2, 0, 1, 1",
289 'sv.add 1.v, 5.v, 9.v'
292 print ("listing", lst
)
294 # initial values in GPR regfile
295 initial_regs
= [0] * 32
296 initial_regs
[9] = 0x1234
297 initial_regs
[10] = 0x1111
298 initial_regs
[5] = 0x4321
299 initial_regs
[6] = 0x2223
301 # copy before running
302 expected_regs
= deepcopy(initial_regs
)
303 expected_regs
[1] = 0x5555
304 expected_regs
[2] = 0x3334
305 expected_regs
[3] = 2 # setvl places copy of VL here
307 with
Program(lst
, bigendian
=False) as program
:
308 sim
= self
.run_tst_program(program
, initial_regs
)
309 self
._check
_regs
(sim
, expected_regs
)
311 def test_svstep_add_1(self
):
312 """tests svstep with an add, when it reaches VL
313 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
314 'sv.add 1.v, 5.v, 9.v',
315 "setvl. 0, 0, 1, 1, 0, 0",
316 'sv.add 1.v, 5.v, 9.v',
317 "setvl. 0, 0, 1, 1, 0, 0"
319 sequence is as follows:
320 * setvl sets VL=2 but also "Vertical First" mode.
322 * first add, which has srcstep/dststep = 0, does add 1,5,9
323 * svstep EXPLICITLY walks srcstep/dststep to next element
324 * second add, which now has srcstep/dststep = 1, does add 2,6,10
325 * svstep EXPLICITLY walks srcstep/dststep to next element,
326 which now equals VL. srcstep and dststep are both set to
327 zero, and MSR[SVF] is cleared.
329 lst
= SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
330 'sv.add 1.v, 5.v, 9.v',
331 "setvl. 0, 0, 1, 1, 0, 0", # svstep
332 'sv.add 1.v, 5.v, 9.v',
333 "setvl. 0, 0, 1, 1, 0, 0" # svstep
337 # SVSTATE (in this case, VL=2)
338 svstate
= SVP64State()
340 svstate
.maxvl
= 2 # MAXVL
341 print ("SVSTATE", bin(svstate
.asint()))
343 # initial values in GPR regfile
344 initial_regs
= [0] * 32
345 initial_regs
[9] = 0x1234
346 initial_regs
[10] = 0x1111
347 initial_regs
[5] = 0x4321
348 initial_regs
[6] = 0x2223
350 # copy before running
351 expected_regs
= deepcopy(initial_regs
)
352 expected_regs
[1] = 0x5555
353 expected_regs
[2] = 0x3334
354 expected_regs
[3] = 2 # setvl places copy of VL here
356 with
Program(lst
, bigendian
=False) as program
:
357 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
358 print ("SVSTATE after", bin(sim
.svstate
.asint()))
359 print (" vl", bin(sim
.svstate
.vl
))
360 print (" mvl", bin(sim
.svstate
.maxvl
))
361 print (" srcstep", bin(sim
.svstate
.srcstep
))
362 print (" dststep", bin(sim
.svstate
.dststep
))
363 print (" vfirst", bin(sim
.svstate
. vfirst
))
364 self
.assertEqual(sim
.svstate
.vl
, 2)
365 self
.assertEqual(sim
.svstate
.maxvl
, 2)
366 self
.assertEqual(sim
.svstate
.srcstep
, 0)
367 self
.assertEqual(sim
.svstate
.dststep
, 0)
368 # when end reached, vertical mode is exited
369 self
.assertEqual(sim
.svstate
.vfirst
, 0)
371 print(" CR0", bin(CR0
.get_range().value
))
372 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
373 self
.assertEqual(CR0
[CRFields
.LT
], 0)
374 self
.assertEqual(CR0
[CRFields
.GT
], 0)
375 self
.assertEqual(CR0
[CRFields
.SO
], 1)
377 # check registers as expected
378 self
._check
_regs
(sim
, expected_regs
)
380 def test_svstep_add_2(self
):
381 """tests svstep with a branch.
382 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
383 'sv.add 1.v, 5.v, 9.v',
384 "setvl. 0, 0, 1, 1, 0, 0",
387 sequence is as follows:
388 * setvl sets VL=2 but also "Vertical First" mode.
390 * first time add, which has srcstep/dststep = 0, does add 1,5,9
391 * svstep EXPLICITLY walks srcstep/dststep to next element,
392 not yet met VL, so CR0.EQ is set to zero
393 * branch conditional checks bne on CR0, jumps back TWELVE bytes
394 because whilst branch is 32-bit the sv.add is 64-bit
395 * second time add, which now has srcstep/dststep = 1, does add 2,6,10
396 * svstep walks to next element, meets VL, so:
397 - srcstep and dststep set to zero
399 - MSR[SVF] is cleared
400 * branch conditional detects CR0.EQ=1 and FAILs the condition,
403 we therefore have an explicit "Vertical-First" system which can
404 have **MULTIPLE* instructions inside a loop, running each element 0
405 first, then looping back and running all element 1, then all element 2
408 lst
= SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
409 'sv.add 1.v, 5.v, 9.v',
410 "setvl. 0, 0, 1, 1, 0, 0", # svstep - this is 64-bit!
411 "bc 6, 3, -0xc" # branch to add (64-bit op so -0xc!)
415 # SVSTATE (in this case, VL=2)
416 svstate
= SVP64State()
418 svstate
.maxvl
= 2 # MAXVL
419 print ("SVSTATE", bin(svstate
.asint()))
421 # initial values in GPR regfile
422 initial_regs
= [0] * 32
423 initial_regs
[9] = 0x1234
424 initial_regs
[10] = 0x1111
425 initial_regs
[5] = 0x4321
426 initial_regs
[6] = 0x2223
428 # copy before running
429 expected_regs
= deepcopy(initial_regs
)
430 expected_regs
[1] = 0x5555
431 expected_regs
[2] = 0x3334
432 expected_regs
[3] = 2 # setvl places copy of VL here
434 with
Program(lst
, bigendian
=False) as program
:
435 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
436 print ("SVSTATE after", bin(sim
.svstate
.asint()))
437 print (" vl", bin(sim
.svstate
.vl
))
438 print (" mvl", bin(sim
.svstate
.maxvl
))
439 print (" srcstep", bin(sim
.svstate
.srcstep
))
440 print (" dststep", bin(sim
.svstate
.dststep
))
441 print (" vfirst", bin(sim
.svstate
. vfirst
))
442 self
.assertEqual(sim
.svstate
.vl
, 2)
443 self
.assertEqual(sim
.svstate
.maxvl
, 2)
444 self
.assertEqual(sim
.svstate
.srcstep
, 0)
445 self
.assertEqual(sim
.svstate
.dststep
, 0)
446 # when end reached, vertical mode is exited
447 self
.assertEqual(sim
.svstate
.vfirst
, 0)
449 print(" CR0", bin(CR0
.get_range().value
))
450 self
.assertEqual(CR0
[CRFields
.EQ
], 0)
451 self
.assertEqual(CR0
[CRFields
.LT
], 0)
452 self
.assertEqual(CR0
[CRFields
.GT
], 0)
453 self
.assertEqual(CR0
[CRFields
.SO
], 1)
455 # check registers as expected
456 self
._check
_regs
(sim
, expected_regs
)
458 def test_svremap(self
):
459 """svremap, see if values get set
461 lst
= SVP64Asm(["svremap 11, 0, 1, 2, 3, 3, 1",
465 with
Program(lst
, bigendian
=False) as program
:
466 sim
= self
.run_tst_program(program
)
467 svstate
= sim
.svstate
468 print ("SVREMAP after", bin(svstate
.value
))
469 print (" men", bin(svstate
.SVme
))
470 print (" mi0", bin(svstate
.mi0
))
471 print (" mi1", bin(svstate
.mi1
))
472 print (" mi2", bin(svstate
.mi2
))
473 print (" mo0", bin(svstate
.mo0
))
474 print (" mo1", bin(svstate
.mo1
))
475 print (" persist", bin(svstate
.RMpst
))
476 self
.assertEqual(svstate
.SVme
, 11)
477 self
.assertEqual(svstate
.mi0
, 0)
478 self
.assertEqual(svstate
.mi1
, 1)
479 self
.assertEqual(svstate
.mi2
, 2)
480 self
.assertEqual(svstate
.mo0
, 3)
481 self
.assertEqual(svstate
.mo1
, 3)
482 self
.assertEqual(svstate
.RMpst
, 1)
484 def run_tst_program(self
, prog
, initial_regs
=None,
486 if initial_regs
is None:
487 initial_regs
= [0] * 32
488 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
)
493 if __name__
== "__main__":