Implement module prefix API#2155
Conversation
jackkoenig
left a comment
There was a problem hiding this comment.
Overall looks great, nice clean implementation!
|
|
||
| /** Elaborates a Chisel module into a circuit, but return that circuit in module form | ||
| * @param gen a call-by-name Chisel module | ||
| */ | ||
| def construct[T <: RawModule](gen: => T): T = { | ||
| val phase = new ChiselPhase { | ||
| override val targets = Seq( Dependency[chisel3.stage.phases.Checks], | ||
| Dependency[chisel3.stage.phases.Elaborate] ) | ||
| } | ||
|
|
||
| phase | ||
| .transform(Seq(ChiselGeneratorAnnotation(() => gen), NoRunFirrtlCompilerAnnotation)) | ||
| .collectFirst { | ||
| case DesignAnnotation(a) => a.asInstanceOf[T] | ||
| } | ||
| .get | ||
| } |
There was a problem hiding this comment.
| /** Elaborates a Chisel module into a circuit, but return that circuit in module form | |
| * @param gen a call-by-name Chisel module | |
| */ | |
| def construct[T <: RawModule](gen: => T): T = { | |
| val phase = new ChiselPhase { | |
| override val targets = Seq( Dependency[chisel3.stage.phases.Checks], | |
| Dependency[chisel3.stage.phases.Elaborate] ) | |
| } | |
| phase | |
| .transform(Seq(ChiselGeneratorAnnotation(() => gen), NoRunFirrtlCompilerAnnotation)) | |
| .collectFirst { | |
| case DesignAnnotation(a) => a.asInstanceOf[T] | |
| } | |
| .get | |
| } |
This is a very large public API to add just for testing. If we want to add this, we need to be pretty thoughtful about it and with the current architecture of Chisel3, not much value comes from having references to elaborated module objects. Although arguably that should change, that's well beyond the scope of this PR.
| import chisel3.stage.CircuitSerializationAnnotation.FirrtlFileFormat | ||
|
|
||
| import java.io.{StringWriter, PrintWriter} | ||
| import chisel3.Module |
There was a problem hiding this comment.
| import chisel3.Module |
Related to comment about `ChiselStage.construct
| } | ||
|
|
||
| property("withModulePrefix should prefix modules within it") { | ||
| val m = ChiselStage.construct(new Module { |
There was a problem hiding this comment.
| val m = ChiselStage.construct(new Module { | |
| val m = elaborateAndGetModule(new Module { |
Related to deletion of ChiselStage.construct, chiselTests.ChiselRunners already defines what you need here: elaborateAndGetModule
| } | ||
|
|
||
| property("withModulePrefix should support nested module prefixing") { | ||
| val m = ChiselStage.construct(new Module { |
There was a problem hiding this comment.
| val m = ChiselStage.construct(new Module { | |
| val m = elaborateAndGetModule(new Module { |
Related to deletion of ChiselStage.construct, chiselTests.ChiselRunners already defines what you need here: elaborateAndGetModule
| /** Returns the current Module */ | ||
| def currentModule: Option[BaseModule] = Builder.currentModule | ||
| /** Returns the current nested module prefix */ | ||
| def currentPrefix: String = Builder.getModulePrefix |
There was a problem hiding this comment.
| def currentPrefix: String = Builder.getModulePrefix | |
| def currentModulePrefix: String = Builder.getModulePrefix |
Just to avoid confusion with other uses of "prefix" which is usually referring to the intra-Module component prefixing rather than the global namespace Module prefixing.
|
|
||
| property("withModulePrefix should prefix modules within it") { | ||
| val m = ChiselStage.construct(new Module { | ||
| val io = IO(new Bundle { }) |
There was a problem hiding this comment.
| val io = IO(new Bundle { }) |
io is no longer needed, please delete from all the added Modules.
| }) | ||
|
|
||
| m.child.nestedChild.name should be ("FooBarModule") | ||
| } |
There was a problem hiding this comment.
Because this is a generator, people may want to have generated prefixes, including empty ones. I believe this works but can you add a test showing that an empty prefix (withModulePrefix("")) does not change the resulting modules names?
There was a problem hiding this comment.
is there any desire to "flush" the prefixing? Or is "nested" the only option?
Eg given:
Module TestHarness
Module DUT
Module A
Module B
Module VIP
If I say I want everything in TestHarness to be prefixed "TestHarness", e.g. I want TestHarnessVIP, it seems there is no way to "reset" the prefixes for DUT using withPrefix. Is there any other API to "clear out" the prefix stack? So that I don't end up with TestHarnessDUT?
| } | ||
| }) | ||
|
|
||
| m.child.nestedChild.name should be ("FooBarModule") |
There was a problem hiding this comment.
can you please add a test which includes a SeqMem and run the ReplSeqMem? What is the prefixing behavior for the seq mems?
And also please add a test for blackbox/inline black box, which should NOT get prefixes applied
There was a problem hiding this comment.
Agreed with all of the tests. I'll note that prefixing of SyncReadMems is going to be tricky. I think maybe we should add a test for it but have it as ignore right now because I'm not yet sure how we should handle it.
|
Discussed this again with @jackkoenig . The main limitation of this PR as it is is that we lose the "what is the prefix (ad-hoc namespace)" and "what is the leaf name" distinction. I'd suggest we do one of (in increasing order of complexity / design thought required):
|
Contributor Checklist
docs/src?Type of Improvement
API Impact
Adds new API
Backend Code Generation Impact
No impact
Desired Merge Strategy
Squash and merge
Release Notes
Implement Module Prefix API
withModulePrefix(prefix), that prefixes all instantiated modules within its scope with theprefixargumentReviewer Checklist (only modified by reviewer)
3.3.x, [small] API extension:3.4.x, API modification or big change:3.5.0)?Please Merge?