Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add private Module API and internal DataMirror API for moduleIOs. #4036

Merged
merged 4 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions core/src/main/scala/chisel3/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,21 @@ package experimental {
_ports.toSeq
}

/** Get IOs that are currently bound to this module.
*/
private[chisel3] def getIOs: Seq[Data] = {
_ids.flatMap { id =>
id match {
case (data: Data) if data.isSynthesizable =>
data.topBinding match {
case PortBinding(_) => Some(data)
case _ => None
}
case _ => None
}
}.toSeq
mikeurbach marked this conversation as resolved.
Show resolved Hide resolved
}

// These methods allow checking some properties of ports before the module is closed,
// mainly for compatibility purposes.
protected def portsContains(elem: Data): Boolean = {
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/scala/chisel3/reflect/DataMirror.scala
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,17 @@ object DataMirror {
def chiselTypeClone[T <: Data](target: T): T = {
target.cloneTypeFull
}

/** Returns the current ports of an in-progress module.
*
* This method does not necessarily return the final ports of the target module. It consults Chisel's internal data
* structures to extract the module's IOs. For this reason, it is generally not safe, and users should prefer
* [[DataMirror.modulePorts]], but this method may be used for certain use cases that want the current list of
* ports before the module is closed.
*
* @param target BaseModule to get IOs from
*/
def currentModulePorts(target: BaseModule): Seq[Data] = target.getIOs
}

// Old definition of collectLeafMembers
Expand Down
27 changes: 27 additions & 0 deletions src/test/scala/chiselTests/reflect/DataMirrorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,31 @@ class DataMirrorSpec extends ChiselFlatSpec {
DataMirror.getLayerColor(foo.c) should be(Some(A))
}

"moduleIOs" should "return an in-progress module's IOs" in {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit you changed the name of this function and maybe we should have changed this string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, i wish we could push NFC changes to main.

class Foo extends RawModule {
val in = IO(Input(Bool()))
val out = IO(Output(Bool()))
val wire = Wire(Bool())
val child = Module(new RawModule {})

val ports0 = DataMirror.internal.currentModulePorts(this)

val other = IO(Input(Bool()))

val ports1 = DataMirror.internal.currentModulePorts(this)
}

ChiselStage.emitCHIRRTL(new RawModule {
val foo = Module(new Foo)

foo.ports0.size should be(2)
foo.ports0(0).toNamed.name should be("in")
foo.ports0(1).toNamed.name should be("out")
mikeurbach marked this conversation as resolved.
Show resolved Hide resolved

foo.ports1.size should be(3)
foo.ports1(0).toNamed.name should be("in")
foo.ports1(1).toNamed.name should be("out")
foo.ports1(2).toNamed.name should be("other")
})
}
}
Loading