on_Assume = on_property
on_Cover = on_property
+ def on_Display(self, stmt):
+ pass
+
def on_Switch(self, stmt):
self._check_rhs(stmt.test)
"UserValue", "ValueCastable",
"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",
]
def __repr__(self):
return "({} {!r})".format(self._kind, self.test)
-
@final
class Assert(Property):
_kind = "assert"
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):
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)))
def on_Cover(self, stmt):
pass # :nocov:
+ @abstractmethod
+ def on_Display(self, stmt):
+ pass # :nocov:
+
@abstractmethod
def on_Switch(self, stmt):
pass # :nocov:
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)
def on_Cover(self, stmt):
return Cover(self.on_value(stmt.test), _check=stmt._check, _en=stmt._en)
+ def on_Display(self, stmt):
+ # args = [self.on_value(arg) for arg in stmt.args]
+ # return Display(stmt.text, *args)
+ stmt.args = [self.on_value(arg) for arg in stmt.args]
+ 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)
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)
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())
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():
on_Assert = on_property
on_Assume = on_property
on_Cover = on_property
+ on_Display = on_property
class _ControlInserter(FragmentTransformer):
def on_Cover(self, stmt):
raise NotImplementedError # :nocov:
+ def on_Display(self, stmt):
+ args = []
+ for i in range(len(stmt.args)):
+ arg = self.emitter.def_var(f"args{i}", f"{self.rhs(stmt.args[i])} & {(1 << len(stmt.args[i])) - 1}")
+ args.append(arg)
+ self.emitter.append(f"print(\"{stmt.text}\" % tuple([{','.join(args)}]))")
+
@classmethod
def compile(cls, state, stmt):
output_indexes = [state.get_signal(signal) for signal in stmt._lhs_signals()]