run autopep8
[sv2nmigen.git] / absyn.py
1 from lib2to3.pytree import Node, Leaf
2 from lib2to3.pgen2 import token
3 from lib2to3.pygram import python_symbols as syms
4
5 preamble = """# this file has been generated by sv2nmigen
6
7 from nmigen import Signal, Module, Const, Cat, Elaboratable
8
9
10
11 """
12
13
14 def port_decl_do_not_use(comment, dt, name):
15 if dt is None or dt.dims is None:
16 width = '' # width: 1
17 else:
18 width = dt.dims
19 # XXX TODO, better checking, should be using data structure... *sigh*
20 width = width[1:-1] # strip brackets
21 width = width.split(':')
22 assert width[0] == '0'
23 width = width[1]
24 return 'self.%s = Signal(%s) # %s' % (name, width, comment)
25
26
27 indent_debug = 0
28
29
30 class PortDecl:
31 def __init__(self, comment, dt, name):
32 self.comment = comment
33 self.dt = dt
34 self.name = name
35
36 def initNode(self):
37 return port_decl_do_not_use(self.comment, self.dt, self.name)
38
39
40 class Assignment:
41 def __init__(self, left, op, right):
42 self.left = left
43 self.op = op
44 self.right = right
45
46
47 class Absyn:
48 def __init__(self, outputfn):
49 self.outputfile = open(outputfn, "w")
50 self.outputfile.write(preamble)
51 self.assign = []
52 self.ports = []
53
54 def printpy(self, p):
55 self.outputfile.write(str(p)+"\n")
56
57 def assign(self, p):
58 p = list(p)
59 if(p[1] == "assign"):
60 self.printpy(p[4])
61 # m.d.comb += [l.eq(r)]
62
63 def indent(self, count):
64 if(indent_debug):
65 return Leaf(token.INDENT, '>>> '*count)
66 else:
67 return Leaf(token.INDENT, ' '*4*count)
68
69 def dedent(self, count):
70 return Leaf(token.DEDENT, '')
71
72 def nl(self):
73 return Leaf(token.NEWLINE, '\n')
74
75 def port_decl(self, comment, dt, name):
76 port = PortDecl(comment, dt, name)
77 self.ports += [port]
78 return port
79
80 def initFunc(self, ports, params):
81 params = [Leaf(token.LPAR, '('), Leaf(
82 token.NAME, "self")] + [Leaf(token.RPAR, ')')]
83 # TODO handle sv params
84 fn = [Leaf(token.NAME, 'def'),
85 Leaf(token.NAME, '__init__', prefix=' '),
86 Node(syms.parameters, params),
87 Leaf(token.COLON, ':'),
88 self.nl()
89 ]
90 fndef = Node(syms.funcdef, fn)
91 stmts = Node(syms.stmt, [fndef])
92 for port in ports:
93 stmts.children.append(self.indent(2))
94 stmts.children.append(port.initNode())
95 stmts.children.append(self.nl())
96 return stmts
97
98 def elaborateFunc(self):
99 params = [Leaf(token.LPAR, '('), Leaf(
100 token.NAME, "self, platform=None"), Leaf(token.RPAR, ')')]
101 fn = [Leaf(token.NAME, 'def'),
102 Leaf(token.NAME, 'elaborate', prefix=' '),
103 Node(syms.parameters, params),
104 Leaf(token.COLON, ':'),
105 self.nl()
106 ]
107 fndef = Node(syms.funcdef, fn)
108 stmts = Node(syms.stmt, [fndef])
109 stmts.children.append(self.indent(2))
110 stmts.children.append(Leaf(token.STRING, "m = Module()"))
111 stmts.children.append(self.nl())
112
113 for a in self.assign:
114 stmts.children.append(self.indent(2))
115 # m.d.sync += self.left.eq(right)
116 stmts.children.append(Leaf(token.STRING, "m.d.comb += self."))
117 stmts.children.append(Leaf(token.STRING, a.left))
118 stmts.children.append(Leaf(token.STRING, ".eq(self."))
119 stmts.children.append(Leaf(token.STRING, a.right))
120 stmts.children.append(Leaf(token.STRING, ")"))
121 stmts.children.append(self.nl())
122
123 # for a in self.assign:
124 #
125 #
126 #ports = a[8]
127 #
128
129 stmts.children.append(self.indent(2))
130 stmts.children.append(Leaf(token.STRING, "return m"))
131 stmts.children.append(self.nl())
132 return stmts
133
134 def module_1(self, p):
135 params = p[7]
136 ports = p[8]
137 clsname = [Leaf(token.NAME, 'class'),
138 Leaf(token.NAME, p[4], prefix=' '),
139 Leaf(token.LPAR, '('),
140 Leaf(token.NAME, 'Elaboratable'),
141 Leaf(token.LPAR, ')'),
142 Leaf(token.COLON, ':'),
143 self.nl(),
144 ]
145
146 suite = Node(syms.suite, [Leaf(token.NEWLINE, '\n'),
147 self.indent(1),
148 self.initFunc(ports, params),
149 self.indent(1),
150 self.elaborateFunc()
151
152 ])
153 clsdecl = Node(syms.classdef, clsname + [suite])
154 clsdecl = Node(syms.compound_stmt, [clsdecl])
155
156 self.printpy(str(clsdecl))
157 print("=====================")
158 print(str(clsdecl))
159 return clsdecl
160
161 def appendComments(self, data):
162 self.outputfile.write(data)
163 #lines = data.split("\n")
164 # for line in lines:
165 # self.printpy("#"+line)
166
167 # combinatorical assign
168 def cont_assign_1(self, p):
169 # print("#ASSIGN:BROKEN"+str(list(p)))
170 self.assign += [Assignment(p[1], p[2], p[3])]