diff options
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala | 3 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Data.scala | 4 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Module.scala | 16 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/BlackBox.scala | 8 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/ExtModule.scala | 8 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/Module.scala | 12 |
6 files changed, 50 insertions, 1 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala index 3e7251c5..57acd7b3 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala @@ -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 diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index cab6075e..869e22fb 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -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 diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 399f0462..88013bae 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -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. * diff --git a/src/test/scala/chiselTests/BlackBox.scala b/src/test/scala/chiselTests/BlackBox.scala index 27895a54..b45171f4 100644 --- a/src/test/scala/chiselTests/BlackBox.scala +++ b/src/test/scala/chiselTests/BlackBox.scala @@ -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)) + }) + } } diff --git a/src/test/scala/chiselTests/ExtModule.scala b/src/test/scala/chiselTests/ExtModule.scala index 6bffa333..5d5b51f9 100644 --- a/src/test/scala/chiselTests/ExtModule.scala +++ b/src/test/scala/chiselTests/ExtModule.scala @@ -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)) + }) + } } diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index 5f2927dd..968e7578 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -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)) + }) + } } |
