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
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 2, 0, 0x0010",
37 "sv.stw/els *4, 16(2)",
38 "sv.lwz/els *8, 16(2)"]
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 2, 0, 0x0010",
51 "sv.stw/els *4, 24(2)", # scalar r1 + 16 + 24*offs
52 "sv.lwz/els *8, 24(2)"]) # 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, 8(1)", # scalar r1 + 8 + wordlen*offs
97 "sv.lwz *12, 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 @unittest.skip("deprecated, needs Scalar LDST-shifted")
122 def test_sv_load_store_shifted(self
):
123 """>>> lst = ["addi 1, 0, 0x0010",
131 "sv.lwzsh *12, 4(1), 2"]
133 shifted LD is computed as:
135 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
137 lst
= SVP64Asm(["addi 1, 0, 0x0010",
143 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
144 "sv.lwzsh *12, 4(1), 2"]) # bit-reversed
147 # SVSTATE (in this case, VL=4)
148 svstate
= SVP64State()
150 svstate
.maxvl
= 4 # MAXVL
151 print ("SVSTATE", bin(svstate
.asint()))
153 with
Program(lst
, bigendian
=False) as program
:
154 sim
= self
.run_tst_program(program
, svstate
=svstate
)
155 mem
= sim
.mem
.dump(printout
=False)
158 self
.assertEqual(mem
, [(16, 0x020200000101),
159 (24, 0x040400000303)])
162 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
163 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
164 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
165 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
166 # r1=0x10, RC=0, offs=4: contents of memory expected at:
167 # element 0: EA = r1 + 0b00*4 => 0x10 + 0b00*4 => 0x10
168 # element 1: EA = r1 + 0b01*4 => 0x10 + 0b01*4 => 0x18
169 # element 2: EA = r1 + 0b10*4 => 0x10 + 0b10*4 => 0x14
170 # element 3: EA = r1 + 0b11*4 => 0x10 + 0b11*4 => 0x1c
171 # therefore loaded from (bit-reversed indexing):
172 # r9 => mem[0x10] which was stored from r5
173 # r10 => mem[0x18] which was stored from r6
174 # r11 => mem[0x18] which was stored from r7
175 # r12 => mem[0x1c] which was stored from r8
176 self
.assertEqual(sim
.gpr(12), SelectableInt(0x101, 64))
177 self
.assertEqual(sim
.gpr(13), SelectableInt(0x202, 64))
178 self
.assertEqual(sim
.gpr(14), SelectableInt(0x303, 64))
179 self
.assertEqual(sim
.gpr(15), SelectableInt(0x404, 64))
181 @unittest.skip("deprecated, needs Scalar LDST-shifted")
182 def test_sv_load_store_shifted_fp(self
):
183 """>>> lst = ["addi 1, 0, 0x0010",
191 "sv.lfdbr *12, 4(1), 2"]
193 shifted LD is computed as:
195 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
197 lst
= SVP64Asm(["addi 1, 0, 0x0010",
203 "sv.std *4, 0(1)", # scalar r1 + 0 + wordlen*offs
204 "sv.lfdsh *12, 8(1), 2"]) # shifted
207 # SVSTATE (in this case, VL=4)
208 svstate
= SVP64State()
210 svstate
.maxvl
= 4 # MAXVL
211 print ("SVSTATE", bin(svstate
.asint()))
215 with
Program(lst
, bigendian
=False) as program
:
216 sim
= self
.run_tst_program(program
, svstate
=svstate
,
218 mem
= sim
.mem
.dump(printout
=False)
221 self
.assertEqual(mem
, [(16, 0x101),
228 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
229 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
230 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
231 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
232 # r1=0x10, RC=0, offs=4: contents of memory expected at:
233 # element 0: EA = r1 + bitrev(0b00)*4 => 0x10 + 0b00*4 => 0x10
234 # element 1: EA = r1 + bitrev(0b01)*4 => 0x10 + 0b10*4 => 0x18
235 # element 2: EA = r1 + bitrev(0b10)*4 => 0x10 + 0b01*4 => 0x14
236 # element 3: EA = r1 + bitrev(0b11)*4 => 0x10 + 0b10*4 => 0x1c
237 # therefore loaded from (bit-reversed indexing):
238 # r9 => mem[0x10] which was stored from r5
239 # r10 => mem[0x18] which was stored from r6
240 # r11 => mem[0x18] which was stored from r7
241 # r12 => mem[0x1c] which was stored from r8
242 self
.assertEqual(sim
.fpr(12), SelectableInt(0x101, 64))
243 self
.assertEqual(sim
.fpr(13), SelectableInt(0x202, 64))
244 self
.assertEqual(sim
.fpr(14), SelectableInt(0x303, 64))
245 self
.assertEqual(sim
.fpr(15), SelectableInt(0x404, 64))
247 @unittest.skip("deprecated, needs Scalar LDST-shifted")
248 def test_sv_load_store_shifted2(self
):
249 """>>> lst = ["addi 1, 0, 0x0010",
253 "sv.lfssh *12, 4(1), 2"]
255 shifted LD is computed as:
257 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
260 lst
= SVP64Asm(["addi 1, 0, 0x0010",
262 "sv.stfs *4, 0(1)", # scalar r1 + 0 + wordlen*offs
263 "sv.lfssh *12, 4(1), 2"]) # shifted (by zero, but hey)
266 # SVSTATE (in this case, VL=4)
267 svstate
= SVP64State()
269 svstate
.maxvl
= 4 # MAXVL
270 print ("SVSTATE", bin(svstate
.asint()))
275 fprs
[4] = fp64toselectable(1.0)
276 fprs
[5] = fp64toselectable(2.0)
277 fprs
[6] = fp64toselectable(3.0)
278 fprs
[7] = fp64toselectable(4.0)
280 # expected results, remember that bit-reversed load has been done
281 expected_fprs
= deepcopy(fprs
)
282 expected_fprs
[12] = fprs
[4] # 0b00 -> 0b00
283 expected_fprs
[13] = fprs
[5] # 0b10 -> 0b01
284 expected_fprs
[14] = fprs
[6] # 0b01 -> 0b10
285 expected_fprs
[15] = fprs
[7] # 0b11 -> 0b11
287 with
Program(lst
, bigendian
=False) as program
:
288 sim
= self
.run_tst_program(program
, svstate
=svstate
,
290 mem
= sim
.mem
.dump(printout
=False)
297 #self.assertEqual(mem, [(16, 0x020200000101),
298 # (24, 0x040400000303)])
299 self
._check
_fpregs
(sim
, expected_fprs
)
301 def test_sv_load_store_remap_matrix(self
):
302 """>>> lst = ["addi 1, 0, 0x0010",
309 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
310 "svshape 3, 3, 4, 0, 0",
311 "svremap 1, 1, 2, 0, 0, 0, 0",
315 REMAPed a LD operation via a Matrix Multiply Schedule,
316 which is set up as 3x4 result
318 lst
= SVP64Asm(["addi 1, 0, 0x0010",
335 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
336 "svshape 3, 3, 4, 0, 0",
337 "svremap 1, 1, 2, 0, 0, 0, 0",
342 # SVSTATE (in this case, VL=4)
343 svstate
= SVP64State()
345 svstate
.maxvl
= 12 # MAXVL
346 print ("SVSTATE", bin(svstate
.asint()))
350 with
Program(lst
, bigendian
=False) as program
:
351 sim
= self
.run_tst_program(program
, svstate
=svstate
,
353 mem
= sim
.mem
.dump(printout
=False)
357 self
.assertEqual(mem
, [(16, 0x020200000101),
358 (24, 0x040400000303),
359 (32, 0x060600000505),
360 (40, 0x080800000707),
361 (48, 0x0a0a00000909),
362 (56, 0x0c0c00000b0b)])
365 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
366 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
367 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
368 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
369 self
.assertEqual(sim
.gpr(8), SelectableInt(0x505, 64))
370 self
.assertEqual(sim
.gpr(9), SelectableInt(0x606, 64))
371 self
.assertEqual(sim
.gpr(10), SelectableInt(0x707, 64))
372 self
.assertEqual(sim
.gpr(11), SelectableInt(0x808, 64))
373 # combination of bit-reversed load with a Matrix REMAP
376 self
.assertEqual(sim
.gpr(20+i
), SelectableInt(0x101, 64))
377 self
.assertEqual(sim
.gpr(23+i
), SelectableInt(0x505, 64))
378 self
.assertEqual(sim
.gpr(26+i
), SelectableInt(0x909, 64))
379 self
.assertEqual(sim
.gpr(29+i
), SelectableInt(0x202, 64))
381 def test_sv_load_store_bitreverse_remap_halfswap(self
):
382 """>>> lst = ["addi 1, 0, 0x0010",
393 "svshape 8, 1, 1, 6, 0",
394 "svremap 31, 1, 2, 3, 0, 0, 0",
395 "sv.lwz/els *12, 4(1)"]
397 shifted LD is computed as:
399 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
401 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
402 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
404 and thus creates the butterfly needed for one iteration of FFT.
405 the RC (shift) is to be able to offset the LDs by Radix-2 spans
407 on top of the bit-reversal is a REMAP for half-swaps for DCT
410 lst
= SVP64Asm(["addi 1, 0, 0x0010",
420 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
421 "svshape 8, 1, 1, 6, 0",
422 "svremap 1, 0, 0, 0, 0, 0, 0",
423 #"setvl 0, 0, 8, 0, 1, 1",
424 "sv.lwz/els *12, 4(1)",
429 # SVSTATE (in this case, VL=4)
430 svstate
= SVP64State()
432 svstate
.maxvl
= 8 # MAXVL
433 print ("SVSTATE", bin(svstate
.asint()))
437 avi
= [0x001, 0x102, 0x203, 0x304, 0x405, 0x506, 0x607, 0x708]
439 levels
= n
.bit_length() - 1
441 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
442 av
= halfrev2(avi
, False)
443 av
= [av
[ri
[i
]] for i
in range(n
)]
445 with
Program(lst
, bigendian
=False) as program
:
446 sim
= self
.run_tst_program(program
, svstate
=svstate
,
448 mem
= sim
.mem
.dump(printout
=False)
452 self
.assertEqual(mem
, [(16, 0x010200000001),
453 (24, 0x030400000203),
454 (32, 0x050600000405),
455 (40, 0x070800000607)])
457 for i
in range(len(avi
)):
458 print ("st gpr", i
, sim
.gpr(i
+4), hex(avi
[i
]))
459 for i
in range(len(avi
)):
460 self
.assertEqual(sim
.gpr(i
+4), avi
[i
])
461 # combination of bit-reversed load with a DCT half-swap REMAP
463 for i
in range(len(avi
)):
464 print ("ld gpr", i
, sim
.gpr(i
+12), hex(av
[i
]))
465 for i
in range(len(avi
)):
466 self
.assertEqual(sim
.gpr(i
+12), av
[i
])
468 def test_sv_load_store_bitreverse_remap_halfswap_idct(self
):
469 """>>> lst = ["addi 1, 0, 0x0010",
480 "svshape 8, 1, 1, 6, 0",
481 "svremap 31, 1, 2, 3, 0, 0, 0",
482 "sv.lwz/els *12, 4(1)"]
484 bitreverse LD is computed as:
486 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
488 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
489 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
491 and thus creates the butterfly needed for one iteration of FFT.
492 the RC (shift) is to be able to offset the LDs by Radix-2 spans
494 on top of the bit-reversal is a REMAP for half-swaps for DCT
497 lst
= SVP64Asm(["addi 1, 0, 0x0010",
507 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
508 "svshape 8, 1, 1, 14, 0",
509 "svremap 16, 0, 0, 0, 0, 0, 0",
510 #"setvl 0, 0, 8, 0, 1, 1",
511 "sv.lwz/els *12, 4(1)",
516 # SVSTATE (in this case, VL=4)
517 svstate
= SVP64State()
519 svstate
.maxvl
= 8 # MAXVL
520 print ("SVSTATE", bin(svstate
.asint()))
524 avi
= [0x001, 0x102, 0x203, 0x304, 0x405, 0x506, 0x607, 0x708]
526 levels
= n
.bit_length() - 1
528 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
529 av
= [avi
[ri
[i
]] for i
in range(n
)]
530 av
= halfrev2(av
, True)
532 with
Program(lst
, bigendian
=False) as program
:
533 sim
= self
.run_tst_program(program
, svstate
=svstate
,
535 mem
= sim
.mem
.dump(printout
=False)
539 self
.assertEqual(mem
, [(16, 0x010200000001),
540 (24, 0x030400000203),
541 (32, 0x050600000405),
542 (40, 0x070800000607)])
544 for i
in range(len(avi
)):
545 print ("st gpr", i
, sim
.gpr(i
+4), hex(avi
[i
]))
546 for i
in range(len(avi
)):
547 self
.assertEqual(sim
.gpr(i
+4), avi
[i
])
548 # combination of bit-reversed load with a DCT half-swap REMAP
550 for i
in range(len(avi
)):
551 print ("ld gpr", i
, sim
.gpr(i
+12), hex(av
[i
]))
552 for i
in range(len(avi
)):
553 self
.assertEqual(sim
.gpr(i
+12), av
[i
])
555 def run_tst_program(self
, prog
, initial_regs
=None,
556 svstate
=None, initial_fprs
=None):
557 if initial_regs
is None:
558 initial_regs
= [0] * 32
559 if initial_fprs
is None:
560 initial_fprs
= [0] * 32
561 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
562 initial_fprs
=initial_fprs
)
570 if __name__
== "__main__":