Skip to content

Commit 8db8c1e

Browse files
Support boring on original Module after .toInstance call (backport #4602) (#4604)
* Support boring on original Module after .toInstance call (#4602) (cherry picked from commit 4d162c4) * Add needed private API and change new test to 6.x-style --------- Co-authored-by: Jack Koenig <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 4c10d0e commit 8db8c1e

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

core/src/main/scala/chisel3/Module.scala

+6
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,12 @@ package experimental {
578578
_ports.toSeq
579579
}
580580

581+
/** Get IOs that are currently bound to this module.
582+
*/
583+
private[chisel3] def getIOs: Seq[Data] = {
584+
_ports.map(_._1).toSeq
585+
}
586+
581587
// These methods allow checking some properties of ports before the module is closed,
582588
// mainly for compatibility purposes.
583589
protected def portsContains(elem: Data): Boolean = {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ object Lookupable {
352352
def getIoMap(hierarchy: Hierarchy[_]): Option[Map[Data, Data]] = {
353353
hierarchy.underlying match {
354354
case Clone(x: ModuleClone[_]) => Some(x.ioMap)
355-
case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data: Data) => data -> data }.toMap)
355+
case Proto(x: BaseModule) => Some(x.getIOs.map { data => data -> data }.toMap)
356356
case Clone(x: InstantiableClone[_]) => getIoMap(x._innerContext)
357357
case Clone(x: InstanceClone[_]) => None
358358
case other => {

src/test/scala/chiselTests/BoringUtilsSpec.scala

+28
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,34 @@ class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners with Utils with
320320
log should include("Can only bore into modules that are not fully closed")
321321
}
322322

323+
it should "support boring on a Module even after .toInstance (and accessing a port)" in {
324+
import chisel3.experimental.hierarchy._
325+
@instantiable
326+
class Bar extends RawModule {
327+
@public val port = IO(Output(UInt(8.W)))
328+
val a_wire = WireInit(UInt(1.W), DontCare)
329+
}
330+
class Foo extends RawModule {
331+
val bar = Module(new Bar)
332+
val bi = bar.toInstance
333+
val x = BoringUtils.bore(bar.a_wire)
334+
val p = bi.port // Previously, the lookup here would close the module due to reflecting on the IOs of bar
335+
val y = BoringUtils.bore(bar.a_wire)
336+
}
337+
338+
val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Foo)
339+
matchesAndOmits(chirrtl)(
340+
"module Bar :",
341+
"output x_bore : UInt<1>",
342+
"output y_bore : UInt<1>",
343+
"connect x_bore, a_wire",
344+
"connect y_bore, a_wire",
345+
"module Foo :",
346+
"connect x, bar.x_bore",
347+
"connect y, bar.y_bore"
348+
)()
349+
}
350+
323351
it should "not create a new port when source is a port" in {
324352
class Baz extends RawModule {
325353
val a = IO(Output(Bool()))

0 commit comments

Comments
 (0)