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 DataMirror.modulePorts #901

Merged
merged 3 commits into from
Oct 3, 2018
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
3 changes: 2 additions & 1 deletion chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param
require(!_closed, "Can't generate module more than once")
_closed = true

val namedPorts = io.elements.toSeq
val namedPorts = io.elements.toSeq.reverse // ListMaps are stored in reverse order

// setRef is not called on the actual io.
// There is a risk of user improperly attempting to connect directly with io
// Long term solution will be to define BlackBox IO differently as part of
Expand Down
4 changes: 4 additions & 0 deletions chiselFrontend/src/main/scala/chisel3/core/Data.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ object DataMirror {
target.direction
}

// TODO: maybe move to something like Driver or DriverUtils, since this is mainly for interacting
// with compiled artifacts (vs. elaboration-time reflection)?
def modulePorts(target: BaseModule): Seq[(String, Data)] = target.getChiselPorts

// Internal reflection-style APIs, subject to change and removal whenever.
object internal {
def isSynthesizable(target: Data) = target.topBindingOpt.isDefined
Expand Down
16 changes: 16 additions & 0 deletions chiselFrontend/src/main/scala/chisel3/core/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,22 @@ abstract class BaseModule extends HasId {
*/
final def toNamed: ModuleName = ModuleName(this.name, CircuitName(this.circuitName))

/**
* Internal API. Returns a list of this module's generated top-level ports as a map of a String
* (FIRRTL name) to the IO object. Only valid after the module is closed.
*
* Note: for BlackBoxes (but not ExtModules), this returns the contents of the top-level io
* object, consistent with what is emitted in FIRRTL.
*
* TODO: Use SeqMap/VectorMap when those data structures become available.
*/
private[core] def getChiselPorts: Seq[(String, Data)] = {
require(_closed, "Can't get ports before module close")
_component.get.ports.map { port =>
(port.id.getRef.asInstanceOf[ModuleIO].name, port.id)
}
}

/** Called at the Module.apply(...) level after this Module has finished elaborating.
* Returns a map of nodes -> names, for named nodes.
*
Expand Down
8 changes: 8 additions & 0 deletions src/test/scala/chiselTests/BlackBox.scala
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,12 @@ class BlackBoxSpec extends ChiselFlatSpec {
assertTesterPasses({ new BlackBoxWithParamsTester },
Seq("/chisel3/BlackBoxTest.v"))
}
"DataMirror.modulePorts" should "work with BlackBox" in {
elaborate(new Module {
val io = IO(new Bundle { })
val m = Module(new BlackBoxPassthrough)
assert(chisel3.experimental.DataMirror.modulePorts(m) == Seq(
"in" -> m.io.in, "out" -> m.io.out))
})
}
}
8 changes: 8 additions & 0 deletions src/test/scala/chiselTests/ExtModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,12 @@ class ExtModuleSpec extends ChiselFlatSpec {
assertTesterPasses({ new MultiExtModuleTester },
Seq("/chisel3/BlackBoxTest.v"))
}
"DataMirror.modulePorts" should "work with ExtModule" in {
elaborate(new Module {
val io = IO(new Bundle { })
val m = Module(new ExtModule.BlackBoxPassthrough)
assert(chisel3.experimental.DataMirror.modulePorts(m) == Seq(
"in" -> m.in, "out" -> m.out))
})
}
}
12 changes: 12 additions & 0 deletions src/test/scala/chiselTests/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,16 @@ class ModuleSpec extends ChiselPropSpec {
assert(checkModule(this))
})
}
property("DataMirror.modulePorts should work") {
elaborate(new Module {
val io = IO(new Bundle { })
val m = Module(new chisel3.experimental.MultiIOModule {
val a = IO(UInt(8.W))
val b = IO(Bool())
})
assert(chisel3.experimental.DataMirror.modulePorts(m) == Seq(
"clock" -> m.clock, "reset" -> m.reset,
"a" -> m.a, "b" -> m.b))
})
}
}