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