Fixes #194.
-from .hdl.ast import AnyConst, AnySeq, Assert, Assume
+from .hdl.ast import AnyConst, AnySeq, Assert, Assume, Cover
from .hdl.ast import Past, Stable, Rose, Fell, Initial
def on_Assume(self, stmt):
pass # :nocov:
+ def on_Cover(self, stmt):
+ raise NotImplementedError("Covers not yet implemented for Simulator backend.") # :nocov:
+
def on_Switch(self, stmt):
test = self.rrhs_compiler(stmt.test)
cases = []
else:
self._case.assign(self.lhs_compiler(stmt.lhs), rhs_sigspec)
- def on_Assert(self, stmt):
+ def on_property(self, stmt):
self(stmt._check.eq(stmt.test))
self(stmt._en.eq(1))
en_wire = self.rhs_compiler(stmt._en)
check_wire = self.rhs_compiler(stmt._check)
- self.state.rtlil.cell("$assert", ports={
+ self.state.rtlil.cell("$" + stmt._kind, ports={
"\\A": check_wire,
"\\EN": en_wire,
}, src=src(stmt.src_loc))
- def on_Assume(self, stmt):
- self(stmt._check.eq(stmt.test))
- self(stmt._en.eq(1))
-
- en_wire = self.rhs_compiler(stmt._en)
- check_wire = self.rhs_compiler(stmt._check)
- self.state.rtlil.cell("$assume", ports={
- "\\A": check_wire,
- "\\EN": en_wire,
- }, src=src(stmt.src_loc))
+ on_Assert = on_property
+ on_Assume = on_property
+ on_Cover = on_property
def on_Switch(self, stmt):
self._check_rhs(stmt.test)
"Signal", "ClockSignal", "ResetSignal",
"UserValue",
"Sample", "Past", "Stable", "Rose", "Fell", "Initial",
- "Statement", "Assign", "Assert", "Assume", "Switch", "Delay", "Tick",
+ "Statement", "Assign", "Assert", "Assume", "Cover", "Switch", "Delay", "Tick",
"Passive", "ValueKey", "ValueDict", "ValueSet", "SignalKey", "SignalDict",
"SignalSet",
]
_kind = "assume"
+@final
+class Cover(Property):
+ _kind = "cover"
+
+
# @final
class Switch(Statement):
def __init__(self, test, cases, *, src_loc=None, src_loc_at=0, case_src_locs={}):
self._pop_ctrl()
for assign in Statement.wrap(assigns):
- if not compat_mode and not isinstance(assign, (Assign, Assert, Assume)):
+ if not compat_mode and not isinstance(assign, (Assign, Assert, Assume, Cover)):
raise SyntaxError(
- "Only assignments, asserts, and assumes may be appended to d.{}"
+ "Only assignments and property checks may be appended to d.{}"
.format(domain_name(domain)))
assign = SampleDomainInjector(domain)(assign)
def on_Assume(self, stmt):
pass # :nocov:
+ @abstractmethod
+ def on_Cover(self, stmt):
+ pass # :nocov:
+
@abstractmethod
def on_Switch(self, stmt):
pass # :nocov:
new_stmt = self.on_Assert(stmt)
elif type(stmt) is Assume:
new_stmt = self.on_Assume(stmt)
+ elif type(stmt) is Cover:
+ new_stmt = self.on_Cover(stmt)
elif isinstance(stmt, Switch):
# Uses `isinstance()` and not `type() is` because nmigen.compat requires it.
new_stmt = self.on_Switch(stmt)
def on_Assume(self, stmt):
return Assume(self.on_value(stmt.test), _check=stmt._check, _en=stmt._en)
+ def on_Cover(self, stmt):
+ return Cover(self.on_value(stmt.test), _check=stmt._check, _en=stmt._en)
+
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)
self.on_value(stmt.lhs)
self.on_value(stmt.rhs)
- def on_Assert(self, stmt):
+ def on_property(self, stmt):
self.on_value(stmt.test)
- def on_Assume(self, stmt):
- self.on_value(stmt.test)
+ on_Assert = on_property
+ on_Assume = on_property
+ on_Cover = on_property
def on_Switch(self, stmt):
self.on_value(stmt.test)
class SwitchCleaner(StatementVisitor):
- def on_Assign(self, stmt):
+ def on_ignore(self, stmt):
return stmt
- on_Assert = on_Assign
-
- on_Assume = on_Assign
+ on_Assign = on_ignore
+ on_Assert = on_ignore
+ on_Assume = on_ignore
+ on_Cover = on_ignore
def on_Switch(self, stmt):
cases = OrderedDict((k, self.on_statement(s)) for k, s in stmt.cases.items())
if lhs_signals:
self.unify(*stmt._lhs_signals())
- on_Assert = on_Assign
+ def on_property(self, stmt):
+ lhs_signals = stmt._lhs_signals()
+ if lhs_signals:
+ self.unify(*stmt._lhs_signals())
- on_Assume = on_Assign
+ on_Assert = on_property
+ on_Assume = on_property
+ on_Cover = on_property
def on_Switch(self, stmt):
for case_stmts in stmt.cases.values():
if any_lhs_signal in self.signals:
return stmt
- def on_Assert(self, stmt):
+ def on_property(self, stmt):
any_lhs_signal = next(iter(stmt._lhs_signals()))
if any_lhs_signal in self.signals:
return stmt
- on_Assume = on_Assert
+ on_Assert = on_property
+ on_Assume = on_property
+ on_Cover = on_property
class _ControlInserter(FragmentTransformer):
def test_d_asgn_wrong(self):
m = Module()
with self.assertRaises(SyntaxError,
- msg="Only assignments, asserts, and assumes may be appended to d.sync"):
+ msg="Only assignments and property checks may be appended to d.sync"):
m.d.sync += Switch(self.s1, {})
def test_comb_wrong(self):