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 copy
import deepcopy
19 class DecoderTestCase(FHDLTestCase
):
21 def _check_regs(self
, sim
, expected
):
23 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
25 def test_sv_load_store_elementstride(self
):
26 """>>> lst = ["addi 1, 0, 0x0010",
30 "sv.stw/els 5.v, 16(1)",
31 "sv.lwz/els 9.v, 16(1)"]
33 note: element stride mode is only enabled when RA is a scalar
34 and when the immediate is non-zero
36 element stride is computed as:
38 EA = (RA|0) + EXTS(D) * i
40 lst
= SVP64Asm(["addi 1, 0, 0x0010",
44 "sv.stw/els 5.v, 24(1)", # scalar r1 + 16 + 24*offs
45 "sv.lwz/els 9.v, 24(1)"]) # scalar r1 + 16 + 24*offs
48 # SVSTATE (in this case, VL=2)
49 svstate
= SVP64State()
50 svstate
.vl
[0:7] = 2 # VL
51 svstate
.maxvl
[0:7] = 2 # MAXVL
52 print ("SVSTATE", bin(svstate
.spr
.asint()))
54 with
Program(lst
, bigendian
=False) as program
:
55 sim
= self
.run_tst_program(program
, svstate
=svstate
)
56 mem
= sim
.mem
.dump(printout
=False)
58 # contents of memory expected at:
59 # element 0: r1=0x10, D=24, => EA = 0x10+24*0 = 16 (0x10)
60 # element 1: r1=0x10, D=24, => EA = 0x10+24*1 = 40 (0x28)
61 # therefore, at address 0x10 ==> 0x1234
62 # therefore, at address 0x28 ==> 0x1235
63 expected_mem
= [(16, 0x1234),
65 self
.assertEqual(mem
, expected_mem
)
67 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1234, 64))
68 self
.assertEqual(sim
.gpr(10), SelectableInt(0x1235, 64))
70 def test_sv_load_store_unitstride(self
):
71 """>>> lst = ["addi 1, 0, 0x0010",
78 note: unit stride mode is only enabled when RA is a scalar.
80 unit stride is computed as:
82 EA = (RA|0) + EXTS(D) + LDSTsize * i
83 where for stw and lwz, LDSTsize is 4 because it is 32-bit words
85 lst
= SVP64Asm(["addi 1, 0, 0x0010",
89 "sv.stw 5.v, 8(1)", # scalar r1 + 8 + wordlen*offs
90 "sv.lwz 9.v, 8(1)"]) # scalar r1 + 8 + wordlen*offs
93 # SVSTATE (in this case, VL=2)
94 svstate
= SVP64State()
95 svstate
.vl
[0:7] = 2 # VL
96 svstate
.maxvl
[0:7] = 2 # MAXVL
97 print ("SVSTATE", bin(svstate
.spr
.asint()))
99 with
Program(lst
, bigendian
=False) as program
:
100 sim
= self
.run_tst_program(program
, svstate
=svstate
)
101 mem
= sim
.mem
.dump(printout
=False)
103 # contents of memory expected at:
104 # element 0: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*0 = 0x24
105 # element 1: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*8 = 0x28
106 # therefore, at address 0x24 ==> 0x1234
107 # therefore, at address 0x28 ==> 0x1235
108 self
.assertEqual(mem
, [(24, 0x123500001234)])
110 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1234, 64))
111 self
.assertEqual(sim
.gpr(10), SelectableInt(0x1235, 64))
113 def test_sv_load_store_bitreverse(self
):
114 """>>> lst = ["addi 1, 0, 0x0010",
122 "sv.lwzbr 9.v, 4(1), 2"]
124 note: bitreverse mode is... odd. it's the butterfly generator
125 from Cooley-Tukey FFT:
126 https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms
128 bitreverse LD is computed as:
130 EA = (RA|0) + (EXTS(D) * LDSTsize * bitreverse(i, VL)) << RC
132 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
133 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
135 and thus creates the butterfly needed for one iteration of FFT.
136 the RC (shift) is to be able to offset the LDs by Radix-2 spans
138 lst
= SVP64Asm(["addi 1, 0, 0x0010",
144 "sv.stw 5.v, 0(1)", # scalar r1 + 0 + wordlen*offs
145 "sv.lwzbr 9.v, 4(1), 2"]) # bit-reversed
148 # SVSTATE (in this case, VL=4)
149 svstate
= SVP64State()
150 svstate
.vl
[0:7] = 4 # VL
151 svstate
.maxvl
[0:7] = 4 # MAXVL
152 print ("SVSTATE", bin(svstate
.spr
.asint()))
154 with
Program(lst
, bigendian
=False) as program
:
155 sim
= self
.run_tst_program(program
, svstate
=svstate
)
156 mem
= sim
.mem
.dump(printout
=False)
159 self
.assertEqual(mem
, [(16, 0x020200000101),
160 (24, 0x040400000303)])
163 self
.assertEqual(sim
.gpr(5), SelectableInt(0x101, 64))
164 self
.assertEqual(sim
.gpr(6), SelectableInt(0x202, 64))
165 self
.assertEqual(sim
.gpr(7), SelectableInt(0x303, 64))
166 self
.assertEqual(sim
.gpr(8), SelectableInt(0x404, 64))
167 # r1=0x10, RC=0, offs=4: contents of memory expected at:
168 # element 0: EA = r1 + bitrev(0b00)*4 => 0x10 + 0b00*4 => 0x10
169 # element 1: EA = r1 + bitrev(0b01)*4 => 0x10 + 0b10*4 => 0x18
170 # element 2: EA = r1 + bitrev(0b10)*4 => 0x10 + 0b01*4 => 0x14
171 # element 3: EA = r1 + bitrev(0b11)*4 => 0x10 + 0b10*4 => 0x1c
172 # therefore loaded from (bit-reversed indexing):
173 # r9 => mem[0x10] which was stored from r5
174 # r10 => mem[0x18] which was stored from r6
175 # r11 => mem[0x18] which was stored from r7
176 # r12 => mem[0x1c] which was stored from r8
177 self
.assertEqual(sim
.gpr(9), SelectableInt(0x101, 64))
178 self
.assertEqual(sim
.gpr(10), SelectableInt(0x303, 64))
179 self
.assertEqual(sim
.gpr(11), SelectableInt(0x202, 64))
180 self
.assertEqual(sim
.gpr(12), SelectableInt(0x404, 64))
182 def run_tst_program(self
, prog
, initial_regs
=None,
184 if initial_regs
is None:
185 initial_regs
= [0] * 32
186 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
)
191 if __name__
== "__main__":