Implement User API registerFinishAction
This PR adds user API chisel3.experimental.registerFinishAction(block: () => Unit): Unit to let user be able to append code blocks at end of a Module.
Currently, A library-writer can add code blocks at the begin of Module by providing trait, and let user extend it. However it is impossible to append a code block to last of user codes.
There are some important usage, for example,
DataMirror all user IO, and annotate them.
Let user define a list of registers/wires, and annotate them automatically.
Auto connection, like what we did in diplomacy.
Tests will be added after approving this API.
Contributor Checklist
- [x] Did you add Scaladoc to every public function/method?
- [ ] Did you add at least one test demonstrating the PR?
- [x] Did you delete any extraneous printlns/debugging code?
- [x] Did you specify the type of improvement?
- [ ] Did you add appropriate documentation in
docs/src? - [x] Did you state the API impact?
- [x] Did you specify the code generation impact?
- [x] Did you request a desired merge strategy?
- [ ] Did you add text to be included in the Release Notes for this change?
Type of Improvement
- new feature/API
API Impact
add user API:
chisel3.experimental.registerFinishAction(block: () => Unit): Unit
Backend Code Generation Impact
None
Desired Merge Strategy
- Rebase: You will rebase the PR onto master and it will be merged with a merge commit.
Release Notes
add chisel3.experimental.registerFinishAction(block: () => Unit): Unit to let user insert code block at the end of Module.
Reviewer Checklist (only modified by reviewer)
- [ ] Did you add the appropriate labels?
- [ ] Did you mark the proper milestone (3.2.x, 3.3.x, 3.4.x, 3.5.0) ?
- [ ] Did you review?
- [ ] Did you check whether all relevant Contributor checkboxes have been checked?
- [ ] Did you mark as
Please Merge?
this sounds like LazyModule's InModuleBody... but agree it doesn't make sense at least as a one-time call.
Why is this generally needed? There already exist several mechanisms as mentioned for this sort of thing (Aspects, diplomacy's LazyModule), what would a typical use case be?
@mwachs5 this sounds like
LazyModule'sInModuleBody.
For user-API this is InModuleBody, but for library writer, it is the instantiate function.
@jackkoenig That sounds a lot like aspects to me. Maybe what we want here is a lighter-weight aspect API, I'm not sure. @mwachs5 Why is this generally needed? There already exist several mechanisms as mentioned for this sort of thing (Aspects, diplomacy's LazyModule), what would a typical use case be?
I admit this API is something similar to Aspect. Here are some different points:
Aspect can only access public API in a module, while this API is more flexible, since user is defining this API in their own module, only put it at last block to instantiate.
This API is more light-weight, there are no additional passes.
while diplomacy is a pretty big library, I'd like it to be extracted from Rocket-Chip and server as a standalone library to users, but even it may becomes a standalone library in the future, it is too big for this demand(we only need to put a block in the end of entire Module), and I'd like diplomacy use this new future in the future, which can clean up its code bases.
@jackkoenig Perhaps we could constrain these "finish actions" to not be able to generate any hardware, only inject annotations.
But I still think we can construct hardware here, Diplomacy has the instantiate function, and it requires constructing hardware.
@jackkoenig Say we do something different, rather than a single method to override, you can call something like
registerFinishAction(f: () => Unit)that registers functions to call at the end. You still run into ordering issues, what if you have an action that don't touches all ports but then another action runs after it that adds another port?
That sounds better! but abstract override could also meet the sequence demand, here is a blog to illustrate(currently I'm using this), but I admit this is some black magic in Scala, and we should not encourage users to do so. So in my next reversion, I will use your suggesting to rewrite this API.