Closed Kuree closed 2 years ago
Your intuition is spot-on. We would like to eventually replace this with a check that all signals are driven and then enable direct lowering to a Verilog representation that is closer to the original Chisel-emitted FIRRTL description.
However, our primary concern has been to build a Scala FIRRTL Compiler (SFC) -equivalent Chisel compiler. SFC has always had an ExpandWhens
pass for two major reasons:
when
(which has last-connect semantics) to mux
(which effectively removes last-connect semantics) makes this analysis much easier.ExpandWhens
is much harder than writing them after all when
statements are removed.However, this is all SFC legacy stuff...
Why we're really doing this is that it's a lot easier to build an SFC-compliant FIRRTL compiler if we are doing the same lowerings. Part of building this has been running formal equivalence checking on SFC and MFC (MLIR-based FIRRTL Compiler, i.e., CIRCT) -produced Verilog as well as running large test suites on both. Getting formal equivalence to work or debugging test failures when the Verilog diff is large is borderline intractable. Hence, we've chosen to stay SFC-exact in our implementation and only deviate once we've replaced the SFC.
Another transform like this is LowerTypes
. A goal of the MFC is to preserve Chisel-defined aggregates. However, doing this from the beginning would be enormously risky... Hence, we implemented LowerTypes
and have only been slowly removing it (through a lot of hard work by @uenoku) and are at the point where we can preserve passive aggregates with an option and pass test suites.
However, our primary concern has been to build a Scala FIRRTL Compiler (SFC) -equivalent Chisel compiler.
That makes a lot of sense to me now. Thanks for the explanation, @seldridge.
A follow up question that's been troubling me when I'm trying to implement the symbol table. What is the best course of action for me to extract out conditional information given ExpandWhens
pass? This is critical for compute whether an emulated breakpoint should be triggered during simulation.
Closing this now since I've found a relatively easy way to deal with lowered muxes. Thanks for the clarification again!
Nice. I'm glad you got it sorted out.
Hello,
I'm a little bit confused about the purpose of
ExpandWhens
pass in Firrtl, which runs before the IR is lowered to HW. It seems to me that it tries to convert a more high-level construct (if statement) into low-level muxes. From a layperson's point of view, I fail to understand the benefits:if
statement insidealways_ff
block, so I don't think compatibility is an issue.if
statement over mux. This is because branch predictor works better thancmov
instruction. I believe Verilator has a pass that changes mux into if statement whenever possible. I could be wrong on this one.My outsider's suggestions is to replace this pass with a simple legality check pass, and lower
WhenOp
directly intoIfOp
during the Firrtl to HW pass. However, since I'm not familiar with circt, this could be much harder than I imagine. Please let me know if you have any suggestions.Best, Keyi