split parser into separate module
[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
17 from soc.decoder.power_decoder import create_pdecode
18 from nmigen.back.pysim import Simulator, Delay
19 from nmigen import Module, Signal
20
21 from soc.decoder.pseudo.lexer import IndentLexer
22 from soc.decoder.pseudo.parser import GardenSnakeCompiler
23
24 ####### Test code #######
25
26 bpermd = r"""
27 perm <- [0] * 8
28 if index < 64:
29 index <- (RS)[8*i:8*i+7]
30 RA <- [0]*56 || perm[0:7]
31 print (RA)
32 """
33
34 bpermd = r"""
35 if index < 64 then index <- 0
36 else index <- 5
37 do while index < 5
38 index <- 0
39 leave
40 for i = 0 to 7
41 index <- 0
42 """
43
44 _bpermd = r"""
45 for i = 0 to 7
46 index <- (RS)[8*i:8*i+7]
47 if index < 64 then
48 permi <- (RB)[index]
49 else
50 permi <- 0
51 RA <- [0]*56|| perm[0:7]
52 """
53
54 cnttzd = """
55 n <- 0
56 do while n < 64
57 if (RS)[63-n] = 0b1 then
58 leave
59 n <- n + 1
60 RA <- EXTZ64(n)
61 print (RA)
62 """
63
64 #code = testreg
65 code = cnttzd
66 #code = bpermd
67
68 #lexer = IndentLexer(debug=1)
69 # Give the lexer some input
70 #print ("code")
71 #print (code)
72 #lexer.input(code)
73
74 # Tokenize
75 while False:
76 tok = lexer.token()
77 if not tok:
78 break # No more input
79 print(tok)
80
81 #sys.exit(0)
82
83 def tolist(num):
84 l = []
85 for i in range(64):
86 l.append(1 if (num & (1<<i)) else 0)
87 l.reverse()
88 return l
89
90
91 def get_reg_hex(reg):
92 report = ''.join(map(str, reg))
93 return hex(int('0b%s' % report, 2))
94
95
96 gsc = GardenSnakeCompiler()
97 class GPR(dict):
98 def __init__(self, sd, regfile):
99 dict.__init__(self)
100 self.sd = sd
101 self.regfile = regfile
102 for i in range(32):
103 self[i] = [0] * 64
104
105 def set_form(self, form):
106 self.form = form
107
108 def ___getitem__(self, attr):
109 print ("GPR getitem", attr)
110 getform = self.sd.sigforms[self.form]
111 rnum = getattr(getform, attr)
112 print ("GPR get", rnum, rnum, dir(rnum))
113 l = list(rnum)
114 print (l[0]._as_const())
115 #for x in rnum:
116 #print (x, x.value, dir(x))
117 #print (x.value, dir(x.value))
118 print (list(rnum))
119 return self.regfile[rnum]
120
121
122 gsc.regfile = {}
123 for i in range(32):
124 gsc.regfile[i] = 0
125 gsc.gpr = GPR(gsc.parser.sd, gsc.regfile)
126
127 _compile = gsc.compile
128
129 def test():
130 tree = _compile(code, mode="single", filename="string")
131 import ast
132 tree = ast.fix_missing_locations(tree)
133 print ( ast.dump(tree) )
134
135 print ("astor dump")
136 print (astor.dump_tree(tree))
137 print ("to source")
138 source = astor.to_source(tree)
139 print (source)
140
141 #sys.exit(0)
142
143 # Set up the GardenSnake run-time environment
144 def print_(*args):
145 print ("args", args)
146 print ("-->", " ".join(map(str,args)))
147
148 def listconcat(l1, l2):
149 return l1 + l2
150
151 from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,)
152
153 d = {}
154 d["print"] = print_
155 d["EXTS64"] = EXTS64
156 d["EXTZ64"] = EXTZ64
157 d["concat"] = listconcat
158 d["GPR"] = gsc.gpr
159
160 form = 'X'
161 gsc.gpr.set_form(form)
162 getform = gsc.parser.sd.sigforms[form]._asdict()
163 #print ("getform", form)
164 #for k, f in getform.items():
165 #print (k, f)
166 #d[k] = getform[k]
167
168 compiled_code = compile(source, mode="exec", filename="<string>")
169
170 m = Module()
171 comb = m.d.comb
172 instruction = Signal(32)
173
174 m.submodules.decode = decode = gsc.parser.sd
175 comb += decode.raw_opcode_in.eq(instruction)
176 sim = Simulator(m)
177
178 instr = [0x11111117]
179
180 def process():
181 for ins in instr:
182 print("0x{:X}".format(ins & 0xffffffff))
183
184 # ask the decoder to decode this binary data (endian'd)
185 yield decode.bigendian.eq(0) # little / big?
186 yield instruction.eq(ins) # raw binary instr.
187 yield Delay(1e-6)
188
189 # read regs, drop them into dict for function
190 for rname in gsc.parser.read_regs:
191 regidx = yield getattr(decode.sigforms['X'], rname)
192 d[rname] = gsc.gpr[regidx]
193 print ("read reg", rname, regidx, get_reg_hex(d[rname]))
194
195 exec (compiled_code, d)
196 print ("Done")
197
198 print (d.keys())
199
200 print (decode.sigforms['X'])
201 x = yield decode.sigforms['X'].RS
202 ra = yield decode.sigforms['X'].RA
203 print ("RA", ra, d['RA'])
204 print ("RS", x)
205
206 for wname in gsc.parser.write_regs:
207 reg = getform[wname]
208 print ("write regs", wname, d[wname], reg)
209 regidx = yield reg
210 gsc.gpr[regidx] = tolist(d[wname])
211
212 sim.add_process(process)
213 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
214 traces=[decode.ports()]):
215 sim.run()
216
217 for i in range(len(gsc.gpr)):
218 print ("regfile", i, get_reg_hex(gsc.gpr[i]))
219
220
221 if __name__ == '__main__':
222 test()