diplomacy: change API to auto-create node bundles => cross-module refs
This commit is contained in:
@ -6,6 +6,7 @@ import Chisel._
|
||||
import chisel3.experimental.{BaseModule, RawModule, MultiIOModule, withClockAndReset}
|
||||
import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo}
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import scala.collection.immutable.ListMap
|
||||
|
||||
abstract class LazyModule()(implicit val p: Parameters)
|
||||
{
|
||||
@ -54,15 +55,6 @@ abstract class LazyModule()(implicit val p: Parameters)
|
||||
|
||||
def module: LazyModuleImpLike
|
||||
|
||||
protected[diplomacy] def instantiate() = {
|
||||
children.reverse.foreach { c =>
|
||||
// !!! fix chisel3 so we can pass the desired sourceInfo
|
||||
// implicit val sourceInfo = c.module.outer.info
|
||||
Module(c.module)
|
||||
}
|
||||
bindings.reverse.foreach { f => f () }
|
||||
}
|
||||
|
||||
def omitGraphML: Boolean = !nodes.exists(!_.omitGraphML) && !children.exists(!_.omitGraphML)
|
||||
lazy val graphML: String = parent.map(_.graphML).getOrElse {
|
||||
val buf = new StringBuilder
|
||||
@ -144,6 +136,8 @@ object LazyModule
|
||||
sealed trait LazyModuleImpLike extends BaseModule
|
||||
{
|
||||
val wrapper: LazyModule
|
||||
val auto: AutoBundle
|
||||
protected[diplomacy] val dangles: Seq[Dangle]
|
||||
|
||||
// .module had better not be accessed while LazyModules are still being built!
|
||||
require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}")
|
||||
@ -152,18 +146,47 @@ sealed trait LazyModuleImpLike extends BaseModule
|
||||
suggestName(wrapper.instanceName)
|
||||
|
||||
implicit val p = wrapper.p
|
||||
|
||||
protected[diplomacy] def instantiate() = {
|
||||
val childDangles = wrapper.children.reverse.flatMap { c =>
|
||||
implicit val sourceInfo = c.info
|
||||
Module(c.module).dangles
|
||||
}
|
||||
val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate())
|
||||
val (toConnect, toForward) = (nodeDangles ++ childDangles).groupBy(_.source).partition(_._2.size == 2)
|
||||
val forward = toForward.map(_._2(0)).toList
|
||||
toConnect.foreach { case (_, Seq(a, b)) =>
|
||||
require (a.flipped != b.flipped)
|
||||
if (a.flipped) { a.data <> b.data } else { b.data <> a.data }
|
||||
}
|
||||
val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*))
|
||||
val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
|
||||
if (d.flipped) { d.data <> io } else { io <> d.data }
|
||||
d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name)
|
||||
}
|
||||
wrapper.bindings.reverse.foreach { f => f () }
|
||||
(auto, dangles)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LazyModuleImp(val wrapper: LazyModule) extends Module with LazyModuleImpLike {
|
||||
wrapper.instantiate()
|
||||
}
|
||||
|
||||
abstract class LazyMultiIOModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {
|
||||
wrapper.instantiate()
|
||||
abstract class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {
|
||||
val (auto, dangles) = instantiate()
|
||||
}
|
||||
|
||||
abstract class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike {
|
||||
withClockAndReset(Bool(false).asClock, Bool(true)) {
|
||||
wrapper.instantiate()
|
||||
val (auto, dangles) = withClockAndReset(Bool(false).asClock, Bool(true)) {
|
||||
instantiate()
|
||||
}
|
||||
}
|
||||
|
||||
case class HalfEdge(serial: Int, index: Int)
|
||||
case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, data: Data)
|
||||
|
||||
final class AutoBundle(elts: (String, Data, Boolean)*) extends Record {
|
||||
// !!! need to fix-up name collision better than appending _#
|
||||
val elements = ListMap(elts.zipWithIndex map { case ((field, elt, flip), i) =>
|
||||
(field + "_" + i) -> (if (flip) elt.cloneType.flip else elt.cloneType)
|
||||
}:_*)
|
||||
|
||||
override def cloneType = (new AutoBundle(elts:_*)).asInstanceOf[this.type]
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ private case object MonitorsEnabled extends Field[Boolean](true)
|
||||
// BI = Bundle type used when connecting to the inner side of the node
|
||||
trait InwardNodeImp[DI, UI, EI, BI <: Data]
|
||||
{
|
||||
def edgeI(pd: DI, pu: UI): EI
|
||||
def edgeI(pd: DI, pu: UI, p: Parameters): EI
|
||||
def bundleI(ei: EI): BI
|
||||
def colour: String
|
||||
def reverse: Boolean = false
|
||||
@ -55,7 +55,7 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data]
|
||||
// BO = Bundle type used when connecting to the outer side of the node
|
||||
trait OutwardNodeImp[DO, UO, EO, BO <: Data]
|
||||
{
|
||||
def edgeO(pd: DO, pu: UO): EO
|
||||
def edgeO(pd: DO, pu: UO, p: Parameters): EO
|
||||
def bundleO(eo: EO): BO
|
||||
|
||||
// optional methods to track node graph
|
||||
@ -75,11 +75,11 @@ abstract class BaseNode(implicit val valName: ValName)
|
||||
val index = lazyModule.nodes.size
|
||||
lazyModule.nodes = this :: lazyModule.nodes
|
||||
|
||||
val externalIn: Boolean
|
||||
val externalOut: Boolean
|
||||
val serial = BaseNode.serial
|
||||
BaseNode.serial = BaseNode.serial + 1
|
||||
protected[diplomacy] def instantiate(): Seq[Dangle]
|
||||
|
||||
def nodename = getClass.getName.split('.').last
|
||||
def name = lazyModule.name + "." + nodename
|
||||
def name = lazyModule.name + "." + valName.name
|
||||
def omitGraphML = outputs.isEmpty && inputs.isEmpty
|
||||
lazy val nodedebugstring: String = ""
|
||||
|
||||
@ -91,6 +91,11 @@ abstract class BaseNode(implicit val valName: ValName)
|
||||
protected[diplomacy] def reverse: Boolean
|
||||
}
|
||||
|
||||
object BaseNode
|
||||
{
|
||||
protected[diplomacy] var serial = 0
|
||||
}
|
||||
|
||||
case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
||||
(inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO])
|
||||
extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO]
|
||||
@ -138,7 +143,6 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI,
|
||||
protected[diplomacy] val iStar: Int
|
||||
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
|
||||
protected[diplomacy] val iParams: Seq[UI]
|
||||
protected[diplomacy] val bundleIn: HeterogeneousBag[BI]
|
||||
}
|
||||
|
||||
trait OutwardNodeHandle[DO, UO, BO <: Data]
|
||||
@ -171,10 +175,9 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO
|
||||
protected[diplomacy] val oStar: Int
|
||||
protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
|
||||
protected[diplomacy] val oParams: Seq[DO]
|
||||
protected[diplomacy] val bundleOut: HeterogeneousBag[BO]
|
||||
}
|
||||
|
||||
abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
inner: InwardNodeImp [DI, UI, EI, BI],
|
||||
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||
protected[diplomacy] val numPO: Range.Inclusive,
|
||||
@ -213,22 +216,22 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
||||
}
|
||||
|
||||
lazy val oPorts = oBindings.flatMap { case (i, n, _, _) =>
|
||||
lazy val oPorts = oBindings.flatMap { case (i, n, _, p) =>
|
||||
val (start, end) = n.iPortMapping(i)
|
||||
(start until end) map { j => (j, n) }
|
||||
(start until end) map { j => (j, n, p) }
|
||||
}
|
||||
lazy val iPorts = iBindings.flatMap { case (i, n, _, _) =>
|
||||
lazy val iPorts = iBindings.flatMap { case (i, n, _, p) =>
|
||||
val (start, end) = n.oPortMapping(i)
|
||||
(start until end) map { j => (j, n) }
|
||||
(start until end) map { j => (j, n, p) }
|
||||
}
|
||||
|
||||
protected[diplomacy] lazy val oParams: Seq[DO] = {
|
||||
val o = mapParamsD(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) })
|
||||
val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _) => n.oParams(i) })
|
||||
require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}")
|
||||
o.map(outer.mixO(_, this))
|
||||
}
|
||||
protected[diplomacy] lazy val iParams: Seq[UI] = {
|
||||
val i = mapParamsU(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) })
|
||||
val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _) => n.iParams(o) })
|
||||
require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}")
|
||||
i.map(inner.mixI(_, this))
|
||||
}
|
||||
@ -236,23 +239,48 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
protected[diplomacy] def gco = if (iParams.size != 1) None else inner.getO(iParams(0))
|
||||
protected[diplomacy] def gci = if (oParams.size != 1) None else outer.getI(oParams(0))
|
||||
|
||||
lazy val edgesOut = (oPorts zip oParams).map { case ((i, n), o) => outer.edgeO(o, n.iParams(i)) }
|
||||
lazy val edgesIn = (iPorts zip iParams).map { case ((o, n), i) => inner.edgeI(n.oParams(o), i) }
|
||||
lazy val externalEdgesOut = if (externalOut) {edgesOut} else { Seq() }
|
||||
lazy val externalEdgesIn = if (externalIn) {edgesIn} else { Seq() }
|
||||
protected[diplomacy] lazy val edgesOut = (oPorts zip oParams).map { case ((i, n, p), o) => outer.edgeO(o, n.iParams(i), p) }
|
||||
protected[diplomacy] lazy val edgesIn = (iPorts zip iParams).map { case ((o, n, p), i) => inner.edgeI(n.oParams(o), i, p) }
|
||||
|
||||
lazy val paramsOut: Seq[Parameters] = (oPortMapping zip oBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } }
|
||||
lazy val paramsIn: Seq[Parameters] = (iPortMapping zip iBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } }
|
||||
// If you need access to the edges of a foreign Node, use this method (in/out create bundles)
|
||||
lazy val edges = (edgesIn, edgesOut)
|
||||
|
||||
val flip = false // needed for blind nodes
|
||||
private def flipO(b: HeterogeneousBag[BO]) = if (flip) b.flip else b
|
||||
private def flipI(b: HeterogeneousBag[BI]) = if (flip) b else b.flip
|
||||
val wire = false // needed if you want to grab access to from inside a module
|
||||
private def wireO(b: HeterogeneousBag[BO]) = if (wire) Wire(b) else b
|
||||
private def wireI(b: HeterogeneousBag[BI]) = if (wire) Wire(b) else b
|
||||
protected[diplomacy] lazy val bundleOut: Seq[BO] = edgesOut.map(e => Wire(outer.bundleO(e)))
|
||||
protected[diplomacy] lazy val bundleIn: Seq[BI] = edgesIn .map(e => Wire(inner.bundleI(e)))
|
||||
|
||||
lazy val bundleOut = wireO(flipO(HeterogeneousBag(edgesOut.map(outer.bundleO(_)))))
|
||||
lazy val bundleIn = wireI(flipI(HeterogeneousBag(edgesIn .map(inner.bundleI(_)))))
|
||||
protected[diplomacy] def danglesOut: Seq[Dangle] = oPorts.zipWithIndex.map { case ((j, n, _), i) =>
|
||||
Dangle(
|
||||
source = HalfEdge(serial, i),
|
||||
sink = HalfEdge(n.serial, j),
|
||||
flipped= false,
|
||||
name = valName.name + "_out",
|
||||
data = bundleOut(i))
|
||||
}
|
||||
protected[diplomacy] def danglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _), i) =>
|
||||
Dangle(
|
||||
source = HalfEdge(n.serial, j),
|
||||
sink = HalfEdge(serial, i),
|
||||
flipped= true,
|
||||
name = valName.name + "_in",
|
||||
data = bundleIn(i))
|
||||
}
|
||||
|
||||
// Used by LazyModules.module.instantiate
|
||||
private var bundlesSafeNow = false
|
||||
protected[diplomacy] def instantiate() = {
|
||||
bundlesSafeNow = true
|
||||
danglesOut ++ danglesIn
|
||||
}
|
||||
|
||||
// Accessors to the result of negotiation to be used in LazyModuleImp:
|
||||
def out: Seq[(BO, EO)] = {
|
||||
require(bundlesSafeNow, s"${name}.out should only be called from the context of it's module implementation")
|
||||
bundleOut zip edgesOut
|
||||
}
|
||||
def in: Seq[(BI, EI)] = {
|
||||
require(bundlesSafeNow, s"${name}.in should only be called from the context of it's module implementation")
|
||||
bundleIn zip edgesIn
|
||||
}
|
||||
|
||||
// connects the outward part of a node with the inward part of this node
|
||||
private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)
|
||||
@ -268,23 +296,7 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
case BIND_STAR => BIND_QUERY
|
||||
case BIND_QUERY => BIND_STAR })
|
||||
x.iPush(o, y, binding)
|
||||
def edges() = {
|
||||
val (iStart, iEnd) = x.iPortMapping(i)
|
||||
val (oStart, oEnd) = y.oPortMapping(o)
|
||||
require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed")
|
||||
Seq.tabulate(iEnd - iStart) { j => x.edgesIn(iStart+j) }
|
||||
}
|
||||
def bundles() = {
|
||||
val (iStart, iEnd) = x.iPortMapping(i)
|
||||
val (oStart, oEnd) = y.oPortMapping(o)
|
||||
require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed")
|
||||
Seq.tabulate(iEnd - iStart) { j =>
|
||||
(x.bundleIn(iStart+j), y.bundleOut(oStart+j))
|
||||
}
|
||||
}
|
||||
val (out, newbinding) = inner.connect(edges _, bundles _, p(MonitorsEnabled))
|
||||
LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings
|
||||
out
|
||||
None // !!! create monitors
|
||||
}
|
||||
|
||||
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE)
|
||||
@ -333,9 +345,6 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
implicit valName: ValName)
|
||||
extends MixedNode(inner, outer)(num, num)
|
||||
{
|
||||
val externalIn: Boolean = true
|
||||
val externalOut: Boolean = true
|
||||
|
||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||
require (oStars + iStars <= 1, s"${name} (an adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||
if (oStars > 0) {
|
||||
@ -356,6 +365,24 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
}
|
||||
}
|
||||
|
||||
class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||
dFn: D => D,
|
||||
uFn: U => U,
|
||||
num: Range.Inclusive = 0 to 999)(
|
||||
implicit valName: ValName)
|
||||
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num)
|
||||
|
||||
// IdentityNodes automatically connect their inputs to outputs
|
||||
class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName)
|
||||
extends AdapterNode(imp)({ s => s }, { s => s })
|
||||
{
|
||||
override protected[diplomacy] def instantiate() = {
|
||||
val dangles = super.instantiate()
|
||||
(out zip in) map { case ((o, _), (i, _)) => o <> i }
|
||||
dangles
|
||||
}
|
||||
}
|
||||
|
||||
class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
inner: InwardNodeImp [DI, UI, EI, BI],
|
||||
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||
@ -369,9 +396,6 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
// require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}")
|
||||
// require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}")
|
||||
|
||||
val externalIn: Boolean = true
|
||||
val externalOut: Boolean = true
|
||||
|
||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||
require (iStars == 0, s"${name} (a nexus) appears left of :*= (perhaps you should flip the '*' to :=*?)${lazyModule.line}")
|
||||
require (oStars == 0, s"${name} (a nexus) appears right of a :=* (perhaps you should flip the '*' to :*=?)${lazyModule.line}")
|
||||
@ -381,13 +405,6 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { val a = uFn(p); Seq.fill(n)(a) }
|
||||
}
|
||||
|
||||
class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||
dFn: D => D,
|
||||
uFn: U => U,
|
||||
num: Range.Inclusive = 0 to 999)(
|
||||
implicit valName: ValName)
|
||||
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num)
|
||||
|
||||
class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||
dFn: Seq[D] => D,
|
||||
uFn: Seq[U] => U,
|
||||
@ -396,30 +413,10 @@ class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||
implicit valName: ValName)
|
||||
extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI)
|
||||
|
||||
class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName)
|
||||
extends AdapterNode(imp)({s => s}, {s => s})
|
||||
|
||||
class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp)
|
||||
{
|
||||
override val externalIn: Boolean = false
|
||||
override val externalOut: Boolean = true
|
||||
override lazy val bundleIn = bundleOut
|
||||
}
|
||||
|
||||
class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp)
|
||||
{
|
||||
override val externalIn: Boolean = true
|
||||
override val externalOut: Boolean = false
|
||||
|
||||
override lazy val bundleOut = bundleIn
|
||||
}
|
||||
|
||||
// There are no Mixed SourceNodes
|
||||
class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
||||
extends MixedNode(imp, imp)(po.size to po.size, 0 to 0)
|
||||
{
|
||||
override val externalIn: Boolean = false
|
||||
override val externalOut: Boolean = true
|
||||
|
||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||
require (oStars <= 1, s"${name} (a source) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||
require (iStars == 0, s"${name} (a source) cannot appear left of a :*=${lazyModule.line}")
|
||||
@ -429,16 +426,12 @@ class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq
|
||||
}
|
||||
protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = po
|
||||
protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = Seq()
|
||||
|
||||
override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut }
|
||||
}
|
||||
|
||||
// There are no Mixed SinkNodes
|
||||
class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
||||
extends MixedNode(imp, imp)(0 to 0, pi.size to pi.size)
|
||||
{
|
||||
override val externalIn: Boolean = true
|
||||
override val externalOut: Boolean = false
|
||||
|
||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||
require (iStars <= 1, s"${name} (a sink) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
|
||||
require (oStars == 0, s"${name} (a sink) cannot appear right of a :=*${lazyModule.line}")
|
||||
@ -448,40 +441,4 @@ 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
|
||||
|
||||
override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn }
|
||||
}
|
||||
|
||||
class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
||||
extends SinkNode(imp)(pi)
|
||||
{
|
||||
override val externalIn: Boolean = false
|
||||
override val flip = true
|
||||
override lazy val bundleOut = bundleIn
|
||||
}
|
||||
|
||||
class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
||||
extends SourceNode(imp)(po)
|
||||
{
|
||||
override val externalOut: Boolean = false
|
||||
override val flip = true
|
||||
override lazy val bundleIn = bundleOut
|
||||
}
|
||||
|
||||
class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
||||
extends SinkNode(imp)(pi)
|
||||
{
|
||||
override val externalIn: Boolean = false
|
||||
override val externalOut: Boolean = false
|
||||
override val wire = true
|
||||
override lazy val bundleOut = bundleIn
|
||||
}
|
||||
|
||||
class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
||||
extends SourceNode(imp)(po)
|
||||
{
|
||||
override val externalIn: Boolean = false
|
||||
override val externalOut: Boolean = false
|
||||
override val wire = true
|
||||
override lazy val bundleIn = bundleOut
|
||||
}
|
||||
|
Reference in New Issue
Block a user