wire assignments
[sv2nmigen.git] / absyn.py
index 6ccbb0529944f48fcc57d1578f573bfcd8cffd10..a199daa4da6846ebe31ddf19fe9015248d712107 100644 (file)
--- a/absyn.py
+++ b/absyn.py
@@ -10,72 +10,96 @@ 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
+        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[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):
+    def __init__(self, comment, dt, name):
         self.comment = comment
-        self.dt=dt
-        self.name=name
+        self.dt = dt
+        self.name = name
+
     def initNode(self):
-        return port_decl_do_not_use(self.comment,self.dt,self.name)
+        return port_decl_do_not_use(self.comment, self.dt, self.name)
+
 
 class Assignment:
-    def __init__(self,left,op,right):
+    def __init__(self, left, op, right):
         self.left = left
         self.op = op
         self.right = right
 
+
 class Absyn:
-    def __init__(self,outputfn):
-        self.outputfile = open(outputfn,"w")
-        self.outputfile.write(preamble)
+    def __init__(self, outputfn):
+        self.outputfn = outputfn
+        self.outputfile = None
         self.assign = []
         self.ports = []
-    def printpy(self,p):
+        self.wires = []
+
+    def open(self):
+        if(self.outputfile is None):
+            self.outputfile = open(self.outputfn, "w")
+            self.outputfile.write(preamble)
+
+    def printpy(self, p):
+        self.open()
         self.outputfile.write(str(p)+"\n")
-    def assign(self,p):
+
+    def assign(self, p):
         p = list(p)
-        if(p[1]=="assign"):
+        if(p[1] == "assign"):
             self.printpy(p[4])
             # m.d.comb += [l.eq(r)]
-    def indent(self,count):
+
+    def indent(self, count):
         if(indent_debug):
             return Leaf(token.INDENT, '>>> '*count)
         else:
             return Leaf(token.INDENT, ' '*4*count)
-    
-    def dedent(self,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)
+
+    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, ')')]
+    def isPort(self, name):
+        for p in self.ports:
+            if(str(p.name) == str(name)):
+                return True
+        return False
+
+    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:
@@ -85,74 +109,97 @@ class Absyn:
         return stmts
 
     def elaborateFunc(self):
-        params = [Leaf(token.LPAR, '('),Leaf(token.NAME,"self, platform=None"),Leaf(token.RPAR, ')')]
+        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(Leaf(token.STRING, "m = Module()"))
         stmts.children.append(self.nl())
-        
+
+        for w in self.wires:
+            wirename = w[0]
+            hasdims = (len(w) >= 4)
+            stmts.children.append(self.indent(2))
+            stmts.children.append(Leaf(token.STRING, wirename))
+            stmts.children.append(Leaf(token.STRING, " = Signal("))
+            if(hasdims):
+                stmts.children.append(Leaf(token.STRING, str(w[3])))
+            stmts.children.append(Leaf(token.STRING, ")"))
+            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(Leaf(token.STRING, "m.d.comb += "))
+            if(self.isPort(a.left)):
+                stmts.children.append(Leaf(token.STRING, "self."))
+            stmts.children.append(Leaf(token.STRING, a.left))
+            stmts.children.append(Leaf(token.STRING, ".eq("))
+            if(self.isPort(a.right)):
+                stmts.children.append(Leaf(token.STRING, "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:
-        #    
+
+        # 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.indent(2))
+        stmts.children.append(Leaf(token.STRING, "return m"))
         stmts.children.append(self.nl())
         return stmts
-        
-    def module_1(self,p):
+
+    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.LPAR, '('),
                    Leaf(token.NAME, 'Elaboratable'),
-                   Leaf(token.LPAR,')'),
+                   Leaf(token.LPAR, ')'),
                    Leaf(token.COLON, ':'),
                    self.nl(),
-        ]
+                   ]
 
         suite = Node(syms.suite, [Leaf(token.NEWLINE, '\n'),
                                   self.indent(1),
-                                  self.initFunc(ports,params),
+                                  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
 
-    def appendComments(self,data):
-        lines = data.split("\n")
-        for line in lines:
-            self.printpy("#"+line)
+    def module_item_2(self, signaltype, dims, mlist):
+        if(signaltype == "wire"):
+            for m in mlist:
+                if(dims):
+                    self.wires.append(m+dims)
+                else:
+                    self.wires.append(m)
+
+    def appendComments(self, data):
+        self.open()
+        self.outputfile.write(data)
+        #lines = data.split("\n")
+        # for line in lines:
+        #    self.printpy("#"+line)
 
     # combinatorical assign
-    def cont_assign_1(self,p):
-       # print("#ASSIGN:BROKEN"+str(list(p)))
-       self.assign += [Assignment(p[1],p[2],p[3])]
+    def cont_assign_1(self, p):
+        # print("#ASSIGN:BROKEN"+str(list(p)))
+        self.assign += [Assignment(p[1], p[2], p[3])]