always_comb: handle if/else blocks
[sv2nmigen.git] / absyn.py
index ecd3846516ddf89e773c7b3bdb20754cf52e5e8b..413e51301580f81b58f54dd12e3e1b0dc6ebbc2b 100644 (file)
--- a/absyn.py
+++ b/absyn.py
@@ -43,6 +43,16 @@ class Assignment:
         self.op = op
         self.right = right
 
+    def debugInfo(self):
+        return "Assignment:"+str(self.left) + " "+str(self.op)+" "+str(self.right)
+
+
+class CondStatement:
+    def __init__(self, cond, ifpart, elsepart):
+        self.cond = cond
+        self.ifpart = ifpart
+        self.elsepart = elsepart
+
 
 class Absyn:
     def __init__(self, outputfn):
@@ -51,6 +61,7 @@ class Absyn:
         self.assign = []
         self.ports = []
         self.wires = []
+        self.comb = []
 
     def open(self):
         if(self.outputfile is None):
@@ -69,6 +80,9 @@ class Absyn:
     def assign3(self, left, op, right):
         return Assignment(left, op, right)
 
+    def cond_statement3(self, cond, ifpart, elsepart):
+        return CondStatement(cond, ifpart, elsepart)
+
     def indent(self, count):
         if(indent_debug):
             return Leaf(token.INDENT, '>>> '*count)
@@ -110,6 +124,45 @@ class Absyn:
             stmts.children.append(self.nl())
         return stmts
 
+    def do_assign(self, a, stmts, indent):
+        stmts.children.append(self.indent(indent))
+        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())
+
+    def do_ifblock(self, c, stmts, indent):
+        stmts.children.append(self.indent(indent))
+        stmts.children.append(Leaf(token.STRING, "with m.If("))
+        if(self.isPort(c.cond)):
+            stmts.children.append(Leaf(token.STRING, "self."))
+        stmts.children.append(Leaf(token.STRING, c.cond))
+        stmts.children.append(Leaf(token.STRING, "):"))
+        stmts.children.append(self.nl())
+
+        for c1 in c.ifpart.statements:
+            if(type(c1) == Assignment):
+                self.do_assign(c1, stmts, indent+1)
+            else:
+                self.do_ifblock(c1, stmts, indent+1)
+
+        if(c.elsepart):
+            stmts.children.append(self.indent(indent))
+            stmts.children.append(Leaf(token.STRING, "with m.Else():"))
+            stmts.children.append(self.nl())
+
+            for c1 in c.elsepart.statements:
+                if(type(c1) == Assignment):
+                    self.do_assign(c1, stmts, indent+1)
+                else:
+                    self.do_ifblock(c1, stmts, indent+1)
+
     def elaborateFunc(self):
         params = [Leaf(token.LPAR, '('), Leaf(
             token.NAME, "self, platform=None"), Leaf(token.RPAR, ')')]
@@ -136,19 +189,16 @@ class Absyn:
             stmts.children.append(Leaf(token.STRING, ")"))
             stmts.children.append(self.nl())
 
+        # refactor: assignments non cond
         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 += "))
-            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())
+            self.do_assign(a, stmts)
+
+        for c in self.comb:
+            print("comb", c)
+            if(type(c) == Assignment):
+                self.do_assign(c, stmts, 2)
+            else:
+                self.do_ifblock(c, stmts, 2)
 
         stmts.children.append(self.indent(2))
         stmts.children.append(Leaf(token.STRING, "return m"))
@@ -199,8 +249,8 @@ class Absyn:
     def cont_assign_1(self, p):
         self.assign += [Assignment(p[1], p[2], p[3])]
 
+    # cond assigmments and other nested blocks
     def always_comb(self, p3, p1):
         print("always_comb")
         slist = p3[6]
-        for s in slist.statements:
-            self.assign += [s]
+        self.comb += slist.statements