1
0

Merge pull request #536 from ucb-bar/diplomacy-star-nodes

diplomacy: add :*= and :=* to support flexible # of edges
This commit is contained in:
Henry Cook 2017-01-30 11:19:33 -08:00 committed by GitHub
commit b567a2a356
42 changed files with 1948 additions and 1895 deletions

View File

@ -11,17 +11,14 @@ import util._
class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex
with CoreplexRISCVPlatform with CoreplexRISCVPlatform
with HasL2MasterPort
with HasRocketTiles { with HasRocketTiles {
override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this))
} }
class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer)
with CoreplexRISCVPlatformBundle with CoreplexRISCVPlatformBundle
with HasL2MasterPortBundle
with HasRocketTilesBundle with HasRocketTilesBundle
class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io)
with CoreplexRISCVPlatformModule with CoreplexRISCVPlatformModule
with HasL2MasterPortModule
with HasRocketTilesModule with HasRocketTilesModule

View File

@ -24,9 +24,13 @@ trait CoreplexNetwork extends HasCoreplexParameters {
val mmio = TLOutputNode() val mmio = TLOutputNode()
val mmioInt = IntInputNode() val mmioInt = IntInputNode()
val l2in = TLInputNode()
intBar.intnode := mmioInt intBar.intnode := mmioInt
// Allows a variable number of inputs from outside to the Xbar
l1tol2.node :=* l2in
cbus.node := cbus.node :=
TLBuffer()( TLBuffer()(
TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata
@ -43,6 +47,7 @@ trait CoreplexNetworkBundle extends HasCoreplexParameters {
val mmio = outer.mmio.bundleOut val mmio = outer.mmio.bundleOut
val interrupts = outer.mmioInt.bundleIn val interrupts = outer.mmioInt.bundleIn
val l2in = outer.l2in.bundleIn
} }
trait CoreplexNetworkModule extends HasCoreplexParameters { trait CoreplexNetworkModule extends HasCoreplexParameters {
@ -93,21 +98,3 @@ trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule {
val outer: BankedL2CoherenceManagers val outer: BankedL2CoherenceManagers
val io: BankedL2CoherenceManagersBundle val io: BankedL2CoherenceManagersBundle
} }
/////
trait HasL2MasterPort extends CoreplexNetwork {
val module: HasL2MasterPortModule
val l2in = TLInputNode()
l1tol2.node := TLBuffer()(l2in)
}
trait HasL2MasterPortBundle extends CoreplexNetworkBundle {
val outer: HasL2MasterPort
val l2in = outer.l2in.bundleIn
}
trait HasL2MasterPortModule extends CoreplexNetworkModule {
val outer: HasL2MasterPort
val io: HasL2MasterPortBundle
}

View File

@ -16,7 +16,9 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data]
def edgeI(pd: DI, pu: UI): EI def edgeI(pd: DI, pu: UI): EI
def bundleI(ei: Seq[EI]): Vec[BI] def bundleI(ei: Seq[EI]): Vec[BI]
def colour: String def colour: String
def connect(bo: => BI, bi: => BI, e: => EI)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) def connect(bindings: () => Seq[(EI, BI, BI)])(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => bindings().foreach { case (_, i, o) => i <> o })
}
// optional methods to track node graph // optional methods to track node graph
def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters
@ -71,8 +73,17 @@ trait InwardNodeHandle[DI, UI, BI <: Data]
val inward: InwardNode[DI, UI, BI] val inward: InwardNode[DI, UI, BI]
def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] =
inward.:=(h)(p, sourceInfo) inward.:=(h)(p, sourceInfo)
def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] =
inward.:*=(h)(p, sourceInfo)
def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] =
inward.:=*(h)(p, sourceInfo)
} }
sealed trait NodeBinding
case object BIND_ONCE extends NodeBinding
case object BIND_QUERY extends NodeBinding
case object BIND_STAR extends NodeBinding
trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI] trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI]
{ {
val inward = this val inward = this
@ -81,21 +92,22 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI,
require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}") require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}")
require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}") require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}")
private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI])]() private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding)]()
private var iRealized = false private var iRealized = false
protected[diplomacy] def iPushed = accPI.size protected[diplomacy] def iPushed = accPI.size
protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI])(implicit sourceInfo: SourceInfo) { protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit sourceInfo: SourceInfo) {
val info = sourceLine(sourceInfo, " at ", "") val info = sourceLine(sourceInfo, " at ", "")
val noIs = numPI.size == 1 && numPI.contains(0) val noIs = numPI.size == 1 && numPI.contains(0)
require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info) require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info)
require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info) require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info)
accPI += ((index, node)) accPI += ((index, node, binding))
} }
private def reqI() = require(numPI.contains(accPI.size), s"${name} has ${accPI.size} inputs, expected ${numPI}${lazyModule.line}") protected[diplomacy] lazy val iBindings = { iRealized = true; accPI.result() }
protected[diplomacy] lazy val iPorts = { iRealized = true; reqI(); accPI.result() }
protected[diplomacy] val iStar: Int
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
protected[diplomacy] val iParams: Seq[UI] protected[diplomacy] val iParams: Seq[UI]
val bundleIn: Vec[BI] val bundleIn: Vec[BI]
} }
@ -113,48 +125,84 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO
require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}") require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}")
require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}") require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}")
private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO])]() private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding)]()
private var oRealized = false private var oRealized = false
protected[diplomacy] def oPushed = accPO.size protected[diplomacy] def oPushed = accPO.size
protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO])(implicit sourceInfo: SourceInfo) { protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit sourceInfo: SourceInfo) {
val info = sourceLine(sourceInfo, " at ", "") val info = sourceLine(sourceInfo, " at ", "")
val noOs = numPO.size == 1 && numPO.contains(0) val noOs = numPO.size == 1 && numPO.contains(0)
require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info) require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info)
require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after it's .module was used" + info) require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after it's .module was used" + info)
accPO += ((index, node)) accPO += ((index, node, binding))
} }
private def reqO() = require(numPO.contains(accPO.size), s"${name} has ${accPO.size} outputs, expected ${numPO}${lazyModule.line}") protected[diplomacy] lazy val oBindings = { oRealized = true; accPO.result() }
protected[diplomacy] lazy val oPorts = { oRealized = true; reqO(); accPO.result() }
protected[diplomacy] val oStar: Int
protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
protected[diplomacy] val oParams: Seq[DO] protected[diplomacy] val oParams: Seq[DO]
val bundleOut: Vec[BO] val bundleOut: Vec[BO]
} }
class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
inner: InwardNodeImp [DI, UI, EI, BI], inner: InwardNodeImp [DI, UI, EI, BI],
outer: OutwardNodeImp[DO, UO, EO, BO])( outer: OutwardNodeImp[DO, UO, EO, BO])(
private val dFn: (Int, Seq[DI]) => Seq[DO],
private val uFn: (Int, Seq[UO]) => Seq[UI],
protected[diplomacy] val numPO: Range.Inclusive, protected[diplomacy] val numPO: Range.Inclusive,
protected[diplomacy] val numPI: Range.Inclusive) protected[diplomacy] val numPI: Range.Inclusive)
extends BaseNode with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] extends BaseNode with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO]
{ {
// meta-data for printing the node graph protected[diplomacy] def resolveStarO(i: Int, o: Int): Int
protected[diplomacy] def colour = inner.colour protected[diplomacy] def resolveStarI(i: Int, o: Int): Int
protected[diplomacy] def outputs = oPorts.map(_._2) zip edgesOut.map(e => outer.labelO(e)) protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
protected[diplomacy] def inputs = iPorts.map(_._2) zip edgesIn .map(e => inner.labelI(e)) protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = {
val oStars = oBindings.filter { case (_,_,b) => b == BIND_STAR }.size
val iStars = iBindings.filter { case (_,_,b) => b == BIND_STAR }.size
require (oStars + iStars <= 1, s"${name} appears beside a :*= ${iStars} times and a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
val oKnown = oBindings.map { case (_, n, b) => b match {
case BIND_ONCE => 1
case BIND_QUERY => n.iStar
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
val iKnown = iBindings.map { case (_, n, b) => b match {
case BIND_ONCE => 1
case BIND_QUERY => n.oStar
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
val oStar = if (oStars > 0) resolveStarO(iKnown, oKnown) else 0
val iStar = if (iStars > 0) resolveStarI(iKnown, oKnown) else 0
val oSum = oBindings.map { case (_, n, b) => b match {
case BIND_ONCE => 1
case BIND_QUERY => n.iStar
case BIND_STAR => oStar }}.scanLeft(0)(_+_)
val iSum = iBindings.map { case (_, n, b) => b match {
case BIND_ONCE => 1
case BIND_QUERY => n.oStar
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
val oTotal = oSum.lastOption.getOrElse(0)
val iTotal = iSum.lastOption.getOrElse(0)
require(numPO.contains(oTotal), s"${name} has ${oTotal} outputs, expected ${numPO}${lazyModule.line}")
require(numPI.contains(iTotal), s"${name} has ${iTotal} inputs, expected ${numPI}${lazyModule.line}")
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
}
lazy val oPorts = oBindings.flatMap { case (i, n, _) =>
val (start, end) = n.iPortMapping(i)
(start until end) map { j => (j, n) }
}
lazy val iPorts = iBindings.flatMap { case (i, n, _) =>
val (start, end) = n.oPortMapping(i)
(start until end) map { j => (j, n) }
}
private def reqE(o: Int, i: Int) = require(i == o, s"${name} has ${i} inputs and ${o} outputs; they must match${lazyModule.line}")
protected[diplomacy] lazy val oParams: Seq[DO] = { protected[diplomacy] lazy val oParams: Seq[DO] = {
val o = dFn(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) }) val o = mapParamsD(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) })
reqE(oPorts.size, o.size) 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)) o.map(outer.mixO(_, this))
} }
protected[diplomacy] lazy val iParams: Seq[UI] = { protected[diplomacy] lazy val iParams: Seq[UI] = {
val i = uFn(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) }) val i = mapParamsU(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) })
reqE(i.size, iPorts.size) 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)) i.map(inner.mixI(_, this))
} }
@ -175,87 +223,174 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
lazy val bundleIn = wireI(flipI(inner.bundleI(edgesIn))) lazy val bundleIn = wireI(flipI(inner.bundleI(edgesIn)))
// connects the outward part of a node with the inward part of this node // connects the outward part of a node with the inward part of this node
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = { private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = {
val x = this // x := y val x = this // x := y
val y = h.outward val y = h.outward
val info = sourceLine(sourceInfo, " at ", "") val info = sourceLine(sourceInfo, " at ", "")
require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info) require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info)
val i = x.iPushed val i = x.iPushed
val o = y.oPushed val o = y.oPushed
y.oPush(i, x) y.oPush(i, x, binding match {
x.iPush(o, y) case BIND_ONCE => BIND_ONCE
val (out, binding) = inner.connect(y.bundleOut(o), x.bundleIn(i), x.edgesIn(i)) case BIND_STAR => BIND_QUERY
LazyModule.stack.head.bindings = binding :: LazyModule.stack.head.bindings case BIND_QUERY => BIND_STAR })
x.iPush(o, y, binding)
def bindings() = {
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), x.bundleIn(iStart+j), y.bundleOut(oStart+j))
}
}
val (out, newbinding) = inner.connect(bindings _)
LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings
out out
} }
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = bind(h, BIND_ONCE)
override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = bind(h, BIND_STAR)
override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = bind(h, BIND_QUERY)
// meta-data for printing the node graph
protected[diplomacy] def colour = inner.colour
protected[diplomacy] def outputs = oPorts.map(_._2) zip edgesOut.map(e => outer.labelO(e))
protected[diplomacy] def inputs = iPorts.map(_._2) zip edgesIn .map(e => inner.labelI(e))
}
class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
inner: InwardNodeImp [DI, UI, EI, BI],
outer: OutwardNodeImp[DO, UO, EO, BO])(
dFn: DI => DO,
uFn: UO => UI,
num: Range.Inclusive = 0 to 999)
extends MixedNode(inner, outer)(num, num)
{
protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = {
require (i >= o, s"${name} has ${o} outputs and ${i} inputs; cannot assign ${i-o} edges to resolve :=*${lazyModule.line}")
i - o
}
protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = {
require (o >= i, s"${name} has ${o} outputs and ${i} inputs; cannot assign ${o-i} edges to resolve :*=${lazyModule.line}")
o - i
}
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = {
require(n == p.size, s"${name} has ${p.size} inputs and ${n} outputs; they must match${lazyModule.line}")
p.map(dFn)
}
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = {
require(n == p.size, s"${name} has ${n} inputs and ${p.size} outputs; they must match${lazyModule.line}")
p.map(uFn)
}
} }
class SimpleNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
oFn: (Int, Seq[D]) => Seq[D], inner: InwardNodeImp [DI, UI, EI, BI],
iFn: (Int, Seq[U]) => Seq[U], outer: OutwardNodeImp[DO, UO, EO, BO])(
numPO: Range.Inclusive, dFn: Seq[DI] => DO,
numPI: Range.Inclusive) uFn: Seq[UO] => UI,
extends MixedNode[D, U, EI, B, D, U, EO, B](imp, imp)(oFn, iFn, numPO, numPI) numPO: Range.Inclusive = 1 to 999,
numPI: Range.Inclusive = 1 to 999)
extends MixedNode(inner, outer)(numPO, numPI)
{
require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}")
require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}")
protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = {
require (false, "${name} cannot resolve :=*${lazyModule.line}")
0
}
protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = {
require (false, s"${name} cannot resolve :*=${lazyModule.line}")
0
}
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = Seq.fill(n) { dFn(p) }
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = Seq.fill(n) { uFn(p) }
}
class IdentityNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
extends SimpleNode(imp)({case (_, s) => s}, {case (_, s) => s}, 0 to 999, 0 to 999) dFn: D => D,
uFn: U => U,
num: Range.Inclusive = 0 to 999)
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num)
class OutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) extends IdentityNode(imp) class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
dFn: Seq[D] => D,
uFn: Seq[U] => U,
numPO: Range.Inclusive = 1 to 999,
numPI: Range.Inclusive = 1 to 999)
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])
extends AdapterNode(imp)({s => s}, {s => s})
class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends IdentityNode(imp)
{ {
override lazy val bundleIn = bundleOut override lazy val bundleIn = bundleOut
} }
class InputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) extends IdentityNode(imp) class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends IdentityNode(imp)
{ {
override lazy val bundleOut = bundleIn override lazy val bundleOut = bundleIn
} }
class SourceNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO, num: Range.Inclusive = 1 to 1) class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])
extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, num, 0 to 0) extends MixedNode(imp, imp)(po.size to po.size, 0 to 0)
{ {
require (num.end >= 1, s"${name} is a source which does not accept outputs${lazyModule.line}") protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = {
require (po.size >= o, s"${name} has ${o} outputs out of ${po.size}; cannot assign ${po.size - o} edges to resolve :=*${lazyModule.line}")
po.size - o
}
protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = {
require (false, s"${name} cannot resolve :*=${lazyModule.line}")
0
}
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 } override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut }
} }
class SinkNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI, num: Range.Inclusive = 1 to 1) class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, num) extends MixedNode(imp, imp)(0 to 0, pi.size to pi.size)
{ {
require (num.end >= 1, s"${name} is a sink which does not accept inputs${lazyModule.line}") protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = {
require (false, s"${name} cannot resolve :=*${lazyModule.line}")
0
}
protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = {
require (pi.size >= i, s"${name} has ${i} inputs out of ${pi.size}; cannot assign ${pi.size - i} edges to resolve :*=${lazyModule.line}")
pi.size - i
}
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 } override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn }
} }
class BlindOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: Seq[PI]) class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (_, Seq()) => pi}, 0 to 0, pi.size to pi.size) extends SinkNode(imp)(pi)
{ {
override val flip = true override val flip = true
override lazy val bundleOut = bundleIn override lazy val bundleOut = bundleIn
} }
class BlindInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: Seq[PO]) class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])
extends SimpleNode(imp)({case (_, Seq()) => po}, {case (0, _) => Seq()}, po.size to po.size, 0 to 0) extends SourceNode(imp)(po)
{ {
override val flip = true override val flip = true
override lazy val bundleIn = bundleOut override lazy val bundleIn = bundleOut
} }
class InternalOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: Seq[PI]) class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (_, Seq()) => pi}, 0 to 0, pi.size to pi.size) extends SinkNode(imp)(pi)
{ {
override val wire = true override val wire = true
override lazy val bundleOut = bundleIn override lazy val bundleOut = bundleIn
} }
class InternalInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: Seq[PO]) class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])
extends SimpleNode(imp)({case (_, Seq()) => po}, {case (0, _) => Seq()}, po.size to po.size, 0 to 0) extends SourceNode(imp)(po)
{ {
override val wire = true override val wire = true
override lazy val bundleIn = bundleOut override lazy val bundleIn = bundleOut
} }
class InteriorNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])
(oFn: Seq[PO] => PO, iFn: Seq[PI] => PI, numPO: Range.Inclusive, numPI: Range.Inclusive)
extends SimpleNode(imp)({case (n,s) => Seq.fill(n)(oFn(s))}, {case (n,s) => Seq.fill(n)(iFn(s))}, numPO, numPI)
{
require (numPO.end >= 1, s"${name} is an adapter which does not accept outputs${lazyModule.line}")
require (numPI.end >= 1, s"${name} is an adapter which does not accept inputs${lazyModule.line}")
}

View File

@ -13,7 +13,7 @@ import uncore.util._
class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule {
val coreDataBytes = p(XLen)/8 val coreDataBytes = p(XLen)/8
val node = TLManagerNode(TLManagerPortParameters( val node = TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
@ -25,7 +25,7 @@ class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule {
supportsGet = TransferSizes(1, coreDataBytes), supportsGet = TransferSizes(1, coreDataBytes),
fifoId = Some(0))), // requests handled in FIFO order fifoId = Some(0))), // requests handled in FIFO order
beatBytes = coreDataBytes, beatBytes = coreDataBytes,
minLatency = 1)) minLatency = 1)))
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {

View File

@ -34,6 +34,7 @@ trait TopNetwork extends HasPeripheryParameters {
val socBus = LazyModule(new TLXbar) val socBus = LazyModule(new TLXbar)
val peripheryBus = LazyModule(new TLXbar) val peripheryBus = LazyModule(new TLXbar)
val intBus = LazyModule(new IntXbar) val intBus = LazyModule(new IntXbar)
val l2 = LazyModule(new TLBuffer)
peripheryBus.node := peripheryBus.node :=
TLBuffer()( TLBuffer()(
@ -62,13 +63,3 @@ class BaseTopBundle[+L <: BaseTop](_outer: L) extends BareTopBundle(_outer)
class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io) class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io)
with TopNetworkModule with TopNetworkModule
trait L2Crossbar extends TopNetwork {
val l2 = LazyModule(new TLXbar)
}
trait L2CrossbarBundle extends TopNetworkBundle {
}
trait L2CrossbarModule extends TopNetworkModule {
}

View File

@ -165,7 +165,7 @@ trait PeripheryMasterAXI4MMIOModule {
///// /////
// PeripherySlaveAXI4 is an example, make your own cake pattern like this one. // PeripherySlaveAXI4 is an example, make your own cake pattern like this one.
trait PeripherySlaveAXI4 extends L2Crossbar { trait PeripherySlaveAXI4 extends TopNetwork {
private val config = p(ExtIn) private val config = p(ExtIn)
val l2_axi4 = AXI4BlindInputNode(Seq(AXI4MasterPortParameters( val l2_axi4 = AXI4BlindInputNode(Seq(AXI4MasterPortParameters(
masters = Seq(AXI4MasterParameters( masters = Seq(AXI4MasterParameters(
@ -179,12 +179,12 @@ trait PeripherySlaveAXI4 extends L2Crossbar {
l2_axi4)))) l2_axi4))))
} }
trait PeripherySlaveAXI4Bundle extends L2CrossbarBundle { trait PeripherySlaveAXI4Bundle extends TopNetworkBundle {
val outer: PeripherySlaveAXI4 val outer: PeripherySlaveAXI4
val l2_axi4 = outer.l2_axi4.bundleIn val l2_axi4 = outer.l2_axi4.bundleIn
} }
trait PeripherySlaveAXI4Module extends L2CrossbarModule { trait PeripherySlaveAXI4Module extends TopNetworkModule {
val outer: PeripherySlaveAXI4 val outer: PeripherySlaveAXI4
val io: PeripherySlaveAXI4Bundle val io: PeripherySlaveAXI4Bundle
// nothing to do // nothing to do
@ -231,7 +231,7 @@ trait PeripheryMasterTLMMIOModule {
///// /////
// NOTE: this port is NOT allowed to issue Acquires // NOTE: this port is NOT allowed to issue Acquires
trait PeripherySlaveTL extends L2Crossbar { trait PeripherySlaveTL extends TopNetwork {
private val config = p(ExtIn) private val config = p(ExtIn)
val l2_tl = TLBlindInputNode(Seq(TLClientPortParameters( val l2_tl = TLBlindInputNode(Seq(TLClientPortParameters(
clients = Seq(TLClientParameters( clients = Seq(TLClientParameters(
@ -243,12 +243,12 @@ trait PeripherySlaveTL extends L2Crossbar {
l2_tl)) l2_tl))
} }
trait PeripherySlaveTLBundle extends L2CrossbarBundle { trait PeripherySlaveTLBundle extends TopNetworkBundle {
val outer: PeripherySlaveTL val outer: PeripherySlaveTL
val l2_tl = outer.l2_tl.bundleIn val l2_tl = outer.l2_tl.bundleIn
} }
trait PeripherySlaveTLModule extends L2CrossbarModule { trait PeripherySlaveTLModule extends TopNetworkModule {
val outer: PeripherySlaveTL val outer: PeripherySlaveTL
val io: PeripherySlaveTLBundle val io: PeripherySlaveTLBundle
// nothing to do // nothing to do

View File

@ -10,23 +10,23 @@ import uncore.devices._
import util._ import util._
import coreplex._ import coreplex._
trait RocketPlexMaster extends L2Crossbar { trait RocketPlexMaster extends TopNetwork {
val module: RocketPlexMasterModule val module: RocketPlexMasterModule
val mem: Seq[TLInwardNode] val mem: Seq[TLInwardNode]
val coreplex = LazyModule(new DefaultCoreplex) val coreplex = LazyModule(new DefaultCoreplex)
coreplex.l2in := l2.node coreplex.l2in :=* l2.node
socBus.node := coreplex.mmio socBus.node := coreplex.mmio
coreplex.mmioInt := intBus.intnode coreplex.mmioInt := intBus.intnode
mem.foreach { _ := coreplex.mem } mem.foreach { _ := coreplex.mem }
} }
trait RocketPlexMasterBundle extends L2CrossbarBundle { trait RocketPlexMasterBundle extends TopNetworkBundle {
val outer: RocketPlexMaster val outer: RocketPlexMaster
} }
trait RocketPlexMasterModule extends L2CrossbarModule { trait RocketPlexMasterModule extends TopNetworkModule {
val outer: RocketPlexMaster val outer: RocketPlexMaster
val io: RocketPlexMasterBundle val io: RocketPlexMasterBundle
val clock: Clock val clock: Clock

View File

@ -19,10 +19,6 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A
override def labelI(ei: AHBEdgeParameters) = (ei.slave.beatBytes * 8).toString override def labelI(ei: AHBEdgeParameters) = (ei.slave.beatBytes * 8).toString
override def labelO(eo: AHBEdgeParameters) = (eo.slave.beatBytes * 8).toString override def labelO(eo: AHBEdgeParameters) = (eo.slave.beatBytes * 8).toString
def connect(bo: => AHBBundle, bi: => AHBBundle, ei: => AHBEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => { bi <> bo })
}
override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters = override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters =
pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) })
override def mixI(pu: AHBSlavePortParameters, node: InwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBSlavePortParameters = override def mixI(pu: AHBSlavePortParameters, node: InwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBSlavePortParameters =
@ -31,16 +27,14 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A
// Nodes implemented inside modules // Nodes implemented inside modules
case class AHBIdentityNode() extends IdentityNode(AHBImp) case class AHBIdentityNode() extends IdentityNode(AHBImp)
case class AHBMasterNode(portParams: AHBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1) case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters]) extends SourceNode(AHBImp)(portParams)
extends SourceNode(AHBImp)(portParams, numPorts) case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters]) extends SinkNode(AHBImp)(portParams)
case class AHBSlaveNode(portParams: AHBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1) case class AHBNexusNode(
extends SinkNode(AHBImp)(portParams, numPorts)
case class AHBAdapterNode(
masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters, masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters, slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1, numMasterPorts: Range.Inclusive = 1 to 999,
numSlavePorts: Range.Inclusive = 1 to 1) numSlavePorts: Range.Inclusive = 1 to 999)
extends InteriorNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class AHBOutputNode() extends OutputNode(AHBImp) case class AHBOutputNode() extends OutputNode(AHBImp)

View File

@ -9,13 +9,13 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends AHBSlaveNode(AHBSlavePortParameters( extends AHBSlaveNode(Seq(AHBSlavePortParameters(
Seq(AHBSlaveParameters( Seq(AHBSlaveParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)), supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)),
supportsRead = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))), supportsRead = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))),
beatBytes = beatBytes)) beatBytes = beatBytes)))
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,14 +8,14 @@ import diplomacy._
class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = AHBSlaveNode(AHBSlavePortParameters( val node = AHBSlaveNode(Seq(AHBSlavePortParameters(
Seq(AHBSlaveParameters( Seq(AHBSlaveParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
executable = executable, executable = executable,
supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer), supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer),
supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))), supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))),
beatBytes = beatBytes)) beatBytes = beatBytes)))
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class AHBFanout()(implicit p: Parameters) extends LazyModule { class AHBFanout()(implicit p: Parameters) extends LazyModule {
val node = AHBAdapterNode( val node = AHBNexusNode(
numSlavePorts = 1 to 1, numSlavePorts = 1 to 1,
numMasterPorts = 1 to 32, numMasterPorts = 1 to 32,
masterFn = { case Seq(m) => m }, masterFn = { case Seq(m) => m },

View File

@ -19,10 +19,6 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A
override def labelI(ei: APBEdgeParameters) = (ei.slave.beatBytes * 8).toString override def labelI(ei: APBEdgeParameters) = (ei.slave.beatBytes * 8).toString
override def labelO(eo: APBEdgeParameters) = (eo.slave.beatBytes * 8).toString override def labelO(eo: APBEdgeParameters) = (eo.slave.beatBytes * 8).toString
def connect(bo: => APBBundle, bi: => APBBundle, ei: => APBEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => { bi <> bo })
}
override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters = override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters =
pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) })
override def mixI(pu: APBSlavePortParameters, node: InwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBSlavePortParameters = override def mixI(pu: APBSlavePortParameters, node: InwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBSlavePortParameters =
@ -31,16 +27,14 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A
// Nodes implemented inside modules // Nodes implemented inside modules
case class APBIdentityNode() extends IdentityNode(APBImp) case class APBIdentityNode() extends IdentityNode(APBImp)
case class APBMasterNode(portParams: APBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1) case class APBMasterNode(portParams: Seq[APBMasterPortParameters]) extends SourceNode(APBImp)(portParams)
extends SourceNode(APBImp)(portParams, numPorts) case class APBSlaveNode(portParams: Seq[APBSlavePortParameters]) extends SinkNode(APBImp)(portParams)
case class APBSlaveNode(portParams: APBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1) case class APBNexusNode(
extends SinkNode(APBImp)(portParams, numPorts)
case class APBAdapterNode(
masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters, masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters, slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1, numMasterPorts: Range.Inclusive = 1 to 1,
numSlavePorts: Range.Inclusive = 1 to 1) numSlavePorts: Range.Inclusive = 1 to 1)
extends InteriorNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class APBOutputNode() extends OutputNode(APBImp) case class APBOutputNode() extends OutputNode(APBImp)

View File

@ -9,13 +9,13 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends APBSlaveNode(APBSlavePortParameters( extends APBSlaveNode(Seq(APBSlavePortParameters(
Seq(APBSlaveParameters( Seq(APBSlaveParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
supportsWrite = true, supportsWrite = true,
supportsRead = true)), supportsRead = true)),
beatBytes = beatBytes)) beatBytes = beatBytes)))
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,14 +8,14 @@ import diplomacy._
class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = APBSlaveNode(APBSlavePortParameters( val node = APBSlaveNode(Seq(APBSlavePortParameters(
Seq(APBSlaveParameters( Seq(APBSlaveParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
executable = executable, executable = executable,
supportsRead = true, supportsRead = true,
supportsWrite = true)), supportsWrite = true)),
beatBytes = beatBytes)) beatBytes = beatBytes)))
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class APBFanout()(implicit p: Parameters) extends LazyModule { class APBFanout()(implicit p: Parameters) extends LazyModule {
val node = APBAdapterNode( val node = APBNexusNode(
numSlavePorts = 1 to 1, numSlavePorts = 1 to 1,
numMasterPorts = 1 to 32, numMasterPorts = 1 to 32,
masterFn = { case Seq(m) => m }, masterFn = { case Seq(m) => m },

View File

@ -18,8 +18,8 @@ class AXI4Buffer(aw: Int = 2, w: Int = 2, b: Int = 2, ar: Int = 2, r: Int = 2, p
require (r >= 0) require (r >= 0)
val node = AXI4AdapterNode( val node = AXI4AdapterNode(
masterFn = { case Seq(p) => p }, masterFn = { p => p },
slaveFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) }) slaveFn = { p => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {

View File

@ -23,8 +23,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true) def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true)
val node = AXI4AdapterNode( val node = AXI4AdapterNode(
masterFn = { case Seq(mp) => mp.copy(masters = mp.masters.map(m => mapMaster(m))) }, masterFn = { mp => mp.copy(masters = mp.masters.map(m => mapMaster(m))) },
slaveFn = { case Seq(sp) => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) }) slaveFn = { sp => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -32,8 +32,7 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
val out = node.bundleOut val out = node.bundleOut
} }
val edgeOut = node.edgesOut(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeIn = node.edgesIn(0)
val slave = edgeOut.slave val slave = edgeOut.slave
val slaves = slave.slaves val slaves = slave.slaves
val beatBytes = slave.beatBytes val beatBytes = slave.beatBytes
@ -136,9 +135,6 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
(out, last, beats) (out, last, beats)
} }
val in = io.in(0)
val out = io.out(0)
// The size to which we will fragment the access // The size to which we will fragment the access
val readSizes1 = slaves.map(s => s.supportsRead .max/beatBytes-1) val readSizes1 = slaves.map(s => s.supportsRead .max/beatBytes-1)
val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1) val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1)
@ -237,9 +233,9 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
when (out_b.fire()) { r_resp := Mux(b_last, UInt(0), resp) } when (out_b.fire()) { r_resp := Mux(b_last, UInt(0), resp) }
in_b.bits.resp := resp in_b.bits.resp := resp
} }
} }
/* We want to put barriers between the fragments of a fragmented transfer and all other transfers. /* We want to put barriers between the fragments of a fragmented transfer and all other transfers.
* This lets us use very little state to reassemble the fragments (else we need one FIFO per ID). * This lets us use very little state to reassemble the fragments (else we need one FIFO per ID).
* Furthermore, because all the fragments share the same AXI ID, they come back contiguously. * Furthermore, because all the fragments share the same AXI ID, they come back contiguously.
* This guarantees that no other R responses might get mixed between fragments, ensuring that the * This guarantees that no other R responses might get mixed between fragments, ensuring that the
@ -247,8 +243,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
* Of course, if you need to fragment, this means there is a potentially hefty serialization cost. * Of course, if you need to fragment, this means there is a potentially hefty serialization cost.
* However, this design allows full concurrency in the common no-fragmentation-needed scenario. * However, this design allows full concurrency in the common no-fragmentation-needed scenario.
*/ */
class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Module class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Module
{ {
val io = new QueueIO(Bool(), maxInFlight) val io = new QueueIO(Bool(), maxInFlight)
io.count := UInt(0) io.count := UInt(0)
@ -283,6 +279,7 @@ class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Mo
is(FIND) { when (io.enq.valid && io.enq.bits && !full) { state := Mux(empty, PASS, WAIT) } } is(FIND) { when (io.enq.valid && io.enq.bits && !full) { state := Mux(empty, PASS, WAIT) } }
is(WAIT) { when (last && io.deq.ready) { state := PASS } } is(WAIT) { when (last && io.deq.ready) { state := PASS } }
} }
}
} }
object AXI4Fragmenter object AXI4Fragmenter

View File

@ -19,10 +19,6 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters
override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString
override def labelO(eo: AXI4EdgeParameters) = (eo.slave.beatBytes * 8).toString override def labelO(eo: AXI4EdgeParameters) = (eo.slave.beatBytes * 8).toString
def connect(bo: => AXI4Bundle, bi: => AXI4Bundle, ei: => AXI4EdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => { bi <> bo })
}
override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters = override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters =
pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) })
override def mixI(pu: AXI4SlavePortParameters, node: InwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4SlavePortParameters = override def mixI(pu: AXI4SlavePortParameters, node: InwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4SlavePortParameters =
@ -31,16 +27,13 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters
// Nodes implemented inside modules // Nodes implemented inside modules
case class AXI4IdentityNode() extends IdentityNode(AXI4Imp) case class AXI4IdentityNode() extends IdentityNode(AXI4Imp)
case class AXI4MasterNode(portParams: AXI4MasterPortParameters, numPorts: Range.Inclusive = 1 to 1) case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters]) extends SourceNode(AXI4Imp)(portParams)
extends SourceNode(AXI4Imp)(portParams, numPorts) case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters]) extends SinkNode(AXI4Imp)(portParams)
case class AXI4SlaveNode(portParams: AXI4SlavePortParameters, numPorts: Range.Inclusive = 1 to 1)
extends SinkNode(AXI4Imp)(portParams, numPorts)
case class AXI4AdapterNode( case class AXI4AdapterNode(
masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters, masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters,
slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters, slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1, numPorts: Range.Inclusive = 0 to 999)
numSlavePorts: Range.Inclusive = 1 to 1) extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
extends InteriorNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class AXI4OutputNode() extends OutputNode(AXI4Imp) case class AXI4OutputNode() extends OutputNode(AXI4Imp)

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends AXI4SlaveNode(AXI4SlavePortParameters( extends AXI4SlaveNode(Seq(AXI4SlavePortParameters(
Seq(AXI4SlaveParameters( Seq(AXI4SlaveParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
@ -17,7 +17,7 @@ class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int
supportsRead = TransferSizes(1, beatBytes), supportsRead = TransferSizes(1, beatBytes),
interleavedId = Some(0))), interleavedId = Some(0))),
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = min(concurrency, 1))) // the Queue adds at most one cycle minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,7 +8,7 @@ import diplomacy._
class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = AXI4SlaveNode(AXI4SlavePortParameters( val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
Seq(AXI4SlaveParameters( Seq(AXI4SlaveParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
@ -17,7 +17,7 @@ class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int =
supportsWrite = TransferSizes(1, beatBytes), supportsWrite = TransferSizes(1, beatBytes),
interleavedId = Some(0))), interleavedId = Some(0))),
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = 0)) // B responds on same cycle minLatency = 0))) // B responds on same cycle
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -8,15 +8,15 @@ import config._
import diplomacy._ import diplomacy._
import uncore.tilelink2._ import uncore.tilelink2._
case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)( case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)(
dFn = { case (1, Seq(AXI4MasterPortParameters(masters))) => dFn = { case AXI4MasterPortParameters(masters) =>
Seq(TLClientPortParameters(clients = masters.map { m => TLClientPortParameters(clients = masters.map { m =>
TLClientParameters( TLClientParameters(
sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct
nodePath = m.nodePath) nodePath = m.nodePath)
})) })
}, },
uFn = { case (1, Seq(mp)) => Seq(AXI4SlavePortParameters( uFn = { mp => AXI4SlavePortParameters(
slaves = mp.managers.map { m => slaves = mp.managers.map { m =>
AXI4SlaveParameters( AXI4SlaveParameters(
address = m.address, address = m.address,
@ -27,10 +27,8 @@ case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)(
supportsRead = m.supportsGet, supportsRead = m.supportsGet,
interleavedId = Some(0))}, // TL2 never interleaves D beats interleavedId = Some(0))}, // TL2 never interleaves D beats
beatBytes = mp.beatBytes, beatBytes = mp.beatBytes,
minLatency = mp.minLatency)) minLatency = mp.minLatency)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class AXI4ToTL()(implicit p: Parameters) extends LazyModule class AXI4ToTL()(implicit p: Parameters) extends LazyModule
{ {
@ -42,10 +40,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val numIds = edgeIn.master.endId val numIds = edgeIn.master.endId
val beatBytes = edgeOut.manager.beatBytes val beatBytes = edgeOut.manager.beatBytes
val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1
@ -168,6 +163,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params) class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params)

View File

@ -62,7 +62,7 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
beatBytes = p(rocket.XLen)/8, beatBytes = p(rocket.XLen)/8,
undefZero = false) undefZero = false)
val intnode = IntAdapterNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 1024, numSourcePorts = 0 to 1024,
numSinkPorts = 0 to 1024, numSinkPorts = 0 to 1024,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) }, sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) },

View File

@ -6,6 +6,7 @@ import Chisel._
import chisel3.internal.sourceinfo.SourceInfo import chisel3.internal.sourceinfo.SourceInfo
import config._ import config._
import diplomacy._ import diplomacy._
import util.GenericParameterizedBundle
import scala.math.{min,max} import scala.math.{min,max}
// Ensures that all downstream RW managers support Atomic operationss. // Ensures that all downstream RW managers support Atomic operationss.
@ -15,8 +16,8 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
require (concurrency >= 1) require (concurrency >= 1)
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) }, clientFn = { case cp => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) },
managerFn = { case Seq(mp) => mp.copy(managers = mp.managers.map { m => managerFn = { case mp => mp.copy(managers = mp.managers.map { m =>
val ourSupport = TransferSizes(1, mp.beatBytes) val ourSupport = TransferSizes(1, mp.beatBytes)
def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport
val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport) val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport)
@ -33,10 +34,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val managers = edgeOut.manager.managers val managers = edgeOut.manager.managers
val beatBytes = edgeOut.manager.beatBytes val beatBytes = edgeOut.manager.beatBytes
@ -72,25 +70,14 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else
Mux1H(select, x.map(_.containsLg(lgSize))) Mux1H(select, x.map(_.containsLg(lgSize)))
val params = TLAtomicAutomata.CAMParams(out.a.bits.params, domainsNeedingHelp.size)
// Do we need to do anything at all? // Do we need to do anything at all?
if (camSize > 0) { if (camSize > 0) {
class CAM_S extends Bundle { val initval = Wire(new TLAtomicAutomata.CAM_S(params))
val state = UInt(width = 2)
}
class CAM_A extends Bundle {
val bits = new TLBundleA(out.a.bits.params)
val fifoId = UInt(width = log2Up(domainsNeedingHelp.size))
val lut = UInt(width = 4)
}
class CAM_D extends Bundle {
val data = UInt(width = out.a.bits.params.dataBits)
}
val initval = Wire(new CAM_S)
initval.state := FREE initval.state := FREE
val cam_s = RegInit(Vec.fill(camSize)(initval)) val cam_s = RegInit(Vec.fill(camSize)(initval))
val cam_a = Reg(Vec(camSize, new CAM_A)) val cam_a = Reg(Vec(camSize, new TLAtomicAutomata.CAM_A(params)))
val cam_d = Reg(Vec(camSize, new CAM_D)) val cam_d = Reg(Vec(camSize, new TLAtomicAutomata.CAM_D(params)))
val cam_free = cam_s.map(_.state === FREE) val cam_free = cam_s.map(_.state === FREE)
val cam_amo = cam_s.map(_.state === AMO) val cam_amo = cam_s.map(_.state === AMO)
@ -274,6 +261,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
} }
}
} }
object TLAtomicAutomata object TLAtomicAutomata
@ -284,6 +272,20 @@ object TLAtomicAutomata
atomics.node := x atomics.node := x
atomics.node atomics.node
} }
case class CAMParams(a: TLBundleParameters, domainsNeedingHelp: Int)
class CAM_S(params: CAMParams) extends GenericParameterizedBundle(params) {
val state = UInt(width = 2)
}
class CAM_A(params: CAMParams) extends GenericParameterizedBundle(params) {
val bits = new TLBundleA(params.a)
val fifoId = UInt(width = log2Up(params.domainsNeedingHelp))
val lut = UInt(width = 4)
}
class CAM_D(params: CAMParams) extends GenericParameterizedBundle(params) {
val data = UInt(width = params.a.dataBits)
}
} }
/** Synthesizeable unit tests */ /** Synthesizeable unit tests */

View File

@ -13,11 +13,11 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
require (numTrackers > 0) require (numTrackers > 0)
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => clientFn = { cp =>
cp.copy(clients = Seq(TLClientParameters( cp.copy(clients = Seq(TLClientParameters(
sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4))))) sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4)))))
}, },
managerFn = { case Seq(mp) => managerFn = { mp =>
mp.copy( mp.copy(
endSinkId = numTrackers, endSinkId = numTrackers,
managers = mp.managers.map { m => managers = mp.managers.map { m =>
@ -56,10 +56,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val clients = edgeIn.client.clients val clients = edgeIn.client.clients
val managers = edgeOut.manager.managers val managers = edgeOut.manager.managers
val lineShift = log2Ceil(lineBytes) val lineShift = log2Ceil(lineBytes)
@ -205,6 +202,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module

View File

@ -18,8 +18,8 @@ class TLBuffer(a: Int = 2, b: Int = 2, c: Int = 2, d: Int = 2, e: Int = 2, pipe:
require (e >= 0) require (e >= 0)
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) }, clientFn = { p => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) },
managerFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) }) managerFn = { p => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {

View File

@ -210,11 +210,11 @@ final class DecoupledSnoop[+T <: Data](gen: T) extends Bundle
object DecoupledSnoop object DecoupledSnoop
{ {
def apply[T <: Data](i: DecoupledIO[T]) = { def apply[T <: Data](source: DecoupledIO[T], sink: DecoupledIO[T]) = {
val out = Wire(new DecoupledSnoop(i.bits)) val out = Wire(new DecoupledSnoop(sink.bits))
out.ready := i.ready out.ready := sink.ready
out.valid := i.valid out.valid := source.valid
out.bits := i.bits out.bits := source.bits
out out
} }
} }
@ -230,13 +230,13 @@ class TLBundleSnoop(params: TLBundleParameters) extends TLBundleBase(params)
object TLBundleSnoop object TLBundleSnoop
{ {
def apply(x: TLBundle) = { def apply(source: TLBundle, sink: TLBundle) = {
val out = Wire(new TLBundleSnoop(x.params)) val out = Wire(new TLBundleSnoop(sink.params))
out.a <> DecoupledSnoop(x.a) out.a := DecoupledSnoop(source.a, sink.a)
out.b <> DecoupledSnoop(x.b) out.b := DecoupledSnoop(sink.b, source.b)
out.c <> DecoupledSnoop(x.c) out.c := DecoupledSnoop(source.c, sink.c)
out.d <> DecoupledSnoop(x.d) out.d := DecoupledSnoop(sink.d, source.d)
out.e <> DecoupledSnoop(x.e) out.e := DecoupledSnoop(source.e, sink.e)
out out
} }
} }

View File

@ -12,10 +12,10 @@ import TLMessages._
class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => clientFn = { case cp =>
cp.copy(clients = cp.clients.map { c => c.copy( cp.copy(clients = cp.clients.map { c => c.copy(
sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})}, sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})},
managerFn = { case Seq(mp) => managerFn = { case mp =>
mp.copy(managers = mp.managers.map { m => m.copy( mp.copy(managers = mp.managers.map { m => m.copy(
regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType, regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType,
supportsAcquireB = m.supportsGet, supportsAcquireB = m.supportsGet,
@ -27,18 +27,13 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
val out = node.bundleOut val out = node.bundleOut
} }
val edgeIn = node.edgesIn(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeOut = node.edgesOut(0)
require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork") require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork")
require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed") require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed")
edgeOut.manager.managers.foreach { case m => edgeOut.manager.managers.foreach { case m =>
require (!m.supportsAcquireB, "Cannot support caches beyond the Cork") require (!m.supportsAcquireB, "Cannot support caches beyond the Cork")
} }
val out = io.out(0)
val in = io.in(0)
// The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData] // The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData]
// and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck] // and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck]
// We need to encode information sufficient to reverse the transformation in output. // We need to encode information sufficient to reverse the transformation in output.
@ -115,6 +110,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
object TLCacheCork object TLCacheCork

View File

@ -11,8 +11,8 @@ import scala.math.{min,max}
class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => cp }, clientFn = { cp => cp },
managerFn = { case Seq(mp) => managerFn = { mp =>
mp.copy(managers = mp.managers.map { m => mp.copy(managers = mp.managers.map { m =>
val filtered = m.address.map(_.intersect(select)).flatten val filtered = m.address.map(_.intersect(select)).flatten
val alignment = select.alignment /* alignment 0 means 'select' selected everything */ val alignment = select.alignment /* alignment 0 means 'select' selected everything */

View File

@ -41,8 +41,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits)) sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits))
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(c) => c.copy(clients = c.clients.map(mapClient)) }, clientFn = { c => c.copy(clients = c.clients.map(mapClient)) },
managerFn = { case Seq(m) => m.copy(managers = m.managers.map(mapManager)) }) managerFn = { m => m.copy(managers = m.managers.map(mapManager)) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -50,9 +50,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
val out = node.bundleOut val out = node.bundleOut
} }
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
// All managers must share a common FIFO domain (responses might end up interleaved) // All managers must share a common FIFO domain (responses might end up interleaved)
val edgeOut = node.edgesOut(0)
val edgeIn = node.edgesIn(0)
val manager = edgeOut.manager val manager = edgeOut.manager
val managers = manager.managers val managers = manager.managers
val beatBytes = manager.beatBytes val beatBytes = manager.beatBytes
@ -129,9 +128,6 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
* put1 put1 0 ack1 0 ack1 0 0 * put1 put1 0 ack1 0 ack1 0 0
*/ */
val in = io.in(0)
val out = io.out(0)
val counterBits = log2Up(maxSize/beatBytes) val counterBits = log2Up(maxSize/beatBytes)
val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer
@ -249,6 +245,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
object TLFragmenter object TLFragmenter

View File

@ -12,8 +12,8 @@ import diplomacy._
class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(c) => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) }, clientFn = { c => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) },
managerFn = { case Seq(m) => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) }) managerFn = { m => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -21,11 +21,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
// Don't add support for clients if there is no BCE channel // Don't add support for clients if there is no BCE channel
val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
require (!supportClients || bce) require (!supportClients || bce)
@ -96,6 +92,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
} }
}
} }
object TLHintHandler object TLHintHandler

View File

@ -81,16 +81,16 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In
case class IntIdentityNode() extends IdentityNode(IntImp) case class IntIdentityNode() extends IdentityNode(IntImp)
case class IntSourceNode(num: Int) extends SourceNode(IntImp)( case class IntSourceNode(num: Int) extends SourceNode(IntImp)(
IntSourcePortParameters(Seq(IntSourceParameters(num))), (if (num == 0) 0 else 1) to 1) if (num == 0) Seq() else Seq(IntSourcePortParameters(Seq(IntSourceParameters(num)))))
case class IntSinkNode() extends SinkNode(IntImp)( case class IntSinkNode() extends SinkNode(IntImp)(
IntSinkPortParameters(Seq(IntSinkParameters()))) Seq(IntSinkPortParameters(Seq(IntSinkParameters()))))
case class IntAdapterNode( case class IntNexusNode(
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters, sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters, sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters,
numSourcePorts: Range.Inclusive = 1 to 1, numSourcePorts: Range.Inclusive = 0 to 128,
numSinkPorts: Range.Inclusive = 1 to 1) numSinkPorts: Range.Inclusive = 0 to 128)
extends InteriorNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
case class IntOutputNode() extends OutputNode(IntImp) case class IntOutputNode() extends OutputNode(IntImp)
case class IntInputNode() extends InputNode(IntImp) case class IntInputNode() extends InputNode(IntImp)
@ -103,9 +103,7 @@ case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(Seq(
class IntXbar()(implicit p: Parameters) extends LazyModule class IntXbar()(implicit p: Parameters) extends LazyModule
{ {
val intnode = IntAdapterNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 128,
numSinkPorts = 0 to 128,
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
sourceFn = { seq => sourceFn = { seq =>
IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map { IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map {

View File

@ -7,7 +7,7 @@ import chisel3.internal.sourceinfo.{SourceInfo, SourceLine}
import config._ import config._
import diplomacy._ import diplomacy._
case class TLMonitorArgs(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: SourceInfo, p: Parameters) case class TLMonitorArgs(edge: () => Seq[TLEdge], sourceInfo: SourceInfo, p: Parameters)
abstract class TLMonitorBase(args: TLMonitorArgs) extends LazyModule()(args.p) abstract class TLMonitorBase(args: TLMonitorArgs) extends LazyModule()(args.p)
{ {
@ -16,11 +16,12 @@ abstract class TLMonitorBase(args: TLMonitorArgs) extends LazyModule()(args.p)
def legalize(bundle: TLBundleSnoop, edge: TLEdge, reset: Bool): Unit def legalize(bundle: TLBundleSnoop, edge: TLEdge, reset: Bool): Unit
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val edges = args.edge()
val io = new Bundle { val io = new Bundle {
val in = args.gen().asInput val in = Vec(edges.size, new TLBundleSnoop(TLBundleParameters.union(edges.map(_.bundle)))).flip
} }
legalize(io.in, args.edge(), reset) (edges zip io.in).foreach { case (e, in) => legalize(in, e, reset) }
} }
} }

View File

@ -24,11 +24,13 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
override def labelI(ei: TLEdgeIn) = (ei.manager.beatBytes * 8).toString override def labelI(ei: TLEdgeIn) = (ei.manager.beatBytes * 8).toString
override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString
def connect(bo: => TLBundle, bi: => TLBundle, ei: => TLEdgeIn)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { override def connect(bindings: () => Seq[(TLEdgeIn, TLBundle, TLBundle)])(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
val monitor = p(TLMonitorBuilder)(TLMonitorArgs(() => new TLBundleSnoop(bo.params), () => ei, sourceInfo, p)) val monitor = p(TLMonitorBuilder)(TLMonitorArgs(() => bindings().map(_._1), sourceInfo, p))
(monitor, () => { (monitor, () => {
val eval = bindings ()
monitor.foreach { m => (eval zip m.module.io.in) foreach { case ((_,i,o), m) => m := TLBundleSnoop(o,i) } }
eval.foreach { case (_, bi, bo) =>
bi <> bo bi <> bo
monitor.foreach { _.module.io.in := TLBundleSnoop(bo) }
if (p(TLCombinationalCheck)) { if (p(TLCombinationalCheck)) {
// It is forbidden for valid to depend on ready in TL2 // It is forbidden for valid to depend on ready in TL2
// If someone did that, then this will create a detectable combinational loop // If someone did that, then this will create a detectable combinational loop
@ -63,6 +65,7 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
when (!bo.d.valid) { bo.d.bits := bits_d } when (!bo.d.valid) { bo.d.bits := bits_d }
when (!bi.e.valid) { bi.e.bits := bits_e } when (!bi.e.valid) { bi.e.bits := bits_e }
} }
}
}) })
} }
@ -86,29 +89,33 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
// Nodes implemented inside modules // Nodes implemented inside modules
case class TLIdentityNode() extends IdentityNode(TLImp) case class TLIdentityNode() extends IdentityNode(TLImp)
case class TLClientNode(portParams: TLClientPortParameters, numPorts: Range.Inclusive = 1 to 1) case class TLClientNode(portParams: Seq[TLClientPortParameters]) extends SourceNode(TLImp)(portParams)
extends SourceNode(TLImp)(portParams, numPorts) case class TLManagerNode(portParams: Seq[TLManagerPortParameters]) extends SinkNode(TLImp)(portParams)
case class TLManagerNode(portParams: TLManagerPortParameters, numPorts: Range.Inclusive = 1 to 1)
extends SinkNode(TLImp)(portParams, numPorts)
object TLClientNode object TLClientNode
{ {
def apply(params: TLClientParameters) = def apply(params: TLClientParameters) =
new TLClientNode(TLClientPortParameters(Seq(params)), 1 to 1) new TLClientNode(Seq(TLClientPortParameters(Seq(params))))
} }
object TLManagerNode object TLManagerNode
{ {
def apply(beatBytes: Int, params: TLManagerParameters) = def apply(beatBytes: Int, params: TLManagerParameters) =
new TLManagerNode(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0), 1 to 1) new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0)))
} }
case class TLAdapterNode( case class TLAdapterNode(
clientFn: TLClientPortParameters => TLClientPortParameters,
managerFn: TLManagerPortParameters => TLManagerPortParameters,
num: Range.Inclusive = 0 to 999)
extends AdapterNode(TLImp)(clientFn, managerFn, num)
case class TLNexusNode(
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters, clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters, managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
numClientPorts: Range.Inclusive = 1 to 1, numClientPorts: Range.Inclusive = 1 to 999,
numManagerPorts: Range.Inclusive = 1 to 1) numManagerPorts: Range.Inclusive = 1 to 999)
extends InteriorNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class TLOutputNode() extends OutputNode(TLImp) case class TLOutputNode() extends OutputNode(TLImp)
@ -155,10 +162,6 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor
override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString
override def labelO(eo: TLAsyncEdgeParameters) = eo.manager.depth.toString override def labelO(eo: TLAsyncEdgeParameters) = eo.manager.depth.toString
def connect(bo: => TLAsyncBundle, bi: => TLAsyncBundle, ei: => TLAsyncEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => { bi <> bo })
}
override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters = override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters =
pd.copy(base = pd.base.copy(clients = pd.base.clients.map { c => c.copy (nodePath = node +: c.nodePath) })) pd.copy(base = pd.base.copy(clients = pd.base.clients.map { c => c.copy (nodePath = node +: c.nodePath) }))
override def mixI(pu: TLAsyncManagerPortParameters, node: InwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncManagerPortParameters = override def mixI(pu: TLAsyncManagerPortParameters, node: InwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncManagerPortParameters =
@ -169,17 +172,15 @@ case class TLAsyncIdentityNode() extends IdentityNode(TLAsyncImp)
case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp) case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp)
case class TLAsyncInputNode() extends InputNode(TLAsyncImp) case class TLAsyncInputNode() extends InputNode(TLAsyncImp)
case class TLAsyncSourceNode(sync: Int) extends MixedNode(TLImp, TLAsyncImp)( case class TLAsyncSourceNode(sync: Int)
dFn = { case (1, Seq(p)) => Seq(TLAsyncClientPortParameters(p)) }, extends MixedAdapterNode(TLImp, TLAsyncImp)(
uFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, // discard cycles in other clock domain dFn = { p => TLAsyncClientPortParameters(p) },
numPO = 1 to 1, uFn = { p => p.base.copy(minLatency = sync+1) }) // discard cycles in other clock domain
numPI = 1 to 1)
case class TLAsyncSinkNode(depth: Int, sync: Int) extends MixedNode(TLAsyncImp, TLImp)( case class TLAsyncSinkNode(depth: Int, sync: Int)
dFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, extends MixedAdapterNode(TLAsyncImp, TLImp)(
uFn = { case (1, Seq(p)) => Seq(TLAsyncManagerPortParameters(depth, p)) }, dFn = { p => p.base.copy(minLatency = sync+1) },
numPO = 1 to 1, uFn = { p => TLAsyncManagerPortParameters(depth, p) })
numPI = 1 to 1)
object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle] object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle]
{ {
@ -191,10 +192,6 @@ object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParame
def colour = "#00ff00" // green def colour = "#00ff00" // green
def connect(bo: => TLRationalBundle, bi: => TLRationalBundle, ei: => TLEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => { bi <> bo })
}
override def mixO(pd: TLClientPortParameters, node: OutwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLClientPortParameters = override def mixO(pd: TLClientPortParameters, node: OutwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLClientPortParameters =
pd.copy(clients = pd.clients.map { c => c.copy (nodePath = node +: c.nodePath) }) pd.copy(clients = pd.clients.map { c => c.copy (nodePath = node +: c.nodePath) })
override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLManagerPortParameters = override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLManagerPortParameters =
@ -205,14 +202,12 @@ case class TLRationalIdentityNode() extends IdentityNode(TLRationalImp)
case class TLRationalOutputNode() extends OutputNode(TLRationalImp) case class TLRationalOutputNode() extends OutputNode(TLRationalImp)
case class TLRationalInputNode() extends InputNode(TLRationalImp) case class TLRationalInputNode() extends InputNode(TLRationalImp)
case class TLRationalSourceNode() extends MixedNode(TLImp, TLRationalImp)( case class TLRationalSourceNode()
dFn = { case (_, s) => s }, extends MixedAdapterNode(TLImp, TLRationalImp)(
uFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, // discard cycles from other clock domain dFn = { p => p },
numPO = 0 to 999, uFn = { p => p.copy(minLatency = 1) }) // discard cycles from other clock domain
numPI = 0 to 999)
case class TLRationalSinkNode() extends MixedNode(TLRationalImp, TLImp)( case class TLRationalSinkNode()
dFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, extends MixedAdapterNode(TLRationalImp, TLImp)(
uFn = { case (_, s) => s }, dFn = { p => p.copy(minLatency = 1) },
numPO = 0 to 999, uFn = { p => p })
numPI = 0 to 999)

View File

@ -5,6 +5,7 @@ package uncore.tilelink2
import Chisel._ import Chisel._
import config._ import config._
import diplomacy._ import diplomacy._
import util.GenericParameterizedBundle
// We detect concurrent puts that put memory into an undefined state. // We detect concurrent puts that put memory into an undefined state.
// put0, put0Ack, put1, put1Ack => ok: defined // put0, put0Ack, put1, put1Ack => ok: defined
@ -31,13 +32,8 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
val out = node.bundleOut val out = node.bundleOut
} }
// !!! support multiple clients via clock division ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
require (io.out.size == 1) val edge = edgeIn
val in = io.in(0)
val out = io.out(0)
val edge = node.edgesIn(0)
val endAddress = edge.manager.maxAddress + 1 val endAddress = edge.manager.maxAddress + 1
val endSourceId = edge.client.endSourceId val endSourceId = edge.client.endSourceId
val maxTransfer = edge.manager.maxTransfer val maxTransfer = edge.manager.maxTransfer
@ -71,18 +67,10 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
in.c.ready := Bool(true) in.c.ready := Bool(true)
in.e.ready := Bool(true) in.e.ready := Bool(true)
class ByteMonitor extends Bundle { val params = TLRAMModel.MonitorParameters(addressBits, sizeBits)
val valid = Bool()
val value = UInt(width = 8)
}
class FlightMonitor extends Bundle {
val base = UInt(width = addressBits)
val size = UInt(width = sizeBits)
val opcode = UInt(width = 3)
}
// Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed) // Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed)
val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new ByteMonitor) } val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new TLRAMModel.ByteMonitor(params)) }
val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) }
val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) }
val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) } val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) }
@ -95,11 +83,11 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
val dec_trees_wen = Wire(init = Fill(decTrees, wipe)) val dec_trees_wen = Wire(init = Fill(decTrees, wipe))
// This must be registers b/c we build a CAM from it // This must be registers b/c we build a CAM from it
val flight = Reg(Vec(endSourceId, new FlightMonitor)) val flight = Reg(Vec(endSourceId, new TLRAMModel.FlightMonitor(params)))
val valid = Reg(Vec(endSourceId, Bool())) val valid = Reg(Vec(endSourceId, Bool()))
// We want to cross flight data from A to D in the same cycle (for combinational TL2 devices) // We want to cross flight data from A to D in the same cycle (for combinational TL2 devices)
val a_flight = Wire(new FlightMonitor) val a_flight = Wire(new TLRAMModel.FlightMonitor(params))
a_flight.base := edge.address(in.a.bits) a_flight.base := edge.address(in.a.bits)
a_flight.size := edge.size(in.a.bits) a_flight.size := edge.size(in.a.bits)
a_flight.opcode := in.a.bits.opcode a_flight.opcode := in.a.bits.opcode
@ -169,7 +157,7 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
val a_waddr = Mux(wipe, wipeIndex, a_addr_hi) val a_waddr = Mux(wipe, wipeIndex, a_addr_hi)
for (i <- 0 until beatBytes) { for (i <- 0 until beatBytes) {
val data = Wire(new ByteMonitor) val data = Wire(new TLRAMModel.ByteMonitor(params))
val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt
val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData
data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo) data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo)
@ -295,4 +283,20 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
} }
} }
} }
}
}
object TLRAMModel
{
case class MonitorParameters(addressBits: Int, sizeBits: Int)
class ByteMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) {
val valid = Bool()
val value = UInt(width = 8)
}
class FlightMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) {
val base = UInt(width = params.addressBits)
val size = UInt(width = params.sizeBits)
val opcode = UInt(width = 3)
}
} }

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends TLManagerNode(TLManagerPortParameters( extends TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
@ -18,7 +18,7 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int =
supportsPutFull = TransferSizes(1, beatBytes), supportsPutFull = TransferSizes(1, beatBytes),
fifoId = Some(0))), // requests are handled in order fifoId = Some(0))), // requests are handled in order
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = min(concurrency, 1))) // the Queue adds at most one cycle minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,7 +8,7 @@ import diplomacy._
class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = TLManagerNode(TLManagerPortParameters( val node = TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
@ -18,7 +18,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)
supportsPutFull = TransferSizes(1, beatBytes), supportsPutFull = TransferSizes(1, beatBytes),
fifoId = Some(0))), // requests are handled in order fifoId = Some(0))), // requests are handled in order
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = 1)) // no bypass needed for this device minLatency = 1))) // no bypass needed for this device
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -15,8 +15,8 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight)) private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight))
val node = TLAdapterNode( val node = TLAdapterNode(
// We erase all client information since we crush the source Ids // We erase all client information since we crush the source Ids
clientFn = { case _ => TLClientPortParameters(clients = Seq(client)) }, clientFn = { _ => TLClientPortParameters(clients = Seq(client)) },
managerFn = { case Seq(mp) => mp }) managerFn = { mp => mp })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -24,11 +24,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
val out = node.bundleOut val out = node.bundleOut
} }
val edgeIn = node.edgesIn(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeOut = node.edgesOut(0)
val in = io.in(0)
val out = io.out(0)
// Acquires cannot pass this adapter; it makes Probes impossible // Acquires cannot pass this adapter; it makes Probes impossible
require (!edgeIn.client.anySupportProbe || require (!edgeIn.client.anySupportProbe ||
!edgeOut.manager.anySupportAcquireB) !edgeOut.manager.anySupportAcquireB)
@ -74,6 +70,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
allocated := (allocated | alloc_id) & ~free_id allocated := (allocated | alloc_id) & ~free_id
} }
} }
}
} }
object TLSourceShrinker object TLSourceShrinker

View File

@ -10,12 +10,12 @@ import uncore.ahb._
import scala.math.{min, max} import scala.math.{min, max}
import AHBParameters._ import AHBParameters._
case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)( case class TLToAHBNode() extends MixedAdapterNode(TLImp, AHBImp)(
dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) => dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) =>
val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) } val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) }
Seq(AHBMasterPortParameters(masters)) AHBMasterPortParameters(masters)
}, },
uFn = { case (1, Seq(AHBSlavePortParameters(slaves, beatBytes))) => uFn = { case AHBSlavePortParameters(slaves, beatBytes) =>
val managers = slaves.map { case s => val managers = slaves.map { case s =>
TLManagerParameters( TLManagerParameters(
address = s.address, address = s.address,
@ -26,10 +26,8 @@ case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)(
supportsPutFull = s.supportsWrite, // but not PutPartial supportsPutFull = s.supportsWrite, // but not PutPartial
fifoId = Some(0)) // a common FIFO domain fifoId = Some(0)) // a common FIFO domain
} }
Seq(TLManagerPortParameters(managers, beatBytes, 1, 1)) TLManagerPortParameters(managers, beatBytes, 1, 1)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
@ -41,10 +39,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val beatBytes = edgeOut.slave.beatBytes val beatBytes = edgeOut.slave.beatBytes
val maxTransfer = edgeOut.slave.maxTransfer val maxTransfer = edgeOut.slave.maxTransfer
val lgMax = log2Ceil(maxTransfer) val lgMax = log2Ceil(maxTransfer)
@ -127,6 +122,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
out.hprot := PROT_DEFAULT out.hprot := PROT_DEFAULT
out.hwdata := RegEnable(a.bits.data, a.fire()) out.hwdata := RegEnable(a.bits.data, a.fire())
} }
}
} }
object TLToAHB object TLToAHB

View File

@ -10,12 +10,12 @@ import uncore.apb._
import scala.math.{min, max} import scala.math.{min, max}
import APBParameters._ import APBParameters._
case class TLToAPBNode() extends MixedNode(TLImp, APBImp)( case class TLToAPBNode() extends MixedAdapterNode(TLImp, APBImp)(
dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) => dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) =>
val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) } val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) }
Seq(APBMasterPortParameters(masters)) APBMasterPortParameters(masters)
}, },
uFn = { case (1, Seq(APBSlavePortParameters(slaves, beatBytes))) => uFn = { case APBSlavePortParameters(slaves, beatBytes) =>
val managers = slaves.map { case s => val managers = slaves.map { case s =>
TLManagerParameters( TLManagerParameters(
address = s.address, address = s.address,
@ -27,10 +27,8 @@ case class TLToAPBNode() extends MixedNode(TLImp, APBImp)(
supportsPutFull = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none, supportsPutFull = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none,
fifoId = Some(0)) // a common FIFO domain fifoId = Some(0)) // a common FIFO domain
} }
Seq(TLManagerPortParameters(managers, beatBytes, 1, 0)) TLManagerPortParameters(managers, beatBytes, 1, 0)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
@ -42,10 +40,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val beatBytes = edgeOut.slave.beatBytes val beatBytes = edgeOut.slave.beatBytes
val lgBytes = log2Ceil(beatBytes) val lgBytes = log2Ceil(beatBytes)
@ -88,6 +83,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
d.bits := edgeIn.AccessAck(a.bits, UInt(0), out.prdata, out.pslverr) d.bits := edgeIn.AccessAck(a.bits, UInt(0), out.prdata, out.pslverr)
d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData) d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData)
} }
}
} }
object TLToAPB object TLToAPB

View File

@ -10,16 +10,16 @@ import util.PositionalMultiQueue
import uncore.axi4._ import uncore.axi4._
import scala.math.{min, max} import scala.math.{min, max}
case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)( case class TLToAXI4Node(idBits: Int) extends MixedAdapterNode(TLImp, AXI4Imp)(
dFn = { case (1, _) => dFn = { _ =>
// We must erase all client information, because we crush their source Ids // We must erase all client information, because we crush their source Ids
val masters = Seq( val masters = Seq(
AXI4MasterParameters( AXI4MasterParameters(
id = IdRange(0, 1 << idBits), id = IdRange(0, 1 << idBits),
aligned = true)) aligned = true))
Seq(AXI4MasterPortParameters(masters)) AXI4MasterPortParameters(masters)
}, },
uFn = { case (1, Seq(p)) => Seq(TLManagerPortParameters( uFn = { p => TLManagerPortParameters(
managers = p.slaves.map { case s => managers = p.slaves.map { case s =>
TLManagerParameters( TLManagerParameters(
address = s.address, address = s.address,
@ -31,10 +31,8 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)(
supportsPutPartial = s.supportsWrite)}, supportsPutPartial = s.supportsWrite)},
// AXI4 is NEVER fifo in TL sense (R+W are independent) // AXI4 is NEVER fifo in TL sense (R+W are independent)
beatBytes = p.beatBytes, beatBytes = p.beatBytes,
minLatency = p.minLatency)) minLatency = p.minLatency)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
@ -46,11 +44,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val slaves = edgeOut.slave.slaves val slaves = edgeOut.slave.slaves
// All pairs of slaves must promise that they will never interleave data // All pairs of slaves must promise that they will never interleave data
@ -226,6 +220,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
in.c.ready := Bool(true) in.c.ready := Bool(true)
in.e.ready := Bool(true) in.e.ready := Bool(true)
} }
}
} }
object TLToAXI4 object TLToAXI4

View File

@ -12,8 +12,8 @@ import scala.math.{min,max}
class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(c) => c }, clientFn = { case c => c },
managerFn = { case Seq(m) => m.copy(beatBytes = innerBeatBytes) }) managerFn = { case m => m.copy(beatBytes = innerBeatBytes) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -139,11 +139,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
} }
} }
val edgeOut = node.edgesOut(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeIn = node.edgesIn(0)
val in = io.in(0)
val out = io.out(0)
splice(edgeIn, in.a, edgeOut, out.a) splice(edgeIn, in.a, edgeOut, out.a)
splice(edgeOut, out.d, edgeIn, in.d) splice(edgeOut, out.d, edgeIn, in.d)
@ -162,6 +158,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
} }
}
} }
object TLWidthWidget object TLWidthWidget

View File

@ -34,7 +34,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
} }
} }
val node = TLAdapterNode( val node = TLNexusNode(
numClientPorts = 1 to 32, numClientPorts = 1 to 32,
numManagerPorts = 1 to 32, numManagerPorts = 1 to 32,
clientFn = { seq => clientFn = { seq =>