-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Move beu interrupt crossing source register into Tile #2623
Conversation
I agree with the technical solution but would like @hcook to review the code. |
No strong objection to the code as written but two high level concerns:
Furthermore, it looks like @aswaterman and I both missed the addition of a separate clock sink node port for handing the raw reset and driving some certain tile ports using it... It suggests to me that this single "PRCI domain wrapper" is not a good abstraction, since there are apparently actually two reset domains propagating through subcomponents of the tile, both of which are being used? I feel like we might need to step back and examine which components are really expected to be on which reset domain and whether the current Scala code representation of single domain wrapper is suitable... |
It seems to me like we want all the registers that want the unstretched reset to live in an outer wrapper (either TilePRCIDomain rewritten to not use the stretched reset for anything but driving the tile's reset? or a second ClockDomain wrapper added outside the first that doesn't contain the stretcher but doest contain the clock crossings?). Like, the notifications aren't "clock crossed" right now, but they need to be "reset crossed" to have this |
@hcook I'm all for a more general solution. I double-checked and the reset feeding the intsource block (containing the AsyncReset register for the source side of the crossing) is indeed fed by the output of the reset stretcher.
It seems the general need here is for any outputs sourced from the Tile to get their reset from the external input rather than the stretcher and also to include a |
@ernie-sifive Yeah, the
and thus whatever get injected applies itself to all crossing halves, both inputs and outputs, and also the tile. But it seems like we want to distinguish reset strategy between either the crossing halves(/output registers) and the tile contents, or alternatively between all children explicitly on a case by case basis. Put another way, if certain clock crossings have registers that are driven by inputs to the tile, which reset domain should those registers be a part of? Stretched or no? Does it matter? If they can/should all be unstretched, then I think we should figure out how to make If we go down this path, adding a whole separate module layer via another ClockDomain to add the stretcher to the tile is probably the most expedient in terms of source code changes, and it has a clear separation of concerns like
but it also seems a little egregious to add a whole other layer if the only child with stretched reset really is the tile... We could probably figure out how to do it all flat in one wrapper layer too, with a judicious use of something like a |
@hcook I think we can live with tile input registers getting their reset from either the external or the stretched reset. In an async reset system, everything outside gets reset first, then that reset ends, and a while later, the clock starts and the Tile is reset. Things crossing out of the Tile need the async reset so that they are quiescent before and on the first clock edge when whatever they are driving wakes up. The BlockDuringReset ensures that the async reset output registers themselves don't act on randomized outputs from the core on the first clock edge, before the core is reset. For inputs crossing into the Tile, at some point, the input crosses from an async reset domain to the Tile's sync reset domain, and I don't think it matters whether the reset domain crossing occurs between the two halves of the crossing logic or between the crossing sink and the rest of the Tile. Interrupts aren't going to be acted upon, and the Rational Crossing's BlockDuringReset will keep it quiet until both sides have emerged from reset. |
@ernie-sifive Apologies fro the delay, but I'm going to take a crack at the generalization of this today. I will keep you posted and submit my changes as a PR against this PR. |
@ernie-sifive As I fiddle around, some follow-up questions I have to this change:
|
|
Closed in favor of #2641 |
Related issue:
Type of change: bug report
Impact: no functional change
Development Phase: implementation
Release Notes
A DFT error in the Tile interrupt output (from BEU) was detected. The problem is the Diplomatic interrupt crossing uses an AsyncReset flop on the source side of the crossing and this flop gets its reset from the default Chisel reset in effect (which is the stretched core_reset input in an RA or RF system). DFT rules prevent any internally-generated signals from being used as async reset. This PR removes the flop from the crossing itself and puts it into the Tile, where it can get its reset from the raw core_reset.
An IntAdapterNode was added to allow inserting a flop in the interrupt path within RocketTile. Default Diplomatic crossing was changed to use alreadyRegistered=true which prevents a register from being inserted on the source side of the crossing.