construct switch/case/default from if/elif/elif/else
[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 code = switchtest
181 #code = lswx
182 #code = testcond
183 #code = testdo
184 #code = _bpermd
185 #code = testmul
186 #code = testgetzero
187 #code = testcat
188 #code = testgpr
189 #code = testmem
190 #code = testgprslice
191 #code = testreg
192 #code = cnttzd
193 #code = cmpi
194 #code = cmpeqb
195 #code = addpcis
196 #code = bpermd
197
198
199 def tolist(num):
200 l = []
201 for i in range(64):
202 l.append(1 if (num & (1 << i)) else 0)
203 l.reverse()
204 return l
205
206
207 def get_reg_hex(reg):
208 return hex(reg.value)
209
210 def convert_to_python(pcode):
211
212 gsc = GardenSnakeCompiler()
213
214 tree = gsc.compile(pcode, mode="exec", filename="string")
215 tree = ast.fix_missing_locations(tree)
216 regsused = {'read_regs': gsc.parser.read_regs,
217 'write_regs': gsc.parser.write_regs,
218 'uninit_regs': gsc.parser.uninit_regs}
219 return astor.to_source(tree), regsused
220
221
222 def test():
223
224 gsc = GardenSnakeCompiler(debug=True)
225
226 gsc.regfile = {}
227 for i in range(32):
228 gsc.regfile[i] = i
229 gsc.gpr = GPR(gsc.parser.sd, gsc.regfile)
230 gsc.mem = Mem()
231
232 _compile = gsc.compile
233
234 tree = _compile(code, mode="single", filename="string")
235 tree = ast.fix_missing_locations(tree)
236 print(ast.dump(tree))
237
238 print("astor dump")
239 print(astor.dump_tree(tree))
240 print("to source")
241 source = astor.to_source(tree)
242 print(source)
243
244 # sys.exit(0)
245
246 # Set up the GardenSnake run-time environment
247 def print_(*args):
248 print("args", args)
249 print("-->", " ".join(map(str, args)))
250
251 from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,)
252
253 d = {}
254 d["print"] = print_
255 d["EXTS64"] = EXTS64
256 d["EXTZ64"] = EXTZ64
257 d["SelectableInt"] = SelectableInt
258 d["concat"] = selectconcat
259 d["GPR"] = gsc.gpr
260 d["MEM"] = gsc.mem
261 d["memassign"] = gsc.mem.memassign
262
263 form = 'X'
264 gsc.gpr.set_form(form)
265 getform = gsc.parser.sd.sigforms[form]._asdict()
266 #print ("getform", form)
267 # for k, f in getform.items():
268 #print (k, f)
269 #d[k] = getform[k]
270
271 compiled_code = compile(source, mode="exec", filename="<string>")
272
273 m = Module()
274 comb = m.d.comb
275 instruction = Signal(32)
276
277 m.submodules.decode = decode = gsc.parser.sd
278 comb += decode.raw_opcode_in.eq(instruction)
279 sim = Simulator(m)
280
281 instr = [0x11111117]
282
283 def process():
284 for ins in instr:
285 print("0x{:X}".format(ins & 0xffffffff))
286
287 # ask the decoder to decode this binary data (endian'd)
288 yield decode.bigendian.eq(0) # little / big?
289 yield instruction.eq(ins) # raw binary instr.
290 yield Delay(1e-6)
291
292 # uninitialised regs, drop them into dict for function
293 for rname in gsc.parser.uninit_regs:
294 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
295 print("uninitialised", rname, hex(d[rname].value))
296
297 # read regs, drop them into dict for function
298 for rname in gsc.parser.read_regs:
299 regidx = yield getattr(decode.sigforms['X'], rname)
300 d[rname] = gsc.gpr[regidx] # contents of regfile
301 d["_%s" % rname] = regidx # actual register value
302 print("read reg", rname, regidx, hex(d[rname].value))
303
304 exec(compiled_code, d) # code gets executed here in dict "d"
305 print("Done")
306
307 print(d.keys()) # shows the variables that may have been created
308
309 print(decode.sigforms['X'])
310 x = yield decode.sigforms['X'].RS
311 ra = yield decode.sigforms['X'].RA
312 rb = yield decode.sigforms['X'].RB
313 print("RA", ra, d['RA'])
314 print("RB", rb, d['RB'])
315 print("RS", x)
316
317 for wname in gsc.parser.write_regs:
318 reg = getform[wname]
319 regidx = yield reg
320 print("write regs", regidx, wname, d[wname], reg)
321 gsc.gpr[regidx] = d[wname]
322
323 sim.add_process(process)
324 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
325 traces=decode.ports()):
326 sim.run()
327
328 gsc.gpr.dump()
329
330 for i in range(0, len(gsc.mem.mem), 16):
331 hexstr = []
332 for j in range(16):
333 hexstr.append("%02x" % gsc.mem.mem[i+j])
334 hexstr = ' '.join(hexstr)
335 print ("mem %4x" % i, hexstr)
336
337 if __name__ == '__main__':
338 test()