1 from lib2to3
.pytree
import Node
, Leaf
2 from lib2to3
.pgen2
import token
3 from lib2to3
.pygram
import python_symbols
as syms
5 preamble
= """# this file has been generated by sv2nmigen
7 from nmigen import Signal, Module, Const, Cat, Elaboratable
14 def port_decl_do_not_use(comment
, dt
, name
):
15 if dt
is None or dt
.dims
is None:
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'
24 return 'self.%s = Signal(%s) # %s' % (name
, width
, comment
)
31 def __init__(self
, comment
, dt
, name
):
32 self
.comment
= comment
37 return port_decl_do_not_use(self
.comment
, self
.dt
, self
.name
)
41 def __init__(self
, left
, op
, right
):
47 return "Assignment:"+str(self
.left
) + " "+str(self
.op
)+" "+str(self
.right
)
51 def __init__(self
, cond
, ifpart
, elsepart
):
54 self
.elsepart
= elsepart
58 if(type(x
) == Assignment
):
60 elif(type(x
) == CondStatement
):
67 def __init__(self
, outputfn
):
68 self
.outputfn
= outputfn
69 self
.outputfile
= None
77 if(self
.outputfile
is None):
78 self
.outputfile
= open(self
.outputfn
, "w")
79 self
.outputfile
.write(preamble
)
83 self
.outputfile
.write(str(p
)+"\n")
90 def assign3(self
, left
, op
, right
):
91 return Assignment(left
, op
, right
)
93 def cond_statement3(self
, cond
, ifpart
, elsepart
):
94 return CondStatement(cond
, ifpart
, elsepart
)
96 def indent(self
, count
):
98 return Leaf(token
.INDENT
, '>>> '*count
)
100 return Leaf(token
.INDENT
, ' '*4*count
)
102 def dedent(self
, count
):
103 return Leaf(token
.DEDENT
, '')
106 return Leaf(token
.NEWLINE
, '\n')
108 def port_decl(self
, comment
, dt
, name
):
109 port
= PortDecl(comment
, dt
, name
)
113 def isPort(self
, name
):
115 if(str(p
.name
) == str(name
)):
119 def initFunc(self
, ports
, params
):
120 params
= [Leaf(token
.LPAR
, '('), Leaf(
121 token
.NAME
, "self")] + [Leaf(token
.RPAR
, ')')]
122 # TODO handle sv params
123 fn
= [Leaf(token
.NAME
, 'def'),
124 Leaf(token
.NAME
, '__init__', prefix
=' '),
125 Node(syms
.parameters
, params
),
126 Leaf(token
.COLON
, ':'),
129 fndef
= Node(syms
.funcdef
, fn
)
130 stmts
= Node(syms
.stmt
, [fndef
])
132 stmts
.children
.append(self
.indent(2))
133 stmts
.children
.append(port
.initNode())
134 stmts
.children
.append(self
.nl())
137 def do_assign(self
, a
, stmts
, indent
):
138 stmts
.children
.append(self
.indent(indent
))
139 stmts
.children
.append(Leaf(token
.STRING
, "m.d."))
140 stmts
.children
.append(Leaf(token
.STRING
, self
.blocktype
))
141 stmts
.children
.append(Leaf(token
.STRING
, " += "))
142 if(self
.isPort(a
.left
)):
143 stmts
.children
.append(Leaf(token
.STRING
, "self."))
144 stmts
.children
.append(Leaf(token
.STRING
, a
.left
))
145 stmts
.children
.append(Leaf(token
.STRING
, ".eq("))
146 if(self
.isPort(a
.right
)):
147 stmts
.children
.append(Leaf(token
.STRING
, "self."))
148 stmts
.children
.append(Leaf(token
.STRING
, a
.right
))
149 stmts
.children
.append(Leaf(token
.STRING
, ")"))
150 stmts
.children
.append(self
.nl())
152 def do_ifblock(self
, c
, stmts
, indent
):
153 stmts
.children
.append(self
.indent(indent
))
154 stmts
.children
.append(Leaf(token
.STRING
, "with m.If("))
155 if(self
.isPort(c
.cond
)):
156 stmts
.children
.append(Leaf(token
.STRING
, "self."))
157 stmts
.children
.append(Leaf(token
.STRING
, c
.cond
))
158 stmts
.children
.append(Leaf(token
.STRING
, "):"))
159 stmts
.children
.append(self
.nl())
161 for c1
in makeBlock(c
.ifpart
):
162 if(type(c1
) == Assignment
):
163 self
.do_assign(c1
, stmts
, indent
+1)
165 self
.do_ifblock(c1
, stmts
, indent
+1)
168 stmts
.children
.append(self
.indent(indent
))
169 stmts
.children
.append(Leaf(token
.STRING
, "with m.Else():"))
170 stmts
.children
.append(self
.nl())
172 for c1
in makeBlock(c
.elsepart
):
173 if(type(c1
) == Assignment
):
174 self
.do_assign(c1
, stmts
, indent
+1)
176 self
.do_ifblock(c1
, stmts
, indent
+1)
178 def elaborateFunc(self
):
179 params
= [Leaf(token
.LPAR
, '('), Leaf(
180 token
.NAME
, "self, platform=None"), Leaf(token
.RPAR
, ')')]
181 fn
= [Leaf(token
.NAME
, 'def'),
182 Leaf(token
.NAME
, 'elaborate', prefix
=' '),
183 Node(syms
.parameters
, params
),
184 Leaf(token
.COLON
, ':'),
187 fndef
= Node(syms
.funcdef
, fn
)
188 stmts
= Node(syms
.stmt
, [fndef
])
189 stmts
.children
.append(self
.indent(2))
190 stmts
.children
.append(Leaf(token
.STRING
, "m = Module()"))
191 stmts
.children
.append(self
.nl())
195 hasdims
= (len(w
) >= 4)
196 stmts
.children
.append(self
.indent(2))
197 stmts
.children
.append(Leaf(token
.STRING
, wirename
))
198 stmts
.children
.append(Leaf(token
.STRING
, " = Signal("))
200 stmts
.children
.append(Leaf(token
.STRING
, str(w
[3])))
201 stmts
.children
.append(Leaf(token
.STRING
, ")"))
202 stmts
.children
.append(self
.nl())
204 self
.blocktype
= "comb"
205 for a
in self
.assign
:
206 self
.do_assign(a
, stmts
, 2)
209 if(type(c
) == Assignment
):
210 self
.do_assign(c
, stmts
, 2)
212 self
.do_ifblock(c
, stmts
, 2)
214 self
.blocktype
= "sync"
216 if(type(c
) == Assignment
):
217 self
.do_assign(c
, stmts
, 2)
219 self
.do_ifblock(c
, stmts
, 2)
221 stmts
.children
.append(self
.indent(2))
222 stmts
.children
.append(Leaf(token
.STRING
, "return m"))
223 stmts
.children
.append(self
.nl())
226 def module_1(self
, p
):
229 clsname
= [Leaf(token
.NAME
, 'class'),
230 Leaf(token
.NAME
, p
[4], prefix
=' '),
231 Leaf(token
.LPAR
, '('),
232 Leaf(token
.NAME
, 'Elaboratable'),
233 Leaf(token
.LPAR
, ')'),
234 Leaf(token
.COLON
, ':'),
238 suite
= Node(syms
.suite
, [Leaf(token
.NEWLINE
, '\n'),
240 self
.initFunc(ports
, params
),
245 clsdecl
= Node(syms
.classdef
, clsname
+ [suite
])
246 clsdecl
= Node(syms
.compound_stmt
, [clsdecl
])
248 self
.printpy(str(clsdecl
))
251 def module_item_2(self
, signaltype
, dims
, mlist
):
252 if(signaltype
== "wire"):
255 self
.wires
.append(m
+dims
)
259 def appendComments(self
, data
):
261 self
.outputfile
.write(data
)
262 #lines = data.split("\n")
264 # self.printpy("#"+line)
266 # combinatorical assign
267 def cont_assign_1(self
, p
):
268 self
.assign
+= [Assignment(p
[1], p
[2], p
[3])]
270 # cond assigmments and other nested blocks
271 def always_comb(self
, p3
, p1
):
273 self
.comb
+= slist
.statements
275 def always_ff(self
, p3
, p1
):
277 self
.sync
+= slist
.statements