Basic checker capabilities
We need an equivalent for Verilog's assume / assert.
Using Ready/Valid Protocol Primer as a starting point, for Tx/Rx implement the following checks:
NeverReadyUnknown(control signals cannot be X after reset)ReadyStable(sequential protocol check: ready cannot deassert until transfer happens)NeverValidUnknown(control signals cannot be X after reset)NeverDataUnknown(if valid, data cannot be X)ValidDataStable(sequential protocol check: valid cannot deassert and data must not change until transfer happens)
Assume and assert will be functionally the same thing. Since we're not attempting to do anything w/ formal verification, they can serve as a hint to the reader whether check is for an input or output.
Architecture question: How to fail? Throw an exception, and likely exit the main sim loop? Implement a logging error system where user can choose to fail on N checker fails? Not sure about this.
Not in scope:
- Cover properties (no coverage infra yet)
- Global assume/assert disable
$assertoffcapabilities
Couple of ideas:
Every assume/assert is implemented as a generic state machine. The user needs to provide the 1) next state function, and 2) list of checks to perform in each state.
Instead of Python assert, implement new exceptions, AssumeError, and AssertError. Figure out where they should be handled.
SystemVerilog has a sequence construct. Might be a useful abstraction.
Need concurrent assertions. The base task runs forever, and forks checkers whenever its antecedent condition is met. This is different than the idea of implementing the checker as a state machine. To avoid pathological explosion of tasks, maybe implement a timeout?
I think I have something basically functional. At least a few questions still remaining:
- Naming, obviously
- How to enable/disable the base coroutine (the one that kicks off checkers)
- How precisely to fail (I still think raising
AssertErroris fine).
Reviewing structured concurrency for deltacycle. Might prefer to punt the exception idea for the time being. Just use logger.error(...) until I can figure out the right overall process structure.