Skip to content

Commit 429cc7a

Browse files
authored
fix: evaluate target lazily in Path (#4543)
At the moment `toTarget` does not work properly with the D/I system, seeing that we cannot get the instanceName of a module when evaluating it, and even if we call `toTarget` in `atModuleBodyEnd` we will get the wrong circuit name since the definition of the module's parent is still in construction. In order to construct `Path` properly, we need to defer the evaluation of `target` to the IR generation time in the `isMember` constructor, just as the other constructors already do. Signed-off-by: unlsycn <unlsycn@unlsycn.com>
1 parent 876f5f6 commit 429cc7a

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

core/src/main/scala/chisel3/properties/Path.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ object Path {
106106

107107
/** Construct a Path from a target
108108
*/
109-
def apply(target: IsMember): Path = apply(target, false)
110-
def apply(target: IsMember, isMemberPath: Boolean): Path = {
109+
def apply(target: => IsMember): Path = apply(target, false)
110+
def apply(target: => IsMember, isMemberPath: Boolean): Path = {
111111
val _isMemberPath = isMemberPath // avoid name shadowing below
112112
new TargetPath {
113113
def toTarget(): IsMember = target

src/test/scala/chiselTests/ToTargetSpec.scala

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package chiselTests
55
import chisel3._
66
import chisel3.properties.{Path, Property}
77
import circt.stage.ChiselStage
8-
import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance}
8+
import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance, Instantiate}
99

1010
@instantiable
1111
class RelativeInnerModule extends RawModule {
@@ -144,6 +144,20 @@ class RelativeSiblingsInstancesParent extends RawModule {
144144
}
145145
}
146146

147+
class PathFromInstanceToTarget extends RawModule {
148+
@instantiable
149+
class Hierarchy1 extends RawModule {
150+
@instantiable
151+
class Hierarchy2 extends RawModule {
152+
val target = Instantiate(new RelativeInnerModule)
153+
@public val path = IO(Output(Property[Path]()))
154+
path := Property(Path(target.toTarget))
155+
}
156+
val instance2 = Instantiate(new Hierarchy2)
157+
}
158+
val instance1 = Instantiate(new Hierarchy1)
159+
}
160+
147161
class ToTargetSpec extends ChiselFlatSpec with Utils {
148162

149163
var m: InstanceNameModule = _
@@ -290,4 +304,9 @@ class ToTargetSpec extends ChiselFlatSpec with Utils {
290304
e.getMessage should include("No common ancestor between")
291305
}
292306

307+
it should ("get correct Path from an Instance") in {
308+
val chirrtl = ChiselStage.emitCHIRRTL(new PathFromInstanceToTarget)
309+
chirrtl should include("OMInstanceTarget:~PathFromInstanceToTarget|Hierarchy2/target:RelativeInnerModule")
310+
}
311+
293312
}

0 commit comments

Comments
 (0)