diff options
| author | mergify[bot] | 2022-03-09 20:40:25 +0000 |
|---|---|---|
| committer | GitHub | 2022-03-09 20:40:25 +0000 |
| commit | 4ee545d7706a2d2ba59902fb86a4393287327a9a (patch) | |
| tree | 657ed76babbc56ac2edc6b49f221f474783c77d3 /core/src | |
| parent | 941dd7ee76cadacbdd10b3d10d267f5d58a7ed4e (diff) | |
Support BlackBoxes in D/I (#2438) (#2442)
Also delete an errant println in InstanceSpec
(cherry picked from commit 3462c54c018a52a377f1c89121b6ed99c5b0ae1d)
Co-authored-by: Jack Koenig <koenig@sifive.com>
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/main/scala/chisel3/Module.scala | 34 | ||||
| -rw-r--r-- | core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala | 7 |
2 files changed, 32 insertions, 9 deletions
diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index ed323504..84139630 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -248,8 +248,14 @@ package internal { } // Maps proto ports to module clone's ports private[chisel3] lazy val ioMap: Map[Data, Data] = { - val name2Port = getPorts.elements - getProto.getChiselPorts.map { case (name, data) => data -> name2Port(name) }.toMap + getProto match { + // BlackBox needs special handling for its pseduo-io Bundle + case protoBB: BlackBox => + Map(protoBB._io.get -> getPorts.elements("io")) + case _ => + val name2Port = getPorts.elements + getProto.getChiselPorts.map { case (name, data) => data -> name2Port(name) }.toMap + } } // This module doesn't actually exist in the FIRRTL so no initialization to do private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = () @@ -267,7 +273,17 @@ package internal { case bad => throwException(s"Internal Error! Cloned-module Record $record has unexpected ref $bad") } // Set both the record and the module to have the same instance name - record.setRef(ModuleCloneIO(getProto, instName), force = true) // force because we did .forceName first + val ref = ModuleCloneIO(getProto, instName) + record.setRef(ref, force = true) // force because we did .forceName first + getProto match { + // BlackBox needs special handling for its pseduo-io Bundle + case _: BlackBox => + // Override the io Bundle's ref so that it thinks it is the top for purposes of + // generating FIRRTL + record.elements("io").setRef(ref, force = true) + case _ => // Do nothing + } + this.setRef(Ref(instName)) } } @@ -329,8 +345,8 @@ package internal { * @note These are not true Data (the Record doesn't correspond to anything in the emitted * FIRRTL yet its elements *do*) so have some very specialized behavior. */ - private[chisel3] class ClonePorts(elts: Data*)(implicit compileOptions: CompileOptions) extends Record { - val elements = ListMap(elts.map(d => d.instanceName -> d.cloneTypeFull): _*) + private[chisel3] class ClonePorts(elts: (String, Data)*)(implicit compileOptions: CompileOptions) extends Record { + val elements = ListMap(elts.map { case (name, d) => name -> d.cloneTypeFull }: _*) def apply(field: String) = elements(field) override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type] } @@ -351,12 +367,18 @@ package internal { // Fake Module to serve as the _parent of the cloned ports // We don't create this inside the ModuleClone because we need the ref to be set by the // currentModule (and not clonePorts) - val clonePorts = new ClonePorts(proto.getModulePorts: _*) + val clonePorts = proto match { + // BlackBox needs special handling for its pseduo-io Bundle + case b: BlackBox => + new ClonePorts(proto.getChiselPorts :+ ("io" -> b._io.get): _*) + case _ => new ClonePorts(proto.getChiselPorts: _*) + } clonePorts.bind(PortBinding(cloneParent)) clonePorts.setAllParents(Some(cloneParent)) cloneParent._portsRecord = clonePorts // Normally handled during Module construction but ClonePorts really lives in its parent's parent if (!compileOptions.explicitInvalidate) { + // FIXME This almost certainly doesn't work since clonePorts is not a real thing... pushCommand(DefInvalid(sourceInfo, clonePorts.ref)) } if (proto.isInstanceOf[Module]) { diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala index bc94f95d..60290f83 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala @@ -10,7 +10,7 @@ import scala.annotation.implicitNotFound import scala.collection.mutable.HashMap import chisel3._ import chisel3.experimental.dataview.{isView, reify, reifySingleData} -import chisel3.internal.firrtl.{Arg, ILit, Index, Slot, ULit} +import chisel3.internal.firrtl.{Arg, ILit, Index, ModuleIO, Slot, ULit} import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBinding, ViewBinding, ViewParent} /** Represents lookup typeclass to determine how a value accessed from an original IsInstantiable @@ -123,8 +123,8 @@ object Lookupable { def unrollCoordinates(res: List[Arg], d: Data): (List[Arg], Data) = d.binding.get match { case ChildBinding(parent) => d.getRef match { - case arg @ (_: Slot | _: Index) => unrollCoordinates(arg :: res, parent) - case other => err(s"Unroll coordinates failed for '$arg'! Unexpected arg '$other'") + case arg @ (_: Slot | _: Index | _: ModuleIO) => unrollCoordinates(arg :: res, parent) + case other => err(s"unrollCoordinates failed for '$arg'! Unexpected arg '$other'") } case _ => (res, d) } @@ -135,6 +135,7 @@ object Lookupable { val next = (coor.head, d) match { case (Slot(_, name), rec: Record) => rec.elements(name) case (Index(_, ILit(n)), vec: Vec[_]) => vec.apply(n.toInt) + case (ModuleIO(_, name), rec: Record) => rec.elements(name) case (arg, _) => err(s"Unexpected Arg '$arg' applied to '$d'! Root was '$start'.") } applyCoordinates(coor.tail, next) |
