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
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 openpower
.decoder
.helpers
import fp64toselectable
17 from openpower
.decoder
.isa
.remap_dct_yield
import (halfrev2
, reverse_bits
,
19 from copy
import deepcopy
22 class DecoderTestCase(FHDLTestCase
):
24 def _check_regs(self
, sim
, expected
):
26 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
28 def _check_fpregs(self
, sim
, expected
):
30 self
.assertEqual(sim
.fpr(i
), SelectableInt(expected
[i
], 64))
32 def test_sv_load_store_elementstride(self
):
33 """>>> lst = ["addi 1, 0, 0x0010",
37 "sv.stw/els 4.v, 16(1)",
38 "sv.lwz/els 8.v, 16(1)"]
40 note: element stride mode is only enabled when RA is a scalar
41 and when the immediate is non-zero
43 element stride is computed as:
45 EA = (RA|0) + EXTS(D) * i
47 lst
= SVP64Asm(["addi 1, 0, 0x0010",
51 "sv.stw/els 4.v, 24(1)", # scalar r1 + 16 + 24*offs
52 "sv.lwz/els 8.v, 24(1)"]) # scalar r1 + 16 + 24*offs
55 # SVSTATE (in this case, VL=2)
56 svstate
= SVP64State()
58 svstate
.maxvl
= 2 # MAXVL
59 print ("SVSTATE", bin(svstate
.asint()))
61 with
Program(lst
, bigendian
=False) as program
:
62 sim
= self
.run_tst_program(program
, svstate
=svstate
)
63 mem
= sim
.mem
.dump(printout
=False)
65 # contents of memory expected at:
66 # element 0: r1=0x10, D=24, => EA = 0x10+24*0 = 16 (0x10)
67 # element 1: r1=0x10, D=24, => EA = 0x10+24*1 = 40 (0x28)
68 # therefore, at address 0x10 ==> 0x1234
69 # therefore, at address 0x28 ==> 0x1235
70 expected_mem
= [(16, 0x1234),
72 self
.assertEqual(mem
, expected_mem
)
74 self
.assertEqual(sim
.gpr(8), SelectableInt(0x1234, 64))
75 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1235, 64))
77 def test_sv_load_store_unitstride(self
):
78 """>>> lst = ["addi 1, 0, 0x0010",
85 note: unit stride mode is only enabled when RA is a scalar.
87 unit stride is computed as:
89 EA = (RA|0) + EXTS(D) + LDSTsize * i
90 where for stw and lwz, LDSTsize is 4 because it is 32-bit words
92 lst
= SVP64Asm(["addi 1, 0, 0x0010",
96 "sv.stw 8.v, 8(1)", # scalar r1 + 8 + wordlen*offs
97 "sv.lwz 12.v, 8(1)"]) # scalar r1 + 8 + wordlen*offs
100 # SVSTATE (in this case, VL=2)
101 svstate
= SVP64State()
103 svstate
.maxvl
= 2 # MAXVL
104 print ("SVSTATE", bin(svstate
.asint()))
106 with
Program(lst
, bigendian
=False) as program
:
107 sim
= self
.run_tst_program(program
, svstate
=svstate
)
108 mem
= sim
.mem
.dump(printout
=False)
111 # contents of memory expected at:
112 # element 0: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*0 = 0x24
113 # element 1: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*8 = 0x28
114 # therefore, at address 0x24 ==> 0x1234
115 # therefore, at address 0x28 ==> 0x1235
116 self
.assertEqual(mem
, [(24, 0x123500001234)])
118 self
.assertEqual(sim
.gpr(12), SelectableInt(0x1234, 64))
119 self
.assertEqual(sim
.gpr(13), SelectableInt(0x1235, 64))
121 def test_sv_load_store_shifted(self
):
122 """>>> lst = ["addi 1, 0, 0x0010",
130 "sv.lwzsh 12.v, 4(1), 2"]
132 shifted LD is computed as:
134 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
136 lst
= SVP64Asm(["addi 1, 0, 0x0010",
142 "sv.stw 5.v, 0(1)", # scalar r1 + 0 + wordlen*offs
143 "sv.lwzsh 12.v, 4(1), 2"]) # bit-reversed
146 # SVSTATE (in this case, VL=4)
147 svstate
= SVP64State()
149 svstate
.maxvl
= 4 # MAXVL
150 print ("SVSTATE", bin(svstate
.asint()))
152 with
Program(lst
, bigendian
=False) as program
:
153 sim
= self
.run_tst_program(program
, svstate
=svstate
)
154 mem
= sim
.mem
.dump(printout
=False)
157 self
.assertEqual(mem
, [(16, 0x020200000101),
158 (24, 0x040400000303)])
161 self
.assertEqual(sim
.gpr(5), SelectableInt(0x101, 64))
162 self
.assertEqual(sim
.gpr(6), SelectableInt(0x202, 64))
163 self
.assertEqual(sim
.gpr(7), SelectableInt(0x303, 64))
164 self
.assertEqual(sim
.gpr(8), SelectableInt(0x404, 64))
165 # r1=0x10, RC=0, offs=4: contents of memory expected at:
166 # element 0: EA = r1 + 0b00*4 => 0x10 + 0b00*4 => 0x10
167 # element 1: EA = r1 + 0b01*4 => 0x10 + 0b01*4 => 0x18
168 # element 2: EA = r1 + 0b10*4 => 0x10 + 0b10*4 => 0x14
169 # element 3: EA = r1 + 0b11*4 => 0x10 + 0b11*4 => 0x1c
170 # therefore loaded from (bit-reversed indexing):
171 # r9 => mem[0x10] which was stored from r5
172 # r10 => mem[0x18] which was stored from r6
173 # r11 => mem[0x18] which was stored from r7
174 # r12 => mem[0x1c] which was stored from r8
175 self
.assertEqual(sim
.gpr(12), SelectableInt(0x101, 64))
176 self
.assertEqual(sim
.gpr(13), SelectableInt(0x202, 64))
177 self
.assertEqual(sim
.gpr(14), SelectableInt(0x303, 64))
178 self
.assertEqual(sim
.gpr(15), SelectableInt(0x404, 64))
180 def test_sv_load_store_shifted_fp(self
):
181 """>>> lst = ["addi 1, 0, 0x0010",
189 "sv.lfdbr 12.v, 4(1), 2"]
191 shifted LD is computed as:
193 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
195 lst
= SVP64Asm(["addi 1, 0, 0x0010",
201 "sv.std 5.v, 0(1)", # scalar r1 + 0 + wordlen*offs
202 "sv.lfdsh 12.v, 8(1), 2"]) # shifted
205 # SVSTATE (in this case, VL=4)
206 svstate
= SVP64State()
208 svstate
.maxvl
= 4 # MAXVL
209 print ("SVSTATE", bin(svstate
.asint()))
213 with
Program(lst
, bigendian
=False) as program
:
214 sim
= self
.run_tst_program(program
, svstate
=svstate
,
216 mem
= sim
.mem
.dump(printout
=False)
219 self
.assertEqual(mem
, [(16, 0x101),
226 self
.assertEqual(sim
.gpr(5), SelectableInt(0x101, 64))
227 self
.assertEqual(sim
.gpr(6), SelectableInt(0x202, 64))
228 self
.assertEqual(sim
.gpr(7), SelectableInt(0x303, 64))
229 self
.assertEqual(sim
.gpr(8), SelectableInt(0x404, 64))
230 # r1=0x10, RC=0, offs=4: contents of memory expected at:
231 # element 0: EA = r1 + bitrev(0b00)*4 => 0x10 + 0b00*4 => 0x10
232 # element 1: EA = r1 + bitrev(0b01)*4 => 0x10 + 0b10*4 => 0x18
233 # element 2: EA = r1 + bitrev(0b10)*4 => 0x10 + 0b01*4 => 0x14
234 # element 3: EA = r1 + bitrev(0b11)*4 => 0x10 + 0b10*4 => 0x1c
235 # therefore loaded from (bit-reversed indexing):
236 # r9 => mem[0x10] which was stored from r5
237 # r10 => mem[0x18] which was stored from r6
238 # r11 => mem[0x18] which was stored from r7
239 # r12 => mem[0x1c] which was stored from r8
240 self
.assertEqual(sim
.fpr(12), SelectableInt(0x101, 64))
241 self
.assertEqual(sim
.fpr(13), SelectableInt(0x202, 64))
242 self
.assertEqual(sim
.fpr(14), SelectableInt(0x303, 64))
243 self
.assertEqual(sim
.fpr(15), SelectableInt(0x404, 64))
245 def test_sv_load_store_shifted2(self
):
246 """>>> lst = ["addi 1, 0, 0x0010",
250 "sv.lfssh 12.v, 4(1), 2"]
252 shifted LD is computed as:
254 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
257 lst
= SVP64Asm(["addi 1, 0, 0x0010",
259 "sv.stfs 4.v, 0(1)", # scalar r1 + 0 + wordlen*offs
260 "sv.lfssh 12.v, 4(1), 2"]) # shifted (by zero, but hey)
263 # SVSTATE (in this case, VL=4)
264 svstate
= SVP64State()
266 svstate
.maxvl
= 4 # MAXVL
267 print ("SVSTATE", bin(svstate
.asint()))
272 fprs
[4] = fp64toselectable(1.0)
273 fprs
[5] = fp64toselectable(2.0)
274 fprs
[6] = fp64toselectable(3.0)
275 fprs
[7] = fp64toselectable(4.0)
277 # expected results, remember that bit-reversed load has been done
278 expected_fprs
= deepcopy(fprs
)
279 expected_fprs
[12] = fprs
[4] # 0b00 -> 0b00
280 expected_fprs
[13] = fprs
[5] # 0b10 -> 0b01
281 expected_fprs
[14] = fprs
[6] # 0b01 -> 0b10
282 expected_fprs
[15] = fprs
[7] # 0b11 -> 0b11
284 with
Program(lst
, bigendian
=False) as program
:
285 sim
= self
.run_tst_program(program
, svstate
=svstate
,
287 mem
= sim
.mem
.dump(printout
=False)
294 #self.assertEqual(mem, [(16, 0x020200000101),
295 # (24, 0x040400000303)])
296 self
._check
_fpregs
(sim
, expected_fprs
)
298 def test_sv_load_store_remap_matrix(self
):
299 """>>> lst = ["addi 1, 0, 0x0010",
306 "sv.stw 4.v, 0(1)", # scalar r1 + 0 + wordlen*offs
307 "svshape 3, 3, 4, 0, 0",
308 "svremap 1, 1, 2, 0, 0, 0, 0, 1",
312 REMAPed a LD operation via a Matrix Multiply Schedule,
313 which is set up as 3x4 result
315 lst
= SVP64Asm(["addi 1, 0, 0x0010",
332 "sv.stw 4.v, 0(1)", # scalar r1 + 0 + wordlen*offs
333 "svshape 3, 3, 4, 0, 0",
334 "svremap 1, 1, 2, 0, 0, 0, 0, 1",
336 #"sv.lwzsh 12.v, 4(1), 2", # bit-reversed
340 # SVSTATE (in this case, VL=4)
341 svstate
= SVP64State()
343 svstate
.maxvl
= 12 # MAXVL
344 print ("SVSTATE", bin(svstate
.asint()))
348 with
Program(lst
, bigendian
=False) as program
:
349 sim
= self
.run_tst_program(program
, svstate
=svstate
,
351 mem
= sim
.mem
.dump(printout
=False)
355 self
.assertEqual(mem
, [(16, 0x020200000101),
356 (24, 0x040400000303),
357 (32, 0x060600000505),
358 (40, 0x080800000707),
359 (48, 0x0a0a00000909),
360 (56, 0x0c0c00000b0b)])
363 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
364 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
365 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
366 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
367 self
.assertEqual(sim
.gpr(8), SelectableInt(0x505, 64))
368 self
.assertEqual(sim
.gpr(9), SelectableInt(0x606, 64))
369 self
.assertEqual(sim
.gpr(10), SelectableInt(0x707, 64))
370 self
.assertEqual(sim
.gpr(11), SelectableInt(0x808, 64))
371 # combination of bit-reversed load with a Matrix REMAP
374 self
.assertEqual(sim
.gpr(20+i
), SelectableInt(0x101, 64))
375 self
.assertEqual(sim
.gpr(23+i
), SelectableInt(0x505, 64))
376 self
.assertEqual(sim
.gpr(26+i
), SelectableInt(0x909, 64))
377 self
.assertEqual(sim
.gpr(29+i
), SelectableInt(0x202, 64))
379 def test_sv_load_store_bitreverse_remap_halfswap(self
):
380 """>>> lst = ["addi 1, 0, 0x0010",
391 "svshape 8, 1, 1, 6, 0",
392 "svremap 31, 1, 2, 3, 0, 0, 0, 0",
393 "sv.lwzsh 12.v, 4(1), 2"]
395 shifted LD is computed as:
397 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
399 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
400 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
402 and thus creates the butterfly needed for one iteration of FFT.
403 the RC (shift) is to be able to offset the LDs by Radix-2 spans
405 on top of the bit-reversal is a REMAP for half-swaps for DCT
408 lst
= SVP64Asm(["addi 1, 0, 0x0010",
418 "sv.stw 4.v, 0(1)", # scalar r1 + 0 + wordlen*offs
419 "svshape 8, 1, 1, 6, 0",
420 "svremap 1, 0, 0, 0, 0, 0, 0, 1",
421 #"setvl 0, 0, 8, 0, 1, 1",
422 "sv.lwzsh 12.v, 4(1), 2", # bit-reversed
427 # SVSTATE (in this case, VL=4)
428 svstate
= SVP64State()
430 svstate
.maxvl
= 8 # MAXVL
431 print ("SVSTATE", bin(svstate
.asint()))
435 avi
= [0x001, 0x102, 0x203, 0x304, 0x405, 0x506, 0x607, 0x708]
437 levels
= n
.bit_length() - 1
439 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
440 av
= halfrev2(avi
, False)
441 av
= [av
[ri
[i
]] for i
in range(n
)]
443 with
Program(lst
, bigendian
=False) as program
:
444 sim
= self
.run_tst_program(program
, svstate
=svstate
,
446 mem
= sim
.mem
.dump(printout
=False)
450 self
.assertEqual(mem
, [(16, 0x010200000001),
451 (24, 0x030400000203),
452 (32, 0x050600000405),
453 (40, 0x070800000607)])
455 for i
in range(len(avi
)):
456 print ("st gpr", i
, sim
.gpr(i
+4), hex(avi
[i
]))
457 for i
in range(len(avi
)):
458 self
.assertEqual(sim
.gpr(i
+4), avi
[i
])
459 # combination of bit-reversed load with a DCT half-swap REMAP
461 for i
in range(len(avi
)):
462 print ("ld gpr", i
, sim
.gpr(i
+12), hex(av
[i
]))
463 for i
in range(len(avi
)):
464 self
.assertEqual(sim
.gpr(i
+12), av
[i
])
466 def test_sv_load_store_bitreverse_remap_halfswap_idct(self
):
467 """>>> lst = ["addi 1, 0, 0x0010",
478 "svshape 8, 1, 1, 6, 0",
479 "svremap 31, 1, 2, 3, 0, 0, 0, 0",
480 "sv.lwzsh 12.v, 4(1), 2"]
482 bitreverse LD is computed as:
484 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
486 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
487 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
489 and thus creates the butterfly needed for one iteration of FFT.
490 the RC (shift) is to be able to offset the LDs by Radix-2 spans
492 on top of the bit-reversal is a REMAP for half-swaps for DCT
495 lst
= SVP64Asm(["addi 1, 0, 0x0010",
505 "sv.stw 4.v, 0(1)", # scalar r1 + 0 + wordlen*offs
506 "svshape 8, 1, 1, 14, 0",
507 "svremap 16, 0, 0, 0, 0, 0, 0, 1",
508 #"setvl 0, 0, 8, 0, 1, 1",
509 "sv.lwzsh 12.v, 4(1), 2", # bit-reversed
514 # SVSTATE (in this case, VL=4)
515 svstate
= SVP64State()
517 svstate
.maxvl
= 8 # MAXVL
518 print ("SVSTATE", bin(svstate
.asint()))
522 avi
= [0x001, 0x102, 0x203, 0x304, 0x405, 0x506, 0x607, 0x708]
524 levels
= n
.bit_length() - 1
526 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
527 av
= [avi
[ri
[i
]] for i
in range(n
)]
528 av
= halfrev2(av
, True)
530 with
Program(lst
, bigendian
=False) as program
:
531 sim
= self
.run_tst_program(program
, svstate
=svstate
,
533 mem
= sim
.mem
.dump(printout
=False)
537 self
.assertEqual(mem
, [(16, 0x010200000001),
538 (24, 0x030400000203),
539 (32, 0x050600000405),
540 (40, 0x070800000607)])
542 for i
in range(len(avi
)):
543 print ("st gpr", i
, sim
.gpr(i
+4), hex(avi
[i
]))
544 for i
in range(len(avi
)):
545 self
.assertEqual(sim
.gpr(i
+4), avi
[i
])
546 # combination of bit-reversed load with a DCT half-swap REMAP
548 for i
in range(len(avi
)):
549 print ("ld gpr", i
, sim
.gpr(i
+12), hex(av
[i
]))
550 for i
in range(len(avi
)):
551 self
.assertEqual(sim
.gpr(i
+12), av
[i
])
553 def run_tst_program(self
, prog
, initial_regs
=None,
554 svstate
=None, initial_fprs
=None):
555 if initial_regs
is None:
556 initial_regs
= [0] * 32
557 if initial_fprs
is None:
558 initial_fprs
= [0] * 32
559 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
560 initial_fprs
=initial_fprs
)
568 if __name__
== "__main__":