From cc789e9063bba4740aa2e2bfbe5421fb599b58f5 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 7 Nov 2017 13:08:30 -0800 Subject: [PATCH] diplomacy: protect more of the unstable API --- src/main/scala/diplomacy/Clone.scala | 46 ++-------------------- src/main/scala/diplomacy/CloneModule.scala | 25 ++++++------ src/main/scala/diplomacy/Nodes.scala | 42 ++++++++++++++++++++ 3 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/main/scala/diplomacy/Clone.scala b/src/main/scala/diplomacy/Clone.scala index 92920f51..0eeb1b81 100644 --- a/src/main/scala/diplomacy/Clone.scala +++ b/src/main/scala/diplomacy/Clone.scala @@ -5,54 +5,14 @@ package freechips.rocketchip.diplomacy import Chisel._ import chisel3.shim.CloneModule -class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( - node: NodeHandle [DI, UI, EI, BI, DO, UO, EO, BO], clone: CloneLazyModule)( - implicit valName: ValName) - extends MixedCustomNode(node.inner, node.outer)( - numPI = node.inward .uiParams.size to node.inward .uiParams.size, - numPO = node.outward.doParams.size to node.outward.doParams.size) -{ - // The devices connected to this test node must recreate these parameters: - def sourceParams: Seq[DI] = node.inward .diParams - def sinkParams: Seq[UO] = node.outward.uoParams - - def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { - require (oStars <= 1, s"${name} (a test node) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}") - require (iStars <= 1, s"${name} (a test node) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}") - (node.inward.uiParams.size - iKnown, node.outward.doParams.size - oKnown) - } - - def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = node.inward .uiParams - def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = node.outward.doParams - - override protected[diplomacy] def instantiate() = { - val dangles = super.instantiate() - val orig_module = clone.base.module - val clone_auto = clone.io("auto").asInstanceOf[AutoBundle] - - danglesOut.zipWithIndex.foreach { case (d, i) => - val orig = orig_module.dangles.find(_.source == HalfEdge(node.outward.serial, i)) - require (orig.isDefined, s"Cloned node ${node.outward.name} must be connected externally out ${orig_module.name}") - val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1 - d.data <> clone_auto.elements(io_name) - } - danglesIn.zipWithIndex.foreach { case (d, i) => - val orig = orig_module.dangles.find(_.sink == HalfEdge(node.inward.serial, i)) - require (orig.isDefined, s"Cloned node ${node.inward.name} must be connected externally in ${orig_module.name}") - val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1 - clone_auto.elements(io_name) <> d.data - } - - dangles - } -} - final class CloneLazyModule private (val base: LazyModule) { + // Pay special attention to the .iParams and .oParams of the node, which + // indicate the parameters a stand-in master must supply. def clone[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](node: NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO])(implicit valName: ValName) = new MixedTestNode(node, this) - lazy val io = CloneModule(base.module) + protected[diplomacy] lazy val io = CloneModule(base.module) } object CloneLazyModule diff --git a/src/main/scala/diplomacy/CloneModule.scala b/src/main/scala/diplomacy/CloneModule.scala index bacb4c6c..42f7a3ab 100644 --- a/src/main/scala/diplomacy/CloneModule.scala +++ b/src/main/scala/diplomacy/CloneModule.scala @@ -13,18 +13,20 @@ import chisel3.internal.firrtl.{Command, DefInstance} import scala.collection.immutable.ListMap import scala.collection.mutable.ArrayBuffer -class CloneModule private (model: RawModule) extends BlackBox +class ClonePorts protected[shim](elts: Data*) extends Record +{ + val elements = ListMap(elts.map(d => d.instanceName -> d.chiselCloneType): _*) + def apply(field: String) = elements(field) + override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type] +} + +private class CloneModule private (model: RawModule) extends BlackBox { import CloneModule._ override def desiredName = model.name val io = IO(new ClonePorts(model.getPorts.map(_.id): _*)) } -class HackDefInstance(imp: DefInstance, _name: => String) extends DefInstance(imp.sourceInfo, imp.id, imp.ports) -{ - override def name = _name -} - object CloneModule { def apply(model: BaseModule): ClonePorts = { @@ -40,7 +42,9 @@ object CloneModule case _ => false } val victim = commands(victimIdx).asInstanceOf[DefInstance] - val standin = new HackDefInstance(victim.copy(id = model), victim.name) + val standin = new DefInstance(victim.sourceInfo, model, victim.ports) { + override def name = victim.name + } commands.update(victimIdx, standin) // Wire it up model match { @@ -52,10 +56,3 @@ object CloneModule mod.io } } - -class ClonePorts(elts: Data*) extends Record -{ - val elements = ListMap(elts.map(d => d.instanceName -> d.chiselCloneType): _*) - def apply(field: String) = elements(field) - override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type] -} diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index f2fa021e..94db342a 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -535,3 +535,45 @@ class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = Seq() protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = pi } + +class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] protected[diplomacy]( + node: NodeHandle [DI, UI, EI, BI, DO, UO, EO, BO], clone: CloneLazyModule)( + implicit valName: ValName) + extends MixedNode(node.inner, node.outer)( + numPI = node.inward .uiParams.size to node.inward .uiParams.size, + numPO = node.outward.doParams.size to node.outward.doParams.size) +{ + // The devices connected to this test node must recreate these parameters: + def iParams: Seq[DI] = node.inward .diParams + def oParams: Seq[UO] = node.outward.uoParams + + protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { + require (oStars <= 1, s"${name} (a test node) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}") + require (iStars <= 1, s"${name} (a test node) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}") + (node.inward.uiParams.size - iKnown, node.outward.doParams.size - oKnown) + } + + protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = node.inward .uiParams + protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = node.outward.doParams + + override protected[diplomacy] def instantiate() = { + val dangles = super.instantiate() + val orig_module = clone.base.module + val clone_auto = clone.io("auto").asInstanceOf[AutoBundle] + + danglesOut.zipWithIndex.foreach { case (d, i) => + val orig = orig_module.dangles.find(_.source == HalfEdge(node.outward.serial, i)) + require (orig.isDefined, s"Cloned node ${node.outward.name} must be connected externally out ${orig_module.name}") + val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1 + d.data <> clone_auto.elements(io_name) + } + danglesIn.zipWithIndex.foreach { case (d, i) => + val orig = orig_module.dangles.find(_.sink == HalfEdge(node.inward.serial, i)) + require (orig.isDefined, s"Cloned node ${node.inward.name} must be connected externally in ${orig_module.name}") + val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1 + clone_auto.elements(io_name) <> d.data + } + + dangles + } +}