tilelink2: make sink ids optional (#607)
* tilelink2: make sink ids optional * CacheCork: add a special-case for 1 sink id
This commit is contained in:
parent
19eb9b6906
commit
bd08f10816
@ -16,10 +16,12 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
|||||||
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 mp =>
|
managerFn = { case mp =>
|
||||||
mp.copy(managers = mp.managers.map { m => m.copy(
|
mp.copy(
|
||||||
regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType,
|
endSinkId = 1,
|
||||||
supportsAcquireB = m.supportsGet,
|
managers = mp.managers.map { m => m.copy(
|
||||||
supportsAcquireT = m.supportsPutFull)})})
|
regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType,
|
||||||
|
supportsAcquireB = m.supportsGet,
|
||||||
|
supportsAcquireT = m.supportsPutFull)})})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
|
@ -232,7 +232,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
|||||||
|
|
||||||
val source_ok = edge.client.contains(bundle.source)
|
val source_ok = edge.client.contains(bundle.source)
|
||||||
val is_aligned = edge.isAligned(bundle.addr_lo, bundle.size)
|
val is_aligned = edge.isAligned(bundle.addr_lo, bundle.size)
|
||||||
val sink_ok = bundle.sink < UInt(edge.manager.endSinkId)
|
val sink_ok = Bool(edge.manager.endSinkId == 0) || bundle.sink < UInt(edge.manager.endSinkId)
|
||||||
|
|
||||||
when (bundle.opcode === TLMessages.ReleaseAck) {
|
when (bundle.opcode === TLMessages.ReleaseAck) {
|
||||||
assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra)
|
assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra)
|
||||||
@ -286,7 +286,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
def legalizeFormatE(bundle: TLBundleE, edge: TLEdge)(implicit sourceInfo: SourceInfo) {
|
def legalizeFormatE(bundle: TLBundleE, edge: TLEdge)(implicit sourceInfo: SourceInfo) {
|
||||||
val sink_ok = bundle.sink < UInt(edge.manager.endSinkId)
|
val sink_ok = Bool(edge.manager.endSinkId == 0) || bundle.sink < UInt(edge.manager.endSinkId)
|
||||||
assert (sink_ok, "'E' channels carries invalid sink ID" + extra)
|
assert (sink_ok, "'E' channels carries invalid sink ID" + extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
|||||||
legalizeADSource(bundle, edge)
|
legalizeADSource(bundle, edge)
|
||||||
if (edge.client.anySupportProbe && edge.manager.anySupportAcquireB) {
|
if (edge.client.anySupportProbe && edge.manager.anySupportAcquireB) {
|
||||||
// legalizeBCSourceAddress(bundle, edge) // too much state needed to synthesize...
|
// legalizeBCSourceAddress(bundle, edge) // too much state needed to synthesize...
|
||||||
legalizeDESink(bundle, edge)
|
if (edge.manager.endSinkId > 1) legalizeDESink(bundle, edge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,12 +69,12 @@ case class TLManagerParameters(
|
|||||||
case class TLManagerPortParameters(
|
case class TLManagerPortParameters(
|
||||||
managers: Seq[TLManagerParameters],
|
managers: Seq[TLManagerParameters],
|
||||||
beatBytes: Int,
|
beatBytes: Int,
|
||||||
endSinkId: Int = 1,
|
endSinkId: Int = 0, // 0 = no sink ids, 1 = a reusable sink id, >1 = unique sink ids
|
||||||
minLatency: Int = 0)
|
minLatency: Int = 0)
|
||||||
{
|
{
|
||||||
require (!managers.isEmpty)
|
require (!managers.isEmpty)
|
||||||
require (isPow2(beatBytes))
|
require (isPow2(beatBytes))
|
||||||
require (endSinkId > 0)
|
require (endSinkId >= 0)
|
||||||
require (minLatency >= 0)
|
require (minLatency >= 0)
|
||||||
|
|
||||||
def requireFifo() = managers.foreach { m =>require (m.fifoId == Some(0)) }
|
def requireFifo() = managers.foreach { m =>require (m.fifoId == Some(0)) }
|
||||||
|
@ -8,14 +8,16 @@ import diplomacy._
|
|||||||
|
|
||||||
class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p: Parameters) extends LazyModule
|
class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
def mapInputIds (ports: Seq[TLClientPortParameters ]) = assignRanges(ports.map(_.endSourceId))
|
def mapInputIds (ports: Seq[TLClientPortParameters ]) = assignRanges(ports.map(_.endSourceId)).map(_.get)
|
||||||
def mapOutputIds(ports: Seq[TLManagerPortParameters]) = assignRanges(ports.map(_.endSinkId))
|
def mapOutputIds(ports: Seq[TLManagerPortParameters]) = assignRanges(ports.map(_.endSinkId))
|
||||||
|
|
||||||
def assignRanges(sizes: Seq[Int]) = {
|
def assignRanges(sizes: Seq[Int]) = {
|
||||||
val pow2Sizes = sizes.map(1 << log2Ceil(_))
|
val pow2Sizes = sizes.map { z => if (z == 0) 0 else 1 << log2Ceil(z) }
|
||||||
val tuples = pow2Sizes.zipWithIndex.sortBy(_._1) // record old index, then sort by increasing size
|
val tuples = pow2Sizes.zipWithIndex.sortBy(_._1) // record old index, then sort by increasing size
|
||||||
val starts = tuples.scanRight(0)(_._1 + _).tail // suffix-sum of the sizes = the start positions
|
val starts = tuples.scanRight(0)(_._1 + _).tail // suffix-sum of the sizes = the start positions
|
||||||
val ranges = (tuples zip starts) map { case ((sz, i), st) => (IdRange(st, st+sz), i) }
|
val ranges = (tuples zip starts) map { case ((sz, i), st) =>
|
||||||
|
(if (sz == 0) None else Some(IdRange(st, st+sz)), i)
|
||||||
|
}
|
||||||
ranges.sortBy(_._2).map(_._1) // Restore orignal order
|
ranges.sortBy(_._2).map(_._1) // Restore orignal order
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
|
|||||||
val outputIdRanges = mapOutputIds(seq)
|
val outputIdRanges = mapOutputIds(seq)
|
||||||
seq(0).copy(
|
seq(0).copy(
|
||||||
minLatency = seq.map(_.minLatency).min,
|
minLatency = seq.map(_.minLatency).min,
|
||||||
endSinkId = outputIdRanges.map(_.end).max,
|
endSinkId = outputIdRanges.map(_.map(_.end).getOrElse(0)).max,
|
||||||
managers = ManagerUnification(seq.flatMap { port =>
|
managers = ManagerUnification(seq.flatMap { port =>
|
||||||
// println(s"${port.managers.map(_.name)} ${port.beatBytes} vs ${seq(0).managers.map(_.name)} ${seq(0).beatBytes}")
|
// println(s"${port.managers.map(_.name)} ${port.beatBytes} vs ${seq(0).managers.map(_.name)} ${seq(0).beatBytes}")
|
||||||
require (port.beatBytes == seq(0).beatBytes)
|
require (port.beatBytes == seq(0).beatBytes)
|
||||||
@ -132,13 +134,13 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
|
|||||||
|
|
||||||
io.out(i).a <> out(i).a
|
io.out(i).a <> out(i).a
|
||||||
out(i).d <> io.out(i).d
|
out(i).d <> io.out(i).d
|
||||||
out(i).d.bits.sink := io.out(i).d.bits.sink | UInt(r.start)
|
out(i).d.bits.sink := io.out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0))
|
||||||
|
|
||||||
if (node.edgesOut(i).manager.anySupportAcquireB && node.edgesIn.exists(_.client.anySupportProbe)) {
|
if (node.edgesOut(i).manager.anySupportAcquireB && node.edgesIn.exists(_.client.anySupportProbe)) {
|
||||||
io.out(i).c <> out(i).c
|
io.out(i).c <> out(i).c
|
||||||
io.out(i).e <> out(i).e
|
io.out(i).e <> out(i).e
|
||||||
out(i).b <> io.out(i).b
|
out(i).b <> io.out(i).b
|
||||||
io.out(i).e.bits.sink := trim(out(i).e.bits.sink, r.size)
|
io.out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0))
|
||||||
} else {
|
} else {
|
||||||
out(i).c.ready := Bool(false)
|
out(i).c.ready := Bool(false)
|
||||||
out(i).e.ready := Bool(false)
|
out(i).e.ready := Bool(false)
|
||||||
@ -156,7 +158,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
|
|||||||
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) })
|
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) })
|
||||||
val requestBOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.source) }) })
|
val requestBOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.source) }) })
|
||||||
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.d.bits.source) }) })
|
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.d.bits.source) }) })
|
||||||
val requestEIO = Vec(in.map { i => Vec(outputIdRanges.map { o => o.contains(i.e.bits.sink) }) })
|
val requestEIO = Vec(in.map { i => Vec(outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) }) })
|
||||||
|
|
||||||
val beatsAI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
val beatsAI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
||||||
val beatsBO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
val beatsBO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
||||||
|
Loading…
Reference in New Issue
Block a user