Skip to content

Instantly share code, notes, and snippets.

@jeanthom
Created August 5, 2020 14:46
Show Gist options
  • Save jeanthom/d77d5e3698472e5149283da98922a020 to your computer and use it in GitHub Desktop.
Save jeanthom/d77d5e3698472e5149283da98922a020 to your computer and use it in GitHub Desktop.
diff --git a/nmigen/back/rtlil.py b/nmigen/back/rtlil.py
index 100df5a..7581163 100644
--- a/nmigen/back/rtlil.py
+++ b/nmigen/back/rtlil.py
@@ -749,6 +749,9 @@ class _StatementCompiler(xfrm.StatementVisitor):
on_Assume = on_property
on_Cover = on_property
+ def on_Display(self, stmt):
+ pass
+
def on_Switch(self, stmt):
self._check_rhs(stmt.test)
diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py
index 55b825b..1686569 100644
--- a/nmigen/hdl/ast.py
+++ b/nmigen/hdl/ast.py
@@ -19,7 +19,7 @@ __all__ = [
"UserValue",
"Sample", "Past", "Stable", "Rose", "Fell", "Initial",
"Statement", "Switch",
- "Property", "Assign", "Assert", "Assume", "Cover",
+ "Property", "Assign", "Assert", "Assume", "Cover", "Display",
"ValueKey", "ValueDict", "ValueSet", "SignalKey", "SignalDict", "SignalSet",
]
@@ -1398,7 +1398,6 @@ class Property(Statement, MustUse):
def __repr__(self):
return "({} {!r})".format(self._kind, self.test)
-
@final
class Assert(Property):
_kind = "assert"
@@ -1413,6 +1412,29 @@ class Assume(Property):
class Cover(Property):
_kind = "cover"
+@final
+class Display(Statement):
+ _MustUse__warning = UnusedProperty
+
+ def __init__(self, text, *args):
+ super().__init__(src_loc_at=0)
+ self.text = text
+ self.args = args
+ self.test = Signal()
+ self._check = Signal(reset_less=True)
+ self._check.src_loc = self.src_loc
+ self._en = Signal(reset_less=True)
+ self._en.src_loc = self.src_loc
+
+ def _lhs_signals(self):
+ return SignalSet((self._en, self._check))
+
+ def _rhs_signals(self):
+ return self.test._rhs_signals()
+
+ def __repr__(self):
+ return "(display {!r})".format(self.text)
+
# @final
class Switch(Statement):
diff --git a/nmigen/hdl/dsl.py b/nmigen/hdl/dsl.py
index 12081ac..18dac05 100644
--- a/nmigen/hdl/dsl.py
+++ b/nmigen/hdl/dsl.py
@@ -484,7 +484,7 @@ class Module(_ModuleBuilderRoot, Elaboratable):
self._pop_ctrl()
for stmt in Statement.cast(assigns):
- if not compat_mode and not isinstance(stmt, (Assign, Assert, Assume, Cover)):
+ if not compat_mode and not isinstance(stmt, (Assign, Assert, Assume, Cover, Display)):
raise SyntaxError(
"Only assignments and property checks may be appended to d.{}"
.format(domain_name(domain)))
diff --git a/nmigen/hdl/xfrm.py b/nmigen/hdl/xfrm.py
index 6e0c209..9b4d273 100644
--- a/nmigen/hdl/xfrm.py
+++ b/nmigen/hdl/xfrm.py
@@ -190,6 +190,10 @@ class StatementVisitor(metaclass=ABCMeta):
def on_Cover(self, stmt):
pass # :nocov:
+ @abstractmethod
+ def on_Display(self, stmt):
+ pass # :nocov:
+
@abstractmethod
def on_Switch(self, stmt):
pass # :nocov:
@@ -213,6 +217,8 @@ class StatementVisitor(metaclass=ABCMeta):
new_stmt = self.on_Assume(stmt)
elif type(stmt) is Cover:
new_stmt = self.on_Cover(stmt)
+ elif type(stmt) is Display:
+ new_stmt = self.on_Display(stmt)
elif isinstance(stmt, Switch):
# Uses `isinstance()` and not `type() is` because nmigen.compat requires it.
new_stmt = self.on_Switch(stmt)
@@ -248,6 +254,9 @@ class StatementTransformer(StatementVisitor):
def on_Cover(self, stmt):
return Cover(self.on_value(stmt.test), _check=stmt._check, _en=stmt._en)
+ def on_Display(self, stmt):
+ return stmt
+
def on_Switch(self, stmt):
cases = OrderedDict((k, self.on_statement(s)) for k, s in stmt.cases.items())
return Switch(self.on_value(stmt.test), cases)
@@ -401,6 +410,7 @@ class DomainCollector(ValueVisitor, StatementVisitor):
on_Assert = on_property
on_Assume = on_property
on_Cover = on_property
+ on_Display = on_property
def on_Switch(self, stmt):
self.on_value(stmt.test)
@@ -606,6 +616,7 @@ class SwitchCleaner(StatementVisitor):
on_Assert = on_ignore
on_Assume = on_ignore
on_Cover = on_ignore
+ on_Display = on_ignore
def on_Switch(self, stmt):
cases = OrderedDict((k, self.on_statement(s)) for k, s in stmt.cases.items())
@@ -661,6 +672,7 @@ class LHSGroupAnalyzer(StatementVisitor):
on_Assert = on_property
on_Assume = on_property
on_Cover = on_property
+ on_Display = on_property
def on_Switch(self, stmt):
for case_stmts in stmt.cases.values():
@@ -696,6 +708,7 @@ class LHSGroupFilter(SwitchCleaner):
on_Assert = on_property
on_Assume = on_property
on_Cover = on_property
+ on_Display = on_property
class _ControlInserter(FragmentTransformer):
diff --git a/nmigen/sim/_pyrtl.py b/nmigen/sim/_pyrtl.py
index 14279ac..07c8380 100644
--- a/nmigen/sim/_pyrtl.py
+++ b/nmigen/sim/_pyrtl.py
@@ -370,6 +370,9 @@ class _StatementCompiler(StatementVisitor, _Compiler):
def on_Cover(self, stmt):
raise NotImplementedError # :nocov:
+ def on_Display(self, stmt):
+ self.emitter.append(f"print(\"{stmt.text}\")")
+
@classmethod
def compile(cls, state, stmt):
output_indexes = [state.get_signal(signal) for signal in stmt._lhs_signals()]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment