Skip to content

Commit c13e34b

Browse files
authored
Bugfix: .toDefinition should update Builder.definitions (#5197)
* Calling .toDefinition should update Builder.definitions * Ran formatter on tests * Add test for two .toDefinition calls
1 parent 87b7f5d commit c13e34b

2 files changed

Lines changed: 64 additions & 2 deletions

File tree

core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,15 @@ final case class Instance[+A] private[chisel3] (private[chisel3] val underlying:
6767
}
6868

6969
/** Returns the definition of this Instance */
70-
override def toDefinition: Definition[A] = new Definition(Proto(proto))
71-
override def toInstance: Instance[A] = this
70+
override def toDefinition: Definition[A] = {
71+
val result = new Definition(Proto(proto))
72+
// Because we are creating a new Definition, we should update our Builder.definitions
73+
if (Builder.inContext && !Builder.definitions.view.map(_.proto).contains(result.proto)) {
74+
Builder.definitions += result
75+
}
76+
result
77+
}
78+
override def toInstance: Instance[A] = this
7279
private[chisel3] def copy[T](underlying: Underlying[T]) = new Instance(underlying)
7380

7481
}

src/test/scala-2/chiselTests/experimental/hierarchy/DefinitionSpec.scala

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,4 +945,59 @@ class DefinitionSpec extends AnyFunSpec with Matchers with FileCheck {
945945
)
946946
}
947947
}
948+
describe("(9): Calling .toDefinition should update Builder.definitions") {
949+
it("(9.a): calling .toDefinition from another definition's child Instance should work as expected") {
950+
class Bar extends RawModule {
951+
val a = WireInit(false.B)
952+
}
953+
@instantiable
954+
class Foo extends RawModule {
955+
@public val bar = Module(new Bar)
956+
}
957+
class Baz(d: Definition[Foo]) extends RawModule {
958+
val bar = Instance(d.bar.toDefinition)
959+
}
960+
ChiselStage
961+
.emitCHIRRTL(
962+
{
963+
val d = Definition(new Foo)
964+
new Baz(d)
965+
},
966+
Array("--full-stacktrace")
967+
)
968+
.fileCheck()(
969+
"""|CHECK: module Bar :
970+
|CHECK: module Baz :
971+
|""".stripMargin
972+
)
973+
}
974+
it("(9.b): calling .toDefinition twice from anther definition's child Instance should work as expected") {
975+
class Bar extends RawModule {
976+
val a = WireInit(false.B)
977+
}
978+
@instantiable
979+
class Foo extends RawModule {
980+
@public val bar = Module(new Bar)
981+
}
982+
class Baz(d: Definition[Foo]) extends RawModule {
983+
val bar = Instance(d.bar.toDefinition)
984+
val bar2 = Instance(d.bar.toDefinition)
985+
}
986+
val x = ChiselStage
987+
.emitCHIRRTL(
988+
{
989+
val d = Definition(new Foo)
990+
new Baz(d)
991+
},
992+
Array("--full-stacktrace")
993+
)
994+
.fileCheck()(
995+
"""|CHECK: module Bar :
996+
|CHECK-NOT: module Bar_
997+
|CHECK: module Baz :
998+
|""".stripMargin
999+
)
1000+
}
1001+
}
1002+
9481003
}

0 commit comments

Comments
 (0)