add memory get/set
[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
25 ####### Test code #######
26
27 bpermd = r"""
28 perm <- [0] * 8
29 if index < 64:
30 index <- (RS)[8*i:8*i+7]
31 RA <- [0]*56 || perm[0:7]
32 print (RA)
33 """
34
35 bpermd = r"""
36 if index < 64 then index <- 0
37 else index <- 5
38 do while index < 5
39 index <- 0
40 leave
41 for i = 0 to 7
42 index <- 0
43 """
44
45 _bpermd = r"""
46 for i = 0 to 7
47 index <- (RS)[8*i:8*i+7]
48 if index < 64 then
49 permi <- (RB)[index]
50 else
51 permi <- 0
52 RA <- [0]*56|| perm[0:7]
53 """
54
55 cnttzd = """
56 n <- 0
57 do while n < 64
58 print (n)
59 if (RS)[63-n] = 0b1 then
60 leave
61 n <- n + 1
62 RA <- EXTZ64(n)
63 print (RA)
64 """
65
66 cmpi = """
67 if a < EXTS(SI) then
68 c <- 0b100
69 else if a > EXTS(SI) then
70 c <- 0b010
71 """
72
73 cmpi = """
74 RA[0:1] <- 0b11
75 """
76
77 cmpi = """
78 in_range <- ((x | y) &
79 (a | b))
80 in_range <- (x + y) - (a + b)
81 """
82
83 cmpi = """
84 (RA)[0:1] <- 1
85 src1 <- EXTZ((RA)[56:63])
86 CR[4*BF+32] <- 0b0
87 in_range <- src21lo <= src1 & src1 <= src21hi
88 """
89
90 cmpeqb = """
91 src1 <- GPR[RA]
92 src1 <- src1[0:56]
93 """
94
95 addpcis = """
96 D <- d0||d1||d2
97 """
98
99 testmul = """
100 x <- [0] * 16
101 RT <- (RA) + EXTS(SI || [0]*16)
102 """
103
104 testgetzero = """
105 RS <- (RA|0)
106 RS <- RS + 1
107 print(RS)
108 """
109
110 testcat = """
111 RT <- (load_data[56:63] || load_data[48:55]
112 || load_data[40:47] || load_data[32:39]
113 || load_data[24:31] || load_data[16:23]
114 || load_data[8:15] || load_data[0:7])
115 """
116
117 testgpr = """
118 GPR(5) <- x
119 """
120 testmem = """
121 a <- (RA|0)
122 b <- (RB|0)
123 RA <- MEM(RB, 2)
124 EA <- a + 1
125 MEM(EA, 1) <- (RS)[56:63]
126 RB <- RA
127 RA <- EA
128 """
129 #code = testmul
130 #code = testgetzero
131 #code = testcat
132 #code = testgpr
133 code = testmem
134 #code = testreg
135 #code = cnttzd
136 #code = cmpi
137 #code = cmpeqb
138 #code = addpcis
139 #code = bpermd
140
141
142 def tolist(num):
143 l = []
144 for i in range(64):
145 l.append(1 if (num & (1 << i)) else 0)
146 l.reverse()
147 return l
148
149
150 def get_reg_hex(reg):
151 return hex(reg.value)
152
153 class Mem:
154
155 def __init__(self):
156 self.mem = []
157 for i in range(128):
158 self.mem.append(i)
159
160 def __call__(self, addr, sz):
161 res = []
162 for s in range(sz): # TODO: big/little-end
163 res.append(SelectableInt(self.mem[addr.value + s], 8))
164 print ("memread", addr, sz, res)
165 return selectconcat(*res)
166
167 def memassign(self, addr, sz, val):
168 print ("memassign", addr, sz, val)
169 for s in range(sz):
170 byte = (val.value) >> (s*8) & 0xff # TODO: big/little-end
171 self.mem[addr.value + s] = byte
172
173
174 class GPR(dict):
175 def __init__(self, sd, regfile):
176 dict.__init__(self)
177 self.sd = sd
178 for i in range(32):
179 self[i] = SelectableInt(regfile[i], 64)
180
181 def set_form(self, form):
182 self.form = form
183
184 def getz(self, rnum):
185 #rnum = rnum.value # only SelectableInt allowed
186 print("GPR getzero", rnum)
187 if rnum == 0:
188 return SelectableInt(0, 64)
189 return self[rnum]
190
191 def _get_regnum(self, attr):
192 getform = self.sd.sigforms[self.form]
193 rnum = getattr(getform, attr)
194 return rnum
195
196 def ___getitem__(self, attr):
197 print("GPR getitem", attr)
198 rnum = self._get_regnum(attr)
199 return self.regfile[rnum]
200
201
202 def convert_to_python(pcode):
203
204 gsc = GardenSnakeCompiler()
205
206 tree = gsc.compile(pcode, mode="exec", filename="string")
207 tree = ast.fix_missing_locations(tree)
208 regsused = {'read_regs': gsc.parser.read_regs,
209 'write_regs': gsc.parser.write_regs,
210 'uninit_regs': gsc.parser.uninit_regs}
211 return astor.to_source(tree), regsused
212
213
214 def test():
215
216 gsc = GardenSnakeCompiler()
217
218 gsc.regfile = {}
219 for i in range(32):
220 gsc.regfile[i] = i
221 gsc.gpr = GPR(gsc.parser.sd, gsc.regfile)
222 gsc.mem = Mem()
223
224 _compile = gsc.compile
225
226 tree = _compile(code, mode="single", filename="string")
227 tree = ast.fix_missing_locations(tree)
228 print(ast.dump(tree))
229
230 print("astor dump")
231 print(astor.dump_tree(tree))
232 print("to source")
233 source = astor.to_source(tree)
234 print(source)
235
236 # sys.exit(0)
237
238 # Set up the GardenSnake run-time environment
239 def print_(*args):
240 print("args", args)
241 print("-->", " ".join(map(str, args)))
242
243 from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,)
244
245 d = {}
246 d["print"] = print_
247 d["EXTS64"] = EXTS64
248 d["EXTZ64"] = EXTZ64
249 d["SelectableInt"] = SelectableInt
250 d["concat"] = selectconcat
251 d["GPR"] = gsc.gpr
252 d["MEM"] = gsc.mem
253 d["memassign"] = gsc.mem.memassign
254
255 form = 'X'
256 gsc.gpr.set_form(form)
257 getform = gsc.parser.sd.sigforms[form]._asdict()
258 #print ("getform", form)
259 # for k, f in getform.items():
260 #print (k, f)
261 #d[k] = getform[k]
262
263 compiled_code = compile(source, mode="exec", filename="<string>")
264
265 m = Module()
266 comb = m.d.comb
267 instruction = Signal(32)
268
269 m.submodules.decode = decode = gsc.parser.sd
270 comb += decode.raw_opcode_in.eq(instruction)
271 sim = Simulator(m)
272
273 instr = [0x11111117]
274
275 def process():
276 for ins in instr:
277 print("0x{:X}".format(ins & 0xffffffff))
278
279 # ask the decoder to decode this binary data (endian'd)
280 yield decode.bigendian.eq(0) # little / big?
281 yield instruction.eq(ins) # raw binary instr.
282 yield Delay(1e-6)
283
284 # uninitialised regs, drop them into dict for function
285 for rname in gsc.parser.uninit_regs:
286 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
287 print("uninitialised", rname, get_reg_hex(d[rname]))
288
289 # read regs, drop them into dict for function
290 for rname in gsc.parser.read_regs:
291 regidx = yield getattr(decode.sigforms['X'], rname)
292 d[rname] = gsc.gpr[regidx] # contents of regfile
293 d["_%s" % rname] = regidx # actual register value
294 print("read reg", rname, regidx, get_reg_hex(d[rname]))
295
296 exec(compiled_code, d) # code gets executed here in dict "d"
297 print("Done")
298
299 print(d.keys()) # shows the variables that may have been created
300
301 print(decode.sigforms['X'])
302 x = yield decode.sigforms['X'].RS
303 ra = yield decode.sigforms['X'].RA
304 rb = yield decode.sigforms['X'].RB
305 print("RA", ra, d['RA'])
306 print("RB", rb, d['RB'])
307 print("RS", x)
308
309 for wname in gsc.parser.write_regs:
310 reg = getform[wname]
311 regidx = yield reg
312 print("write regs", regidx, wname, d[wname], reg)
313 gsc.gpr[regidx] = d[wname]
314
315 sim.add_process(process)
316 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
317 traces=decode.ports()):
318 sim.run()
319
320 for i in range(len(gsc.gpr)):
321 print("regfile", i, get_reg_hex(gsc.gpr[i]))
322
323 for i in range(0, len(gsc.mem.mem), 16):
324 hexstr = []
325 for j in range(16):
326 hexstr.append("%02x" % gsc.mem.mem[i+j])
327 hexstr = ' '.join(hexstr)
328 print ("mem %4x" % i, hexstr)
329
330 if __name__ == '__main__':
331 test()