-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial debugging support for circt #2581
base: main
Are you sure you want to change the base?
Conversation
This is great to see! I would definitely support getting debug tools working with circt and the chisel flow. I'll take a more detailed look tomorrow at the PR. For the two points you noted, I think the Chisel source locators likely need some improvement. This is probably a but on the chisel side that needs to be dealt with. For scoping, do you mean in relation to regs or vals declared inside whens or something else? |
Yes. For instance, the user can declares variable here: I'd like to represent them as local variables if possible.
Thanks! I will try to fix the CI in the meantime. |
This is very, very cool @Kuree! Thanks for hacking it up for CIRCT! |
Added - Preliminary debugging support for HGDB backend - Debug name tracking from Firrtl to HW Changed - Add `--hgdb` command line arg to generate symbol table
…ormation, debug attributes is added to the module
Squashed git commits: - insert debug attr to ports that don't require lowering - disable temp wire optimziation so that named symbols from firrtl will show up in the symbol table - relax scope line requirement; fix scope filename due to more inclusive debug attribute insertion - sort the scope to reflect the actual order - leave the sorting issue to hgdb instead; add variable decl construct - use condition as a key as well during blocking merging process - use variable reference instead of raw variable definition to save space - Fix expression print in conditions
2. Add mux analysis to reverse ExpandWhens to compute the symbol table
Hi @Kuree, sorry for the long delay, but I have been poking at this change on-and-off. I have one specific point to bring up: can we move the HGDB symbol table export to work at the level of the HW/Comb/Seq dialect, instead of FIRRTL? The current FIRRTL implementation can work for Chisel, but all of the same symbols coming from Chisel should be present in the IR after FIRRTL's LowerToHW pass. The reason I'm pushing away from FIRRTL is it would be really nice to use HGDB for things other than Chisel. Building on top of the "core" CIRCT dialects could enable HGDB for anything that targets those dialects. I'm looking ahead beyond just Chisel, and it would be really great for HGDB to work for such next generation HDLs. |
@mikeurbach I believe that is the case? Although the debug attribute is inserted at the FIRRTL dialects, the symbol extraction happens much later, as shown here: Maybe I misunderstood the code? I just copied this spinet from the code gen pass. |
Thanks, you are right. I was getting confused because I thought this was only usable from firtool, but now I see the ExportDebugTablePass works with the "core" dialects. |
I'm going to mark this draft for now. @fabianschuiki has been looking at some of the debug tracking issues to make debug information first-class. I expect some movement on that soon, which would reduce the heuristics here. |
Hello,
This patch adds preliminary debugging support to firrtl + circt. It is more of a working prototype than an actual PR.
Below is an example where we can step through the code in the vending machine example (from the official Chisel3 repo). The IDE interacts with the hgdb runtime, which communicates with the underlying simulator (Xcelium in this case).
Symbol tracking
There are a couple changes I have to make to the Firrtl dialect to track the naming changes. Mostly whenever a new op is created from an symbol op, I add a new debugging attribute that encodes the original name to the new op. For instance, when a bundle is flattened e.g.
io {a, b}
, each new wire op is named based on its original identifier e.g.io.a and
io.b`. During the debugging session, the runtime will assemble these information together and reconstruct the original structure, as shown in the screenshot.Symbol table generation
I opted for Json-based format since it’s more human readable and LLVM already has a nice serializer. The Json schema can be found here. The main idea is that each statement is nested inside a statement block, which encodes source location. This PR contains a simple implementation of symbol generation. For now we’re focusing on assignments, since they’re the most common and can be used to implement watch points as well.
Here is the firrtl input.
Here is the Json output (
--disable-opt
is used).Remaining issues
While the demo works well, I’ve encountered several issues that’s outside the scope of this PR. I think I mentioned some of them in my hgdb presentation.
As shown in the Firrtl file above, register
cycle
is declared inCounter.scala
, which is not in the working folder here. In addition, all the filenames are also basenames, which makes it difficult to resolve during debugging, if there are conflicting names in the working directory.Please let me know if you have any suggestions or questions. I can break this up into smaller PR if you deem it worthy to merge this feature into the upstream.