[Do-Not-Merge][FIRRTL][Sim][SV] Rework printf
lowering pipeline
#7973
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Do not merge!
This PR is intended to demonstrate and discuss a lowering pipeline for FIRRTL
printf
operations to SV using thesim
dialect infrastructure, notably thesim.proc.print
operation and the to-be-added trigger operations (#7676). The code is still rough and obviously not meant to be merged like this. But I'd like to give everyone the opportunity to try it out and talk about the general shape of it before I start breaking out chunks into separate PRs.The relevant/affected passes are:
This PR also adds the
sim.trigger_gate
operation, which can be used to conditionally disable portions of a trigger tree. This allows us to lower conditional prints without having to rely onscf.if
.I think the first point worth discussing is the ordering requirement on print operations. The current version of the FIRRTL spec (v4.0.0) states in section 16.1:
Going by the discussion with @seldridge in the ODM a couple of weeks ago this is effectively outdated. Since it is not obvious when two clock edges have to be considered to be the same, this requirement is hard to enforce. So, instead, any order should be considered legal. That's how I've implemented the conversion in
FIRRTLToHW
. Specifically, it does not create anysim.trigger_sequence
op, which would impose an hard ordering requirement on its users.On the other hand, @seldridge mentioned a "gentleman's agreement" to try and maintain the order of prints during compilation whenever possible. This is achieved by the
SerializeTriggers
pass, which runs right afterFIRRTLToHW
and removes any concurrency/non-determinism for triggered operations that are part of the same trigger tree at this point during compilation. It does so by insertingsim.trigger_sequence
ops at any point where a trigger-typed value has more than one user. The produced sequence - conveniently - follows the syntactic order of its users.Trying this all out in practice, running this chisel example through
firtool
yields:Note that if we were to run CSE between FIRRTLToHW and SerializeTriggers, we'd get this instead:
Which would be legal, but probably not match the user's expectations. Having these sort of shifts for non-obvious reasons makes me a little uneasy (in this case it is caused by CSEing trigger gates). But unless we go deep into clock domains to clearly define which clocks are the same, I think we'll have to live with this to some extent.
For reference, this is what the current
main
branch firtool produces for the same input:There is more stuff to talk about, but I'll spare you any more walls of text before the holidays. 😉