5e1f1a1d5d21ffa320896765aa7ee72145baf00f
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 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(self
):
26 """>>> lst = ["addi 2, 0, 0x0010",
33 lst
= SVP64Asm(["addi 2, 0, 0x0010",
41 # SVSTATE (in this case, VL=2)
42 svstate
= SVP64State()
44 svstate
.maxvl
= 2 # MAXVL
45 print ("SVSTATE", bin(svstate
.asint()))
47 with
Program(lst
, bigendian
=False) as program
:
48 sim
= self
.run_tst_program(program
, svstate
=svstate
)
50 self
.assertEqual(sim
.gpr(8), SelectableInt(0x1234, 64))
51 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1235, 64))
53 def test_sv_branch_cond(self
):
54 for i
in [0, 10]: #, 10]: #[0, 10]:
56 [f
"addi 1, 0, {i}", # set r1 to i
57 f
"addi 2, 0, {i}", # set r2 to i
58 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
59 "cmpi cr1, 1, 2, 10", # compare r2 with 10 and store to cr1
60 "sv.bc 12, *2, 0xc", # beq 0xc -
61 # branch if r1 equals 10 to the nop below
62 "addi 3, 0, 0x1234", # if r1 == 10 this shouldn't execute
63 "or 0, 0, 0"] # branch target
67 # SVSTATE (in this case, VL=2)
68 svstate
= SVP64State()
70 svstate
.maxvl
= 2 # MAXVL
71 print ("SVSTATE", bin(svstate
.asint()))
73 with
Program(lst
, bigendian
=False) as program
:
74 sim
= self
.run_tst_program(program
, svstate
=svstate
)
76 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
78 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
80 def test_sv_branch_cond_all(self
):
83 [f
"addi 1, 0, {i+1}", # set r1 to i
84 f
"addi 2, 0, {i}", # set r2 to i
85 "cmpi cr0, 1, 1, 8", # compare r1 with 10 and store to cr0
86 "cmpi cr1, 1, 2, 8", # compare r2 with 10 and store to cr1
87 "sv.bc/all 12, *1, 0xc", # bgt 0xc - branch if BOTH
88 # r1 AND r2 greater 8 to the nop below
89 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
90 "or 0, 0, 0"] # branch target
94 # SVSTATE (in this case, VL=2)
95 svstate
= SVP64State()
97 svstate
.maxvl
= 2 # MAXVL
98 print ("SVSTATE", bin(svstate
.asint()))
100 with
Program(lst
, bigendian
=False) as program
:
101 sim
= self
.run_tst_program(program
, svstate
=svstate
)
103 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
105 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
107 def test_sv_branch_cond_all_vlset(self
):
110 [f
"addi 1, 0, {i+1}", # set r1 to i
111 f
"addi 2, 0, {i}", # set r2 to i
112 "cmpi cr0, 1, 1, 8", # compare r1 with 10 and store to cr0
113 "cmpi cr1, 1, 2, 8", # compare r2 with 10 and store to cr1
114 "sv.bc/all/vs 12, *1, 0xc", # bgt 0xc - branch if BOTH
115 # r1 AND r2 greater 8 to the nop below
116 # also truncate VL at the fail-point
117 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
118 "or 0, 0, 0"] # branch target
122 # SVSTATE (in this case, VL=2)
123 svstate
= SVP64State()
125 svstate
.maxvl
= 2 # MAXVL
126 print ("SVSTATE", bin(svstate
.asint()))
128 with
Program(lst
, bigendian
=False) as program
:
129 sim
= self
.run_tst_program(program
, svstate
=svstate
)
131 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
133 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
134 print ("SVSTATE.vl", bin(svstate
.vl
))
135 self
.assertEqual(svstate
.vl
, i
-7)
137 def test_sv_branch_cond_vlset_inv(self
):
140 [f
"addi 1, 0, {i+1}", # set r1 to i
141 f
"addi 2, 0, {i}", # set r2 to i
142 "cmpi cr0, 1, 1, 8", # compare r1 with 8 and store to cr0
143 "cmpi cr1, 1, 2, 8", # compare r2 with 8 and store to cr1
144 "sv.bc/vsb 4, *1, 0xc", # bgt 0xc - branch if BOTH
145 # r1 AND r2 greater 8 to the nop below
146 # also truncate VL at the fail-point
147 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
148 "or 0, 0, 0"] # branch target
152 # SVSTATE (in this case, VL=2)
153 svstate
= SVP64State()
155 svstate
.maxvl
= 2 # MAXVL
156 print ("SVSTATE", bin(svstate
.asint()))
158 with self
.subTest("vlset_inv %d" % i
):
159 with
Program(lst
, bigendian
=False) as program
:
160 sim
= self
.run_tst_program(program
, svstate
=svstate
)
161 print ("SVSTATE.vl", bin(svstate
.vl
))
163 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
165 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
166 self
.assertEqual(svstate
.vl
, i
-7)
168 def test_sv_branch_cond_ctr_vlset_inv(self
):
171 [f
"addi 1, 0, {i+1}", # set r1 to i
172 f
"addi 2, 0, {i}", # set r2 to i
173 "cmpi cr0, 1, 1, 8", # compare r1 with 8 and store to cr0
174 "cmpi cr1, 1, 2, 8", # compare r2 with 8 and store to cr1
175 "sv.bc/vsb 0, *1, 0xc", # bgt 0xc - branch if BOTH
176 # r1 AND r2 greater 8 to the nop below
177 # also truncate VL at the fail-point
178 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
179 "or 0, 0, 0"] # branch target
183 # SVSTATE (in this case, VL=2)
184 svstate
= SVP64State()
186 svstate
.maxvl
= 2 # MAXVL
187 print ("SVSTATE", bin(svstate
.asint()))
190 with self
.subTest("vlset_ctr_inv %d" % i
):
191 with
Program(lst
, bigendian
=False) as program
:
192 sim
= self
.run_tst_program(program
, svstate
=svstate
,
194 print ("SVSTATE.vl", bin(svstate
.vl
))
195 print ("CTR", sim
.spr('CTR').value
)
197 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
199 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
200 self
.assertEqual(svstate
.vl
, i
-7)
202 def test_sv_branch_ctr(self
):
203 """XXX under development, seems to be good.
204 basically this will reduce CTR under a *vector* loop, where BO[0]
205 is 1 so there is no CR-bit-test, and BO[2] is 0 so there is a CTR-zero
206 test. when the CTR-zero test fails the loop is exited, with CTR
207 having been reduced by up to at least VL times. without VLSET
208 mode at the same time (which truncates VL at this same fail-point)
209 however this is not necessarily so useful, but at least the branch
210 occurs with CTR being reduced *at least* by VL.
215 "sv.bc/ctr/all 16, *0, 0xc", # branch, test CTR, reducing by VL
216 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
217 "or 0, 0, 0"] # branch target
221 # SVSTATE (in this case, VL=2)
222 svstate
= SVP64State()
224 svstate
.maxvl
= 2 # MAXVL
225 print ("SVSTATE", bin(svstate
.asint()))
228 with
Program(lst
, bigendian
=False) as program
:
229 sim
= self
.run_tst_program(program
, svstate
=svstate
,
234 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
235 self
.assertEqual(sim
.spr('CTR'), SelectableInt(0, 64))
237 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
238 self
.assertEqual(sim
.spr('CTR'), SelectableInt(1, 64))
240 def test_sv_branch_ctr_loop(self
):
241 """this is a branch-ctr-loop demo which shows an (unconditional)
242 decrementing of CTR by VL. BI still has to be set to Vector even
243 though it is unused (BO[0]=1).
248 "setvl 1, 0, %d, 0, 1, 1" % maxvl
, # VL (and r1) = MIN(CTR,MAXVL=4)
249 "add 2, 2, 1", # for fun accumulate r1 (VL) into r2
250 "sv.bc/all 16, *0, -0x8", # branch, test CTR, reducing by VL
255 # SVSTATE - set vl and maxvl to 2, they get overridden with setvl
256 svstate
= SVP64State()
258 svstate
.maxvl
= 2 # MAXVL
259 print ("SVSTATE", bin(svstate
.asint()))
261 sprs
= {'CTR': target
}
263 with
Program(lst
, bigendian
=False) as program
:
264 sim
= self
.run_tst_program(program
, svstate
=svstate
,
268 self
.assertEqual(sim
.spr('CTR'), SelectableInt(0, 64))
269 self
.assertEqual(sim
.gpr(2), SelectableInt(target
, 64))
270 # MAXVL repeatedly subtracted from VL (r1), last loop has remainder
271 self
.assertEqual(sim
.gpr(1), SelectableInt(target
% maxvl
, 64))
273 def norun_sv_add_cr(self
):
274 """>>> lst = ['sv.add. *1, *5, *9'
277 adds when Rc=1: TODO CRs higher up
278 * 1 = 5 + 9 => 0 = -1+1 CR0=0b100
279 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
281 isa
= SVP64Asm(['sv.add. *1, *5, *9'
284 print ("listing", lst
)
286 # initial values in GPR regfile
287 initial_regs
= [0] * 32
288 initial_regs
[9] = 0xffffffffffffffff
289 initial_regs
[10] = 0x1111
290 initial_regs
[5] = 0x1
291 initial_regs
[6] = 0x2223
292 # SVSTATE (in this case, VL=2)
293 svstate
= SVP64State()
295 svstate
.maxvl
= 2 # MAXVL
296 print ("SVSTATE", bin(svstate
.asint()))
297 # copy before running
298 expected_regs
= deepcopy(initial_regs
)
299 expected_regs
[1] = initial_regs
[5] + initial_regs
[9] # 0x0
300 expected_regs
[2] = initial_regs
[6] + initial_regs
[10] # 0x3334
302 with
Program(lst
, bigendian
=False) as program
:
303 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
304 # XXX TODO, these need to move to higher range (offset)
305 cr0_idx
= SVP64CROffs
.CR0
306 cr1_idx
= SVP64CROffs
.CR1
307 CR0
= sim
.crl
[cr0_idx
].get_range().value
308 CR1
= sim
.crl
[cr1_idx
].get_range().value
311 self
._check
_regs
(sim
, expected_regs
)
312 self
.assertEqual(CR0
, SelectableInt(2, 4))
313 self
.assertEqual(CR1
, SelectableInt(4, 4))
315 def run_tst_program(self
, prog
, initial_regs
=None,
318 if initial_regs
is None:
319 initial_regs
= [0] * 32
320 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
321 initial_sprs
=initial_sprs
)
326 if __name__
== "__main__":