test SVP64 major opcode, start checking if it is EXT001 soon
[soc.git] / src / soc / decoder / power_pseudo.py
1 # Based on GardenSnake - a parser generator demonstration program
2 # GardenSnake was released into the Public Domain by Andrew Dalke.
3
4 # Portions of this work are derived from Python's Grammar definition
5 # and may be covered under the Python copyright and license
6 #
7 # Andrew Dalke / Dalke Scientific Software, LLC
8 # 30 August 2006 / Cape Town, South Africa
9
10 # Modifications for inclusion in PLY distribution
11 import sys
12 from pprint import pprint
13 from copy import copy
14 from ply import lex, yacc
15 import astor
16 import ast
17
18 from soc.decoder.power_decoder import create_pdecode
19 from nmigen.back.pysim import Simulator, Delay
20 from nmigen import Module, Signal
21
22 from soc.decoder.pseudo.parser import GardenSnakeCompiler
23 from soc.decoder.selectable_int import SelectableInt, selectconcat
24 from soc.decoder.isa.caller import GPR, Mem
25
26
27 ####### Test code #######
28
29 bpermd = r"""
30 perm <- [0] * 8
31 if index < 64:
32 index <- (RS)[8*i:8*i+7]
33 RA <- [0]*56 || perm[0:7]
34 print (RA)
35 """
36
37 bpermd = r"""
38 if index < 64 then index <- 0
39 else index <- 5
40 do while index < 5
41 index <- 0
42 leave
43 for i = 0 to 7
44 index <- 0
45 """
46
47 _bpermd = r"""
48 for i = 0 to 7
49 index <- (RS)[8*i:8*i+7]
50 if index < 64 then
51 permi <- (RB)[index]
52 else
53 permi <- 0
54 RA <- [0]*56|| perm[0:7]
55 """
56
57 cnttzd = """
58 n <- 0
59 do while n < 64
60 print (n)
61 if (RS)[63-n] = 0b1 then
62 leave
63 n <- n + 1
64 RA <- EXTZ64(n)
65 print (RA)
66 """
67
68 cmpi = """
69 if a < EXTS(SI) then
70 c <- 0b100
71 else if a > EXTS(SI) then
72 c <- 0b010
73 """
74
75 cmpi = """
76 RA[0:1] <- 0b11
77 """
78
79 cmpi = """
80 in_range <- ((x | y) &
81 (a | b))
82 in_range <- (x + y) - (a + b)
83 """
84
85 cmpi = """
86 (RA)[0:1] <- 1
87 src1 <- EXTZ((RA)[56:63])
88 CR[4*BF+32] <- 0b0
89 in_range <- src21lo <= src1 & src1 <= src21hi
90 """
91
92 cmpeqb = """
93 src1 <- GPR[RA]
94 src1 <- src1[0:56]
95 """
96
97 addpcis = """
98 D <- d0||d1||d2
99 """
100
101 testmul = """
102 x <- [0] * 16
103 RT <- (RA) + EXTS(SI || [0]*16)
104 """
105
106 testgetzero = """
107 RS <- (RA|0)
108 RS <- RS + 1
109 print(RS)
110 """
111
112 testcat = """
113 RT <- (load_data[56:63] || load_data[48:55]
114 || load_data[40:47] || load_data[32:39]
115 || load_data[24:31] || load_data[16:23]
116 || load_data[8:15] || load_data[0:7])
117 """
118
119 testgpr = """
120 GPR(5) <- x
121 """
122 testmem = """
123 a <- (RA|0)
124 b <- (RB|0)
125 RA <- MEM(RB, 2)
126 EA <- a + 1
127 MEM(EA, 1) <- (RS)[56:63]
128 RB <- RA
129 RA <- EA
130 """
131
132 testgprslice = """
133 MEM(EA, 4) <- GPR(r)[32:63]
134 #x <- x[0][32:63]
135 """
136
137 testdo = r"""
138 do i = 0 to 7
139 print(i)
140 """
141
142 testcond = """
143 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
144 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
145 """
146
147 lswx = """
148 if RA = 0 then EA <- 0
149 else EA <- (RA)
150 if NB = 0 then n <- 32
151 else n <- NB
152 r <- RT - 1
153 i <- 32
154 do while n > 0
155 if i = 32 then
156 r <- (r + 1) % 32
157 GPR(r) <- 0
158 GPR(r)[i:i+7] <- MEM(EA, 1)
159 i <- i + 8
160 if i = 64 then i <- 32
161 EA <- EA + 1
162 n <- n - 1
163 """
164
165 _lswx = """
166 GPR(r)[x] <- 1
167 """
168
169 switchtest = """
170 switch (n)
171 case(1): x <- 5
172 case(2): fallthrough
173 case(3):
174 x <- 3
175 case(4): fallthrough
176 default:
177 x <- 9
178 """
179
180 hextest = """
181 RT <- 0x0001_a000_0000_0000
182 """
183
184 code = hextest
185 #code = lswx
186 #code = testcond
187 #code = testdo
188 #code = _bpermd
189 #code = testmul
190 #code = testgetzero
191 #code = testcat
192 #code = testgpr
193 #code = testmem
194 #code = testgprslice
195 #code = testreg
196 #code = cnttzd
197 #code = cmpi
198 #code = cmpeqb
199 #code = addpcis
200 #code = bpermd
201
202
203 def tolist(num):
204 l = []
205 for i in range(64):
206 l.append(1 if (num & (1 << i)) else 0)
207 l.reverse()
208 return l
209
210
211 def get_reg_hex(reg):
212 return hex(reg.value)
213
214
215 def convert_to_python(pcode, form, incl_carry):
216
217 print("form", form)
218 gsc = GardenSnakeCompiler(form=form, incl_carry=incl_carry)
219
220 tree = gsc.compile(pcode, mode="exec", filename="string")
221 tree = ast.fix_missing_locations(tree)
222 regsused = {'read_regs': gsc.parser.read_regs,
223 'write_regs': gsc.parser.write_regs,
224 'uninit_regs': gsc.parser.uninit_regs,
225 'special_regs': gsc.parser.special_regs,
226 'op_fields': gsc.parser.op_fields}
227 return astor.to_source(tree), regsused
228
229
230 def test():
231
232 gsc = GardenSnakeCompiler(debug=True)
233
234 gsc.regfile = {}
235 for i in range(32):
236 gsc.regfile[i] = i
237 gsc.gpr = GPR(gsc.parser.sd, gsc.regfile)
238 gsc.mem = Mem()
239
240 _compile = gsc.compile
241
242 tree = _compile(code, mode="single", filename="string")
243 tree = ast.fix_missing_locations(tree)
244 print(ast.dump(tree))
245
246 print("astor dump")
247 print(astor.dump_tree(tree))
248 print("to source")
249 source = astor.to_source(tree)
250 print(source)
251
252 # sys.exit(0)
253
254 # Set up the GardenSnake run-time environment
255 def print_(*args):
256 print("args", args)
257 print("-->", " ".join(map(str, args)))
258
259 from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
260 trunc_div, trunc_rem)
261
262 d = {}
263 d["print"] = print_
264 d["EXTS64"] = EXTS64
265 d["EXTZ64"] = EXTZ64
266 d["trunc_div"] = trunc_div
267 d["trunc_rem"] = trunc_rem
268 d["SelectableInt"] = SelectableInt
269 d["concat"] = selectconcat
270 d["GPR"] = gsc.gpr
271 d["MEM"] = gsc.mem
272 d["memassign"] = gsc.mem.memassign
273
274 form = 'X'
275 gsc.gpr.set_form(form)
276 getform = gsc.parser.sd.sigforms[form]._asdict()
277 #print ("getform", form)
278 # for k, f in getform.items():
279 #print (k, f)
280 #d[k] = getform[k]
281
282 compiled_code = compile(source, mode="exec", filename="<string>")
283
284 m = Module()
285 comb = m.d.comb
286 instruction = Signal(32)
287
288 m.submodules.decode = decode = gsc.parser.sd
289 comb += decode.raw_opcode_in.eq(instruction)
290 sim = Simulator(m)
291
292 instr = [0x11111117]
293
294 def process():
295 for ins in instr:
296 print("0x{:X}".format(ins & 0xffffffff))
297
298 # ask the decoder to decode this binary data (endian'd)
299 yield decode.bigendian.eq(0) # little / big?
300 yield instruction.eq(ins) # raw binary instr.
301 yield Delay(1e-6)
302
303 # uninitialised regs, drop them into dict for function
304 for rname in gsc.parser.uninit_regs:
305 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
306 print("uninitialised", rname, hex(d[rname].value))
307
308 # read regs, drop them into dict for function
309 for rname in gsc.parser.read_regs:
310 regidx = yield getattr(decode.sigforms['X'], rname)
311 d[rname] = gsc.gpr[regidx] # contents of regfile
312 d["_%s" % rname] = regidx # actual register value
313 print("read reg", rname, regidx, hex(d[rname].value))
314
315 exec(compiled_code, d) # code gets executed here in dict "d"
316 print("Done")
317
318 print(d.keys()) # shows the variables that may have been created
319
320 print(decode.sigforms['X'])
321 x = yield decode.sigforms['X'].RS
322 ra = yield decode.sigforms['X'].RA
323 rb = yield decode.sigforms['X'].RB
324 print("RA", ra, d['RA'])
325 print("RB", rb, d['RB'])
326 print("RS", x)
327
328 for wname in gsc.parser.write_regs:
329 reg = getform[wname]
330 regidx = yield reg
331 print("write regs", regidx, wname, d[wname], reg)
332 gsc.gpr[regidx] = d[wname]
333
334 sim.add_process(process)
335 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
336 traces=decode.ports()):
337 sim.run()
338
339 gsc.gpr.dump()
340
341 for i in range(0, len(gsc.mem.mem), 16):
342 hexstr = []
343 for j in range(16):
344 hexstr.append("%02x" % gsc.mem.mem[i+j])
345 hexstr = ' '.join(hexstr)
346 print("mem %4x" % i, hexstr)
347
348
349 if __name__ == '__main__':
350 test()