1 from nmigen
import Module
, Signal
2 from nmigen
.sim
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
):
22 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
24 def tst_sv_load_store(self
):
25 lst
= SVP64Asm(["addi 1, 0, 0x0010",
33 # SVSTATE (in this case, VL=2)
34 svstate
= SVP64State()
36 svstate
.maxvl
= 2 # MAXVL
37 print ("SVSTATE", bin(svstate
.asint()))
39 with
Program(lst
, bigendian
=False) as program
:
40 sim
= self
.run_tst_program(program
, svstate
=svstate
)
42 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1234, 64))
43 self
.assertEqual(sim
.gpr(10), SelectableInt(0x1235, 64))
45 def test_sv_extsw_intpred(self
):
46 # extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
47 # works as follows, where any zeros indicate "skip element"
48 # - sources are 9 and 10
50 # - source mask says "pick first element from source (5)
51 # - dest mask says "pick *second* element from dest (10)
53 # therefore the operation that's carried out is:
54 # GPR(10) = extsb(GPR(5))
56 # this is a type of back-to-back VREDUCE and VEXPAND but it applies
57 # to *operations*, not just MVs like in traditional Vector ISAs
60 # reg num 0 1 2 3 4 5 6 7 8 9 10
67 isa
= SVP64Asm(['sv.extsb/sm=~r3/dm=r3 *5, *9'
70 print ("listing", lst
)
72 # initial values in GPR regfile
73 initial_regs
= [0] * 32
74 initial_regs
[3] = 0b10 # predicate mask
75 initial_regs
[9] = 0x91 # source ~r3 is 0b01 so this will be used
76 initial_regs
[10] = 0x90 # this gets skipped
77 # SVSTATE (in this case, VL=2)
78 svstate
= SVP64State()
80 svstate
.maxvl
= 2 # MAXVL
81 print ("SVSTATE", bin(svstate
.asint()))
83 expected_regs
= deepcopy(initial_regs
)
84 expected_regs
[5] = 0x0 # dest r3 is 0b10: skip
85 expected_regs
[6] = 0xffff_ffff_ffff_ff91 # 2nd bit of r3 is 1
87 with
Program(lst
, bigendian
=False) as program
:
88 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
89 self
._check
_regs
(sim
, expected_regs
)
91 def test_sv_extsw_intpred_dz(self
):
92 # extsb, integer twin-pred mask: dest is r3 (0b01), zeroing on dest
93 isa
= SVP64Asm(['sv.extsb/dm=r3/dz *5, *9'
96 print ("listing", lst
)
98 # initial values in GPR regfile
99 initial_regs
= [0] * 32
100 initial_regs
[3] = 0b01 # predicate mask (dest)
101 initial_regs
[5] = 0xfeed # going to be overwritten
102 initial_regs
[6] = 0xbeef # going to be overwritten (with zero)
103 initial_regs
[9] = 0x91 # dest r3 is 0b01 so this will be used
104 initial_regs
[10] = 0x90 # this gets read but the output gets zero'd
105 # SVSTATE (in this case, VL=2)
106 svstate
= SVP64State()
108 svstate
.maxvl
= 2 # MAXVL
109 print ("SVSTATE", bin(svstate
.asint()))
110 # copy before running
111 expected_regs
= deepcopy(initial_regs
)
112 expected_regs
[5] = 0xffff_ffff_ffff_ff91 # dest r3 is 0b01: store
113 expected_regs
[6] = 0 # 2nd bit of r3 is 1: zero
115 with
Program(lst
, bigendian
=False) as program
:
116 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
117 self
._check
_regs
(sim
, expected_regs
)
119 def test_sv_add_intpred(self
):
120 # adds, integer predicated mask r3=0b10
121 # 1 = 5 + 9 => not to be touched (skipped)
122 # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
123 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
124 # src r3=0b10 N Y N Y
126 # +-------+ | add + |
127 # | +-------+ add --+
130 isa
= SVP64Asm(['sv.add/m=r3 *1, *5, *9'
133 print ("listing", lst
)
135 # initial values in GPR regfile
136 initial_regs
= [0] * 32
137 initial_regs
[1] = 0xbeef # not to be altered
138 initial_regs
[3] = 0b10 # predicate mask
139 initial_regs
[9] = 0x1234
140 initial_regs
[10] = 0x1111
141 initial_regs
[5] = 0x4321
142 initial_regs
[6] = 0x2223
143 # SVSTATE (in this case, VL=2)
144 svstate
= SVP64State()
146 svstate
.maxvl
= 2 # MAXVL
147 print ("SVSTATE", bin(svstate
.asint()))
148 # copy before running
149 expected_regs
= deepcopy(initial_regs
)
150 expected_regs
[1] = 0xbeef
151 expected_regs
[2] = 0x3334
153 with
Program(lst
, bigendian
=False) as program
:
154 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
155 self
._check
_regs
(sim
, expected_regs
)
157 def test_sv_add_cr_pred(self
):
158 # adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
159 # 1 = 5 + 9 => not to be touched (skipped)
160 # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
161 isa
= SVP64Asm(['sv.add/m=ne *1, *5, *9'
164 print ("listing", lst
)
166 # initial values in GPR regfile
167 initial_regs
= [0] * 32
168 initial_regs
[1] = 0xbeef # not to be altered
169 initial_regs
[9] = 0x1234
170 initial_regs
[10] = 0x1111
171 initial_regs
[5] = 0x4321
172 initial_regs
[6] = 0x2223
173 # SVSTATE (in this case, VL=2)
174 svstate
= SVP64State()
176 svstate
.maxvl
= 2 # MAXVL
177 print ("SVSTATE", bin(svstate
.asint()))
178 # copy before running
179 expected_regs
= deepcopy(initial_regs
)
180 expected_regs
[1] = 0xbeef
181 expected_regs
[2] = 0x3334
183 # set up CR predicate - CR4.eq=1 and CR5.eq=0
184 cr
= (0b0010) << ((7-4)*4) # CR4.eq (we hope)
186 with
Program(lst
, bigendian
=False) as program
:
187 sim
= self
.run_tst_program(program
, initial_regs
, svstate
,
189 self
._check
_regs
(sim
, expected_regs
)
191 def test_intpred_vcompress(self
):
192 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
200 isa
= SVP64Asm(['sv.extsb/sm=r3 *5, *9'])
202 print("listing", lst
)
204 # initial values in GPR regfile
205 initial_regs
= [0] * 32
206 initial_regs
[3] = 0b101 # predicate mask
207 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
208 initial_regs
[10] = 0x91 # this gets skipped
209 initial_regs
[11] = 0x92 # source r3 is 0b101 so this will be used
210 # SVSTATE (in this case, VL=3)
211 svstate
= SVP64State()
213 svstate
.maxvl
= 3 # MAXVL
214 print("SVSTATE", bin(svstate
.asint()))
215 # copy before running
216 expected_regs
= deepcopy(initial_regs
)
217 expected_regs
[5] = 0xffff_ffff_ffff_ff90 # (from r9)
218 expected_regs
[6] = 0xffff_ffff_ffff_ff92 # (from r11)
219 expected_regs
[7] = 0x0 # (VL loop runs out before we can use it)
221 with
Program(lst
, bigendian
=False) as program
:
222 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
223 self
._check
_regs
(sim
, expected_regs
)
225 def test_intpred_vexpand(self
):
226 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
232 # dest r3=0b101 Y N Y
234 isa
= SVP64Asm(['sv.extsb/dm=r3 *5, *9'])
236 print("listing", lst
)
238 # initial values in GPR regfile
239 initial_regs
= [0] * 32
240 initial_regs
[3] = 0b101 # predicate mask
241 initial_regs
[9] = 0x90 # source is "always", so this will be used
242 initial_regs
[10] = 0x91 # likewise
243 initial_regs
[11] = 0x92 # the VL loop runs out before we can use it
244 # SVSTATE (in this case, VL=3)
245 svstate
= SVP64State()
247 svstate
.maxvl
= 3 # MAXVL
248 print("SVSTATE", bin(svstate
.asint()))
249 # copy before running
250 expected_regs
= deepcopy(initial_regs
)
251 expected_regs
[5] = 0xffff_ffff_ffff_ff90 # 1st bit of r3 is 1
252 expected_regs
[6] = 0x0 # skip
253 expected_regs
[7] = 0xffff_ffff_ffff_ff91 # 3nd bit of r3 is 1
255 with
Program(lst
, bigendian
=False) as program
:
256 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
257 self
._check
_regs
(sim
, expected_regs
)
259 def test_intpred_twinpred(self
):
260 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
265 # dest ~r3=0b010 N Y N
267 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 *5, *9'])
269 print("listing", lst
)
271 # initial values in GPR regfile
272 initial_regs
= [0] * 32
273 initial_regs
[3] = 0b101 # predicate mask
274 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
275 initial_regs
[10] = 0x91 # this gets skipped
276 initial_regs
[11] = 0x92 # VL loop runs out before we can use it
277 # SVSTATE (in this case, VL=3)
278 svstate
= SVP64State()
280 svstate
.maxvl
= 3 # MAXVL
281 print("SVSTATE", bin(svstate
.asint()))
282 # copy before running
283 expected_regs
= deepcopy(initial_regs
)
284 expected_regs
[5] = 0x0 # dest ~r3 is 0b010: skip
285 expected_regs
[6] = 0xffff_ffff_ffff_ff90 # 2nd bit of ~r3 is 1
286 expected_regs
[7] = 0x0 # dest ~r3 is 0b010: skip
288 with
Program(lst
, bigendian
=False) as program
:
289 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
290 self
._check
_regs
(sim
, expected_regs
)
292 # checks that we are able to resume in the middle of a VL loop,
293 # after an interrupt, or after the user has updated src/dst step
294 # let's assume the user has prepared src/dst step before running this
296 def test_intpred_reentrant(self
):
297 # reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
299 # src r3=0b0101 Y N Y N
304 # dest ~r3=0b1010 N Y N Y
307 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 *5, *9'])
309 print("listing", lst
)
311 # initial values in GPR regfile
312 initial_regs
= [0] * 32
313 initial_regs
[3] = 0b0101 # mask
314 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
315 initial_regs
[10] = 0x91 # skip
316 initial_regs
[11] = 0x92 # this will be used
317 initial_regs
[12] = 0x93 # skip
319 # SVSTATE (in this case, VL=4)
320 svstate
= SVP64State()
322 svstate
.maxvl
= 4 # MAXVL
323 # set src/dest step on the middle of the loop
326 print("SVSTATE", bin(svstate
.asint()))
327 # copy before running
328 expected_regs
= deepcopy(initial_regs
)
329 expected_regs
[5] = 0x0 # skip
330 expected_regs
[6] = 0x0 # dststep starts at 3, so this gets skipped
331 expected_regs
[7] = 0x0 # skip
332 expected_regs
[8] = 0xffff_ffff_ffff_ff92 # this will be used
334 with
Program(lst
, bigendian
=False) as program
:
335 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
336 self
._check
_regs
(sim
, expected_regs
)
338 def test_shift_one_by_r3_dest(self
):
339 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
340 # src r30=0b100 N N Y
344 # dest r3=1: 1<<r3=0b010 N Y N
346 isa
= SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 *5, *9'])
348 print("listing", lst
)
350 # initial values in GPR regfile
351 initial_regs
= [0] * 32
352 initial_regs
[3] = 1 # dest mask = 1<<r3 = 0b010
353 initial_regs
[30] = 0b100 # source mask
354 initial_regs
[9] = 0x90 # skipped
355 initial_regs
[10] = 0x91 # skipped
356 initial_regs
[11] = 0x92 # 3rd bit of r30 is 1
357 # SVSTATE (in this case, VL=3)
358 svstate
= SVP64State()
360 svstate
.maxvl
= 3 # MAXVL
361 print("SVSTATE", bin(svstate
.asint()))
362 # copy before running
363 expected_regs
= deepcopy(initial_regs
)
364 expected_regs
[5] = 0x0 # skip
365 expected_regs
[6] = 0xffff_ffff_ffff_ff92 # r3 is 1, so this is used
366 expected_regs
[7] = 0x0 # skip
368 with
Program(lst
, bigendian
=False) as program
:
369 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
370 self
._check
_regs
(sim
, expected_regs
)
372 def test_shift_one_by_r3_source(self
):
373 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
374 # src r3=2: 1<<r3=0b100 N N Y
378 # dest r30=0b010 N Y N
380 isa
= SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 *5, *9'])
382 print("listing", lst
)
384 # initial values in GPR regfile
385 initial_regs
= [0] * 32
386 initial_regs
[3] = 2 # source mask = 1<<r3 = 0b100
387 initial_regs
[30] = 0b010 # dest mask
388 initial_regs
[9] = 0x90 # skipped
389 initial_regs
[10] = 0x91 # skipped
390 initial_regs
[11] = 0x92 # r3 is 2, so this will be used
391 # SVSTATE (in this case, VL=3)
392 svstate
= SVP64State()
394 svstate
.maxvl
= 3 # MAXVL
395 print("SVSTATE", bin(svstate
.asint()))
396 # copy before running
397 expected_regs
= deepcopy(initial_regs
)
398 expected_regs
[5] = 0x0 # skip
399 expected_regs
[6] = 0xffff_ffff_ffff_ff92 # 2nd bit of r30 is 1
400 expected_regs
[7] = 0x0 # skip
402 with
Program(lst
, bigendian
=False) as program
:
403 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
404 self
._check
_regs
(sim
, expected_regs
)
406 # checks reentrant CR predication
407 def test_crpred_reentrant(self
):
408 # reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
410 # src cr4.eq=1 Y N Y N
418 isa
= SVP64Asm(['sv.extsb/sm=eq/dm=lt *5, *9'])
420 print("listing", lst
)
422 # initial values in GPR regfile
423 initial_regs
= [0] * 32
424 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
425 initial_regs
[10] = 0x91 # skip
426 initial_regs
[11] = 0x92 # this will be used
427 initial_regs
[12] = 0x93 # skip
430 # set up CR predicate
431 # CR4.eq=1 and CR6.eq=1
432 cr
.crl
[4][CRFields
.EQ
] = 1
433 cr
.crl
[6][CRFields
.EQ
] = 1
434 # CR5.lt=1 and CR7.lt=1
435 cr
.crl
[5][CRFields
.LT
] = 1
436 cr
.crl
[7][CRFields
.LT
] = 1
437 # SVSTATE (in this case, VL=4)
438 svstate
= SVP64State()
440 svstate
.maxvl
= 4 # MAXVL
441 # set src/dest step on the middle of the loop
444 print("SVSTATE", bin(svstate
.asint()))
445 # copy before running
446 expected_regs
= deepcopy(initial_regs
)
447 expected_regs
[5] = 0x0 # skip
448 expected_regs
[6] = 0x0 # dststep starts at 3, so this gets skipped
449 expected_regs
[7] = 0x0 # skip
450 expected_regs
[8] = 0xffff_ffff_ffff_ff92 # this will be used
452 with
Program(lst
, bigendian
=False) as program
:
453 sim
= self
.run_tst_program(program
, initial_regs
, svstate
,
454 initial_cr
=cr
.cr
.asint())
455 self
._check
_regs
(sim
, expected_regs
)
457 def run_tst_program(self
, prog
, initial_regs
=None,
460 if initial_regs
is None:
461 initial_regs
= [0] * 32
462 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
463 initial_cr
=initial_cr
)
468 if __name__
== "__main__":