chipsalliance / chipsalliance/rocket-chip
Rational Crossing Reset Bug
- Dominant language
- Scala
- Stars
- 3.9k
- Forks
- 1.3k
- Avg merge
- 5d 13m
- Merged PRs (30d)
- 1
Description
There is a bug in the Chipyard SystemBus when it is coupled with a rational crossing type with different core and uncore reset domains. The rational crossing is between the core and uncore side of the system bus, and there exists per-core resets and one uncore reset.
An assertion is thrown whenever I place one core in reset, after that core has been running for some time. The problem is that the uncore side of the rational crossing, which exists in the SystemBus, does not get reset. This puts the TLRationalCrossingSink, instantiated inside the TLInterconnectCoupler_sbus_from_rockettile, out of sync with the now reseted source side. This happens because the TLRationalCrossingSource side got reset (driven by core reset), but the TLRationalCrossingSink side did not (driven by uncore reset), which puts the counts of each module out of sync. This throws an assertion error.
A simple fix would be to logical OR the reset of both domains (core + uncore) at the TLInterconnectCoupler_sbus_from_rockettile reset port, which would allow the TLRationalCrossingSink module to also get reset at the same time as the TLRationalCrossingSource module. This would keep both sides of the RationalCrossing in sync, and remove the assertion error. I've tested this and it seems to work.
My only trouble is implementing this fix in the scala code, as I don't know where to place this OR gate logic. @jerryz123 do you have any thoughts on where I can fix this problem in the chipyard files? I've only tested this fix by hacking the generated RTL. Fix shown below:
```
TLInterconnectCoupler_sbus_from_rockettile coupler_from_rockettile ( // @[generators/diplomacy/diplomacy/src/diplomacy/lazymodule/LazyScope.scala:98:27]
.clock (_fixedClockNode_auto_anon_out_0_clock), // @[generators/rocket-chip/src/main/scala/prci/ClockGroup.scala:115:114]
.reset (_fixedClockNode_auto_anon_out_0_reset || auto_sbus_clock_groups_in_member_sbus_rockettile_0_reset), // @[generators/rocket-chip/src/main/scala/prci/ClockGroup.scala:115:114]
.auto_tl_master_clock_xing_in_a_bits0_opcode (auto_coupler_from_rockettile_tl_master_clock_xing_in_0_a_bits0_opcode),
.auto_tl_master_clock_xing_in_a_bits0_param (auto_coupler_from_rockettile_tl_master_clock_xing_in_0_a_bits0_param),
```
Contributor guide
Research direction
Start by tracing the Scala generation of TLInterconnectCoupler_sbus_from_rockettile and how its reset port is connected, then compare that path with the generated RTL snippet in the issue. Done means the rational crossing source and sink reset together when either reset domain is asserted and the assertion no longer occurs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100