@@ -12,17 +12,27 @@ import chisel3.internal.firrtl.ir._
1212import chisel3 .experimental .{requireIsChiselType , BaseModule , SourceInfo , UnlocatableSourceInfo }
1313import chisel3 .properties .{Class , Property }
1414import chisel3 .reflect .DataMirror
15- import _root_ .firrtl .annotations .{InstanceTarget , IsModule , ModuleName , ModuleTarget }
15+ import _root_ .firrtl .annotations .{
16+ Annotation ,
17+ InstanceTarget ,
18+ IsMember ,
19+ IsModule ,
20+ ModuleName ,
21+ ModuleTarget ,
22+ SingleTargetAnnotation ,
23+ Target
24+ }
1625import _root_ .firrtl .AnnotationSeq
1726import chisel3 .internal .plugin .autoNameRecursively
1827import chisel3 .util .simpleClassName
28+ import chisel3 .experimental .{annotate , ChiselAnnotation }
1929import chisel3 .experimental .hierarchy .Hierarchy
2030
2131private [chisel3] trait ObjectModuleImpl {
2232
2333 protected def _applyImpl [T <: BaseModule ](bc : => T )(implicit sourceInfo : SourceInfo ): T = {
2434 // Instantiate the module definition.
25- val module = evaluate[T ](bc)
35+ val module : T = evaluate[T ](bc)
2636
2737 // Handle connections at enclosing scope
2838 // We use _component because Modules that don't generate them may still have one
@@ -165,6 +175,9 @@ private[chisel3] trait ObjectModuleImpl {
165175 /** Returns the current Module */
166176 def currentModule : Option [BaseModule ] = Builder .currentModule
167177
178+ /** Returns the current nested module prefix */
179+ def currentModulePrefix : String = Builder .getModulePrefix
180+
168181 private [chisel3] def do_pseudo_apply [T <: BaseModule ](
169182 bc : => T
170183 )(
@@ -225,6 +238,10 @@ private[chisel3] trait ObjectModuleImpl {
225238 /** Explicitly Asynchronous Reset */
226239 case object Asynchronous extends Type
227240 }
241+
242+ def getModulePrefixList : List [String ] = {
243+ Builder .getModulePrefixList
244+ }
228245}
229246
230247private [chisel3] trait ModuleImpl extends RawModule with ImplicitClock with ImplicitReset {
@@ -677,8 +694,9 @@ package experimental {
677694 // PseudoModules are not "true modules" and thus should share
678695 // their original modules names without uniquification
679696 this match {
680- case _ : PseudoModule => desiredName
681- case _ => Builder .globalNamespace.name(desiredName)
697+ case _ : PseudoModule => Module .currentModulePrefix + desiredName
698+ case _ : BaseBlackBox => Builder .globalNamespace.name(desiredName)
699+ case _ => Builder .globalNamespace.name(Module .currentModulePrefix + desiredName)
682700 }
683701 } catch {
684702 case e : NullPointerException =>
@@ -915,5 +933,43 @@ package experimental {
915933 case Some (c) => getRef.fullName(c)
916934 }
917935
936+ /** Returns the current nested module prefix */
937+ val modulePrefix : String = Builder .getModulePrefix
938+ }
939+ }
940+
941+ /**
942+ * Creates a block under which any generator that gets run results in a module whose name is prepended with the given prefix.
943+ */
944+ object withModulePrefix {
945+
946+ /**
947+ * @param arg prefix Prefix is the module prefix, blank means ignore.
948+ */
949+ def apply [T ](prefix : String )(block : => T ): T = {
950+ if (prefix != " " ) {
951+ Builder .pushModulePrefix(prefix)
952+ }
953+ val res = block // execute block
954+ if (prefix != " " ) {
955+ Builder .popModulePrefix()
956+ }
957+ res
958+ }
959+ }
960+
961+ private case class ModulePrefixAnnotation (target : IsMember , prefix : String ) extends SingleTargetAnnotation [IsMember ] {
962+ def duplicate (n : IsMember ): ModulePrefixAnnotation = this .copy(target = n)
963+ }
964+
965+ private object ModulePrefixAnnotation {
966+ def annotate [T <: HasId ](target : T ): Unit = {
967+ val prefix = Builder .getModulePrefix
968+ if (prefix != " " ) {
969+ val annotation : ChiselAnnotation = new ChiselAnnotation {
970+ def toFirrtl : Annotation = ModulePrefixAnnotation (target.toTarget, prefix)
971+ }
972+ chisel3.experimental.annotate(annotation)
973+ }
918974 }
919975}
0 commit comments