+
Skip to content

Conversation

tianrui-wei
Copy link
Contributor

This commit fixes two different corner cases in aggregate generation when running with firrtl generated by chipyard

  1. a clock signal could reside in an "aggregate". This is caused by diplomacy in part: %6 = "hw.aggregate_constant"() <{fields = [[[false, false]]]}> : () -> !hw.struct<member:
    !hw.struct<fake_uncore: !hw.struct<clock: !seq.clock, reset: i1>>>

  2. Some FIRRTL aggregates still arrive as a DictionaryAttr keyed by field name. Trying to cast that dictionary to an array could create a segfault. The helper now handles both array and dictionary forms: for dictionaries the HW struct fields by name and build the ordered array we need, so the rest of the lowering stays safe.

This commit fixes two different corner cases in aggregate generation
when running with firrtl generated by chipyard

1. a clock signal could reside in an "aggregate". This is caused by
diplomacy in part:  %6 = "hw.aggregate_constant"() <{fields =
[[[false, false]]]}> : () ->  !hw.struct<member:
!hw.struct<fake_uncore: !hw.struct<clock: !seq.clock, reset: i1>>>

2. Some FIRRTL aggregates still arrive as a DictionaryAttr keyed by
field name. Trying to cast that dictionary to an array could create a
segfault. The helper now handles both array and dictionary forms: for
dictionaries the HW struct fields by name and build the ordered array
we need, so the rest of the lowering stays safe.

Signed-off-by: Tianrui Wei <tianrui@tianruiwei.com>
@tianrui-wei
Copy link
Contributor Author

This fixes two different bugs encountered when using the --preserve-aggregate=all flag in Chipyard.

  1. generators/diplomacy/diplomacy/src/diplomacy/nodes/MixedNode.scala:542:17: note: see current operation: %6 = "hw.aggregate_constant"() <{fields = [[[false, false]]]}> : () -> !hw.struct<member: !hw.struct<fake_un core: !hw.struct<clock: !seq.clock, reset: i1>>>

firtool: /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/Support/Casting.h:572: decltype(auto) llvm::cast(From&) [with To = mlir::ArrayAttr; From = mlir::Attribute]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/circt and include the crash backtrace.                                                                                                                        Stack dump:                                                                                                                                                                                                         0.      Program arguments: firtool --format=fir --export-module-hierarchy --verify-each=true --warn-on-unprocessed-annotations --disable-annotation-classless --disable-annotation-unknown --mlir-timing --lowering-options=emittedLineLength=2048,noAlwaysComb,disallowLocalVariables,verifLabels,disallowPortDeclSharing,locationInfoStyle=wrapInAtSquareBracket --repl-seq-mem --repl-seq-mem-file=/scratch/tianruiwei/boom/chipyard-
chisel7/sims/vcs/generated-src/chipyard.harness.TestHarness.MediumBoomV3Config/chipyard.harness.TestHarness.MediumBoomV3Config.mems.conf --annotation-file=/scratch/tianruiwei/boom/chipyard-chisel7/sims/vcs/genera
ted-src/chipyard.harness.TestHarness.MediumBoomV3Config/chipyard.harness.TestHarness.MediumBoomV3Config.appended.anno.json --split-verilog --preserve-values=all --preserve-aggregate=all --disable-wire-elimination
 --verbose-pass-executions --verification-flavor=if-else-fatal --disable-layers=Verification.Assume,Verification.Cover --mlir-disable-threading --mlir-print-ir-tree-dir=/scratch/tianruiwei/boom/chipyard-chisel7/sims/vcs/generated-src/chipyard.harness.TestHarness.MediumBoomV3Config/gen-collateral/mlir --mlir-print-ir-before=firrtl-layer-sink --mlir-print-ir-after=firrtl-layer-sink -o /scratch/tianruiwei/boom/chipyard-chis
el7/sims/vcs/generated-src/chipyard.harness.TestHarness.MediumBoomV3Config/gen-collateral /scratch/tianruiwei/boom/chipyard-chisel7/sims/vcs/generated-src/chipyard.harness.TestHarness.MediumBoomV3Config/chipyard.
harness.TestHarness.MediumBoomV3Config.fir                                                                                                                                                                           #0 0x0000706c49068429 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /scratch/tianruiwei/tmp/circt/llvm/llvm/lib/Support/Unix/Signals.inc:838:3                                                                #1 0x0000706c490654b4 llvm::sys::RunSignalHandlers() /scratch/tianruiwei/tmp/circt/llvm/llvm/lib/Support/Signals.cpp:104:20
 #2 0x0000706c49065cdc SignalHandler(int, siginfo_t*, void*) /scratch/tianruiwei/tmp/circt/llvm/llvm/lib/Support/Unix/Signals.inc:426:14                                                                             #3 0x0000706c48645330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x0000706c4869eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76                                                                                                                                     #5 0x0000706c4869eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x0000706c4869eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x0000706c4864527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x0000706c486288ff abort ./stdlib/abort.c:81:7
 #9 0x0000706c4862881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x0000706c4863b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x0000706c4b9699ea llvm::DenseMapBase<llvm::SmallDenseMap<std::pair<mlir::Block*, mlir::Attribute>, circt::sv::IfDefOp, 4u, llvm::DenseMapInfo<std::pair<mlir::Block*, mlir::Attribute>, void>, llvm::detail::De
nseMapPair<std::pair<mlir::Block*, mlir::Attribute>, circt::sv::IfDefOp>>, std::pair<mlir::Block*, mlir::Attribute>, circt::sv::IfDefOp, llvm::DenseMapInfo<std::pair<mlir::Block*, mlir::Attribute>, void>, llvm::d
etail::DenseMapPair<std::pair<mlir::Block*, mlir::Attribute>, circt::sv::IfDefOp>>::initEmpty() (.part.0) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/DenseMap.h:358:8
#12 0x0000706c4b998395 (/scratch/tianruiwei/tmp/circt/build/bin/../lib/libCIRCTFIRRTLToHW.so+0x78395)
#13 0x0000706c4b9985e9 llvm::SmallVectorBase<unsigned int>::capacity() const /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:80:36
#14 0x0000706c4b9985e9 mlir::Attribute const* llvm::SmallVectorTemplateCommon<mlir::Attribute, void>::reserveForParamAndGetAddressImpl<llvm::SmallVectorTemplateBase<mlir::Attribute, true>>(llvm::SmallVectorTempla
teBase<mlir::Attribute, true>*, mlir::Attribute const&, unsigned long) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:233:9
#15 0x0000706c4b9985e9 llvm::SmallVectorTemplateBase<mlir::Attribute, true>::reserveForParamAndGetAddress(mlir::Attribute&, unsigned long) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:53
8:47
#16 0x0000706c4b9985e9 llvm::SmallVectorTemplateBase<mlir::Attribute, true>::push_back(mlir::Attribute) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:563:51
#17 0x0000706c4b9985e9 (anonymous namespace)::FIRRTLLowering::getOrCreateAggregateConstantAttribute(mlir::Attribute, mlir::Type) /scratch/tianruiwei/tmp/circt/lib/Conversion/FIRRTLToHW/LowerToHW.cpp:2248:21
#18 0x0000706c4b9985e9 llvm::SmallVectorBase<unsigned int>::capacity() const /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:80:36                                                           #19 0x0000706c4b9985e9 mlir::Attribute const* llvm::SmallVectorTemplateCommon<mlir::Attribute, void>::reserveForParamAndGetAddressImpl<llvm::SmallVectorTemplateBase<mlir::Attribute, true>>(llvm::SmallVectorTempla
teBase<mlir::Attribute, true>*, mlir::Attribute const&, unsigned long) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:233:9
#20 0x0000706c4b9985e9 llvm::SmallVectorTemplateBase<mlir::Attribute, true>::reserveForParamAndGetAddress(mlir::Attribute&, unsigned long) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:53
8:47
#21 0x0000706c4b9985e9 llvm::SmallVectorTemplateBase<mlir::Attribute, true>::push_back(mlir::Attribute) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:563:51
#22 0x0000706c4b9985e9 (anonymous namespace)::FIRRTLLowering::getOrCreateAggregateConstantAttribute(mlir::Attribute, mlir::Type) /scratch/tianruiwei/tmp/circt/lib/Conversion/FIRRTLToHW/LowerToHW.cpp:2248:21
#23 0x0000706c4b9985e9 llvm::SmallVectorBase<unsigned int>::capacity() const /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:80:36
#24 0x0000706c4b9985e9 mlir::Attribute const* llvm::SmallVectorTemplateCommon<mlir::Attribute, void>::reserveForParamAndGetAddressImpl<llvm::SmallVectorTemplateBase<mlir::Attribute, true>>(llvm::SmallVectorTempla
teBase<mlir::Attribute, true>*, mlir::Attribute const&, unsigned long) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:233:9
#25 0x0000706c4b9985e9 llvm::SmallVectorTemplateBase<mlir::Attribute, true>::reserveForParamAndGetAddress(mlir::Attribute&, unsigned long) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:53
8:47                                                                                                                                                                                                                #26 0x0000706c4b9985e9 llvm::SmallVectorTemplateBase<mlir::Attribute, true>::push_back(mlir::Attribute) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/ADT/SmallVector.h:563:51                               #27 0x0000706c4b9985e9 (anonymous namespace)::FIRRTLLowering::getOrCreateAggregateConstantAttribute(mlir::Attribute, mlir::Type) /scratch/tianruiwei/tmp/circt/lib/Conversion/FIRRTLToHW/LowerToHW.cpp:2248:21
#28 0x0000706c4b99c4a3 mlir::AttributeStorage::getAbstractAttribute() const /scratch/tianruiwei/tmp/circt/llvm/mlir/include/mlir/IR/AttributeSupport.h:177:5                                                        #29 0x0000706c4b99c4a3 mlir::Attribute::getTypeID() /scratch/tianruiwei/tmp/circt/llvm/mlir/include/mlir/IR/Attributes.h:52:57
#30 0x0000706c4b99c4a3 bool mlir::detail::StorageUserBase<mlir::ArrayAttr, mlir::Attribute, mlir::detail::ArrayAttrStorage, mlir::detail::AttributeUniquer>::classof<mlir::Attribute>(mlir::Attribute) /scratch/tianruiwei/tmp/circt/llvm/mlir/include/mlir/IR/StorageUniquerSupport.h:113:25                                                                                                                                           #31 0x0000706c4b99c4a3 llvm::CastInfo<mlir::ArrayAttr, mlir::Attribute const, void>::isPossible(mlir::Attribute) /scratch/tianruiwei/tmp/circt/llvm/mlir/include/mlir/IR/Attributes.h:388:25                        #32 0x0000706c4b99c4a3 bool llvm::isa<mlir::ArrayAttr, mlir::Attribute>(mlir::Attribute const&) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/Support/Casting.h:549:46
#33 0x0000706c4b99c4a3 decltype(auto) llvm::cast<mlir::ArrayAttr, mlir::Attribute>(mlir::Attribute&) /scratch/tianruiwei/tmp/circt/llvm/llvm/include/llvm/Support/Casting.h:572:3
#34 0x0000706c4b99c4a3 (anonymous namespace)::FIRRTLLowering::visitExpr(circt::firrtl::AggregateConstantOp) /scratch/tianruiwei/tmp/circt/lib/Conversion/FIRRTLToHW/LowerToHW.cpp:3263:48                           #35 0x0000706c4b9c11a1 Case<circt::firrtl::AggregateConstantOp, circt::firrtl::ExprVisitor<(anonymous namespace)::FIRRTLLowering, llvm::LogicalResult>::dispatchExprVisitor(mlir::Operation*)::<lambda(auto:58)>&> /
.......

@uenoku
Copy link
Member

uenoku commented Oct 1, 2025

Hi thank you for sending the PR! I think the root cause of (1) is the type implementation of HW. Currently HW struct type doesn't allow seq.clock as an element so it is causing a failure.

For (2) I'm not sure it actually happens. Do you have a test case for that?

@tianrui-wei
Copy link
Contributor Author

@uenoku Thanks for the quick response.

For <1>, do you think my changes make sense? I'm not sure if the HW struct type disallows seq.clock is a part of firrtl spec (obviously you'd be the expert :) ), but if so, I'll redirect the issue to diplomacy, which is doing chisel hacks to pack clocks inside structs

For <2>, yes, the fir file very huge though (and are causing issues in circt-reduce), would you like me to upload it? It could also be obtained by running chipyar with the --preserve-aggregate=all flag if you'd like to reproduce it yourself.

@uenoku
Copy link
Member

uenoku commented Oct 2, 2025

do you think my changes make sense

Yes, I think the change for aggregate constant makes sense.

i'm not sure if the HW struct type disallows seq.clock is a part of firrtl spec

I think firrtl spec is not restricting anything about output verilog types (except for public module ports which must be scalarized). So firtool has a freedom to emit structs or scalarized ports. The issue is mostly implementation of HW type system which makes it hard to use seq.clock. #8931 is similar issue and we cannot use sv.wire for struct types that contatin seq.clock.

It's necessary to modify HW type implementation to allow seq.clock in HW type, but I'm also not sure what's the best way to do that. From that reason previously we thought it's easier to just lower aggregate that contain clock (
#4667 is a PR, it wasn't land but happy to rebase if necessary).

@tianrui-wei
Copy link
Contributor Author

@uenoku Thanks for your feedback. I agree with your approach, and I think the current PR might be a little brute-forcy in terms of forcing the clocking conversion, it would be a lot cleaner if this is fixed upstream in the hw type implementation. Please lmk your thoughts on rebasing #4667, and I'll be happy to re-implement this PR with the landed changes.

@uenoku
Copy link
Member

uenoku commented Oct 4, 2025

#4667 is basically giving up preserving clock in bundle/array. Is that ok for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载