diplomacy: protect more of the unstable API
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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] | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user