hdl.ast: give Assert and Assume their own src_loc.
authorwhitequark <whitequark@whitequark.org>
Sat, 19 Jan 2019 00:08:51 +0000 (00:08 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 19 Jan 2019 00:08:51 +0000 (00:08 +0000)
This helps with patterns like `Assert(fsm.ongoing("IDLE"))`, which
would otherwise point into nMigen internals.

nmigen/back/rtlil.py
nmigen/hdl/ast.py
nmigen/hdl/xfrm.py

index 7c0dda7c3d2f8e431b46f6f0412eb76980db563d..4d78b8286e9cca9e5b579935212cebd32a2bb97a 100644 (file)
@@ -617,7 +617,7 @@ class _StatementCompiler(xfrm.StatementVisitor):
         self.state.rtlil.cell("$assert", ports={
             "\\A": check_wire,
             "\\EN": en_wire,
-        }, src=src(stmt.test.src_loc))
+        }, src=src(stmt.src_loc))
 
     def on_Assume(self, stmt):
         self(stmt._check.eq(stmt.test))
@@ -628,7 +628,7 @@ class _StatementCompiler(xfrm.StatementVisitor):
         self.state.rtlil.cell("$assume", ports={
             "\\A": check_wire,
             "\\EN": en_wire,
-        }, src=src(stmt.test.src_loc))
+        }, src=src(stmt.src_loc))
 
     def on_Switch(self, stmt):
         self._check_rhs(stmt.test)
index 3ae5370eadeb629ff8ccef29b652da6bb4be50b3..bd66d45fbba8bc663c4f20dd72989f3ed5df88dc 100644 (file)
@@ -910,19 +910,21 @@ class Assign(Statement):
         return "(eq {!r} {!r})".format(self.lhs, self.rhs)
 
 
-class Assert(Statement):
+class Property(Statement):
     def __init__(self, test, _check=None, _en=None):
+        self.src_loc = tracer.get_src_loc()
+
         self.test = Value.wrap(test)
 
         self._check = _check
         if self._check is None:
-            self._check = Signal(reset_less=True, name="$assert$check")
-            self._check.src_loc = self.test.src_loc
+            self._check = Signal(reset_less=True, name="${}$check".format(self._kind))
+            self._check.src_loc = self.src_loc
 
         self._en = _en
         if _en is None:
-            self._en = Signal(reset_less=True, name="$assert$en")
-            self._en.src_loc = self.test.src_loc
+            self._en = Signal(reset_less=True, name="${}$en".format(self._kind))
+            self._en.src_loc = self.src_loc
 
     def _lhs_signals(self):
         return ValueSet((self._en, self._check))
@@ -931,31 +933,15 @@ class Assert(Statement):
         return self.test._rhs_signals()
 
     def __repr__(self):
-        return "(assert {!r})".format(self.test)
-
-
-class Assume(Statement):
-    def __init__(self, test, _check=None, _en=None):
-        self.test = Value.wrap(test)
-
-        self._check = _check
-        if self._check is None:
-            self._check = Signal(reset_less=True, name="$assume$check")
-            self._check.src_loc = self.test.src_loc
+        return "({} {!r})".format(self._kind, self.test)
 
-        self._en = _en
-        if self._en is None:
-            self._en = Signal(reset_less=True, name="$assume$en")
-            self._en.src_loc = self.test.src_loc
 
-    def _lhs_signals(self):
-        return ValueSet((self._en, self._check))
+class Assert(Property):
+    _kind = "assert"
 
-    def _rhs_signals(self):
-        return self.test._rhs_signals()
 
-    def __repr__(self):
-        return "(assume {!r})".format(self.test)
+class Assume(Property):
+    _kind = "assume"
 
 
 class Switch(Statement):
index 473139b900e53349afca77964bb425567e70093f..ca43cf5fdfce483b9d2c65e4a2ff88d229b2adfa 100644 (file)
@@ -190,18 +190,21 @@ class StatementVisitor(metaclass=ABCMeta):
 
     def on_statement(self, stmt):
         if type(stmt) is Assign:
-            return self.on_Assign(stmt)
+            new_stmt = self.on_Assign(stmt)
         elif type(stmt) is Assert:
-            return self.on_Assert(stmt)
+            new_stmt = self.on_Assert(stmt)
         elif type(stmt) is Assume:
-            return self.on_Assume(stmt)
+            new_stmt = self.on_Assume(stmt)
         elif isinstance(stmt, Switch):
             # Uses `isinstance()` and not `type() is` because nmigen.compat requires it.
-            return self.on_Switch(stmt)
+            new_stmt = self.on_Switch(stmt)
         elif isinstance(stmt, Iterable):
-            return self.on_statements(stmt)
+            new_stmt = self.on_statements(stmt)
         else:
-            return self.on_unknown_statement(stmt)
+            new_stmt = self.on_unknown_statement(stmt)
+        if hasattr(stmt, "src_loc") and hasattr(new_stmt, "src_loc"):
+            new_stmt.src_loc = stmt.src_loc
+        return new_stmt
 
     def __call__(self, value):
         return self.on_statement(value)