X-Git-Url: https://git.libre-soc.org/?p=sv2nmigen.git;a=blobdiff_plain;f=absyn.py;h=d52250206719fbefcd53b2dba3c660b529f8ef9a;hp=c59f8b6dc559fc6c04f626ccf80702c9da8615ba;hb=c2475e188a965c7f34e28d3d022205f9a97ed215;hpb=1a995ea028ff7f563f1d453f7736bd548120b604 diff --git a/absyn.py b/absyn.py index c59f8b6..d522502 100644 --- a/absyn.py +++ b/absyn.py @@ -1,5 +1,153 @@ +from lib2to3.pytree import Node, Leaf +from lib2to3.pgen2 import token +from lib2to3.pygram import python_symbols as syms + +preamble = """# this file has been generated by sv2nmigen + +from nmigen import Signal, Module, Const, Cat, Elaboratable + + + +""" + +def port_decl_do_not_use(comment, dt, name): + if dt is None or dt.dims is None: + width = '' # width: 1 + else: + width = dt.dims + # XXX TODO, better checking, should be using data structure... *sigh* + width = width[1:-1] # strip brackets + width = width.split(':') + assert width[0] == '0' + width = width[1] + return 'self.%s = Signal(%s) # %s' % (name, width, comment) + +indent_debug = 0 + +class PortDecl: + def __init__(self,comment,dt,name): + self.comment = comment + self.dt=dt + self.name=name + def initNode(self): + return port_decl_do_not_use(self.comment,self.dt,self.name) + +class Assignment: + def __init__(self,left,op,right): + self.left = left + self.op = op + self.right = right + class Absyn: def __init__(self): self.outputfile = open("output.py","w") + self.outputfile.write(preamble) + self.assign = [] + self.ports = [] def printpy(self,p): self.outputfile.write(str(p)+"\n") + def assign(self,p): + p = list(p) + if(p[1]=="assign"): + self.printpy(p[4]) + # m.d.comb += [l.eq(r)] + def indent(self,count): + if(indent_debug): + return Leaf(token.INDENT, '>>> '*count) + else: + return Leaf(token.INDENT, ' '*4*count) + + def dedent(self,count): + return Leaf(token.DEDENT, '') + def nl(self): + return Leaf(token.NEWLINE, '\n') + + def port_decl(self,comment, dt, name): + port = PortDecl(comment,dt,name) + self.ports += [port] + return port + + def initFunc(self,ports,params): + params = [Leaf(token.LPAR, '('),Leaf(token.NAME,"self")] + [Leaf(token.RPAR, ')')] + # TODO handle sv params + fn = [Leaf(token.NAME, 'def'), + Leaf(token.NAME, '__init__', prefix=' '), + Node(syms.parameters, params), + Leaf(token.COLON, ':'), + self.nl() + ] + fndef = Node(syms.funcdef, fn) + stmts = Node(syms.stmt, [fndef]) + for port in ports: + stmts.children.append(self.indent(2)) + stmts.children.append(port.initNode()) + stmts.children.append(self.nl()) + return stmts + + def elaborateFunc(self): + params = [Leaf(token.LPAR, '('),Leaf(token.NAME,"self, platform=None"),Leaf(token.RPAR, ')')] + fn = [Leaf(token.NAME, 'def'), + Leaf(token.NAME, 'elaborate', prefix=' '), + Node(syms.parameters, params), + Leaf(token.COLON, ':'), + self.nl() + ] + fndef = Node(syms.funcdef, fn) + stmts = Node(syms.stmt, [fndef]) + stmts.children.append(self.indent(2)) + stmts.children.append(Leaf(token.STRING,"m = Module()")) + stmts.children.append(self.nl()) + + + for a in self.assign: + stmts.children.append(self.indent(2)) + # m.d.sync += self.left.eq(right) + stmts.children.append(Leaf(token.STRING,"m.d.comb += self.")) + stmts.children.append(Leaf(token.STRING,a.left)) + stmts.children.append(Leaf(token.STRING,".eq(self.")) + stmts.children.append(Leaf(token.STRING,a.right)) + stmts.children.append(Leaf(token.STRING,")")) + stmts.children.append(self.nl()) + + #for a in self.assign: + # + # + #ports = a[8] + # + + stmts.children.append(self.indent(2)) + stmts.children.append(Leaf(token.STRING,"return m")) + stmts.children.append(self.nl()) + return stmts + + def module_1(self,p): + params = p[7] + ports = p[8] + clsname = [Leaf(token.NAME, 'class'), + Leaf(token.NAME, p[4], prefix=' '), + Leaf(token.LPAR,'('), + Leaf(token.NAME, 'Elaboratable'), + Leaf(token.LPAR,')'), + Leaf(token.COLON, ':'), + self.nl(), + ] + + suite = Node(syms.suite, [Leaf(token.NEWLINE, '\n'), + self.indent(1), + self.initFunc(ports,params), + self.indent(1), + self.elaborateFunc() + + ]) + clsdecl = Node(syms.classdef, clsname + [suite]) + clsdecl = Node(syms.compound_stmt, [clsdecl]) + + self.printpy(str(clsdecl)) + print("=====================") + print(str(clsdecl)) + return clsdecl + + # combinatorical assign + def cont_assign_1(self,p): + print("#ASSIGN:BROKEN"+str(list(p))) + self.assign += [Assignment(p[1],p[2],p[3])]