tilelink: Filter now support arbitrary filter functions
This commit is contained in:
parent
7adfd5c431
commit
13d3ffbcaa
@ -68,7 +68,7 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu
|
||||
for (bank <- 0 until nBanksPerChannel) {
|
||||
val offset = (bank * nMemoryChannels) + channel
|
||||
in := sbus.toMemoryBus
|
||||
mbus.fromCoherenceManager := TLFilter(AddressSet(offset * blockBytes, mask))(out)
|
||||
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * blockBytes, mask)))(out)
|
||||
}
|
||||
mbus
|
||||
}
|
||||
|
@ -8,31 +8,45 @@ import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
|
||||
class TLFilter(
|
||||
Mfilter: TLManagerParameters => Option[TLManagerParameters] = TLFilter.Midentity,
|
||||
Cfilter: TLClientParameters => Option[TLClientParameters] = TLFilter.Cidentity
|
||||
)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { cp => cp },
|
||||
managerFn = { mp =>
|
||||
mp.copy(managers = mp.managers.map { m =>
|
||||
val filtered = m.address.map(_.intersect(select)).flatten
|
||||
val alignment = select.alignment /* alignment 0 means 'select' selected everything */
|
||||
val maxTransfer = 1 << 30
|
||||
val capTransfer = if (alignment == 0 || alignment > maxTransfer) maxTransfer else alignment.toInt
|
||||
val cap = TransferSizes(1, capTransfer)
|
||||
if (filtered.isEmpty) { None } else {
|
||||
Some(m.copy(
|
||||
address = filtered,
|
||||
supportsAcquireT = m.supportsAcquireT .intersect(cap),
|
||||
supportsAcquireB = m.supportsAcquireB .intersect(cap),
|
||||
supportsArithmetic = m.supportsArithmetic.intersect(cap),
|
||||
supportsLogical = m.supportsLogical .intersect(cap),
|
||||
supportsGet = m.supportsGet .intersect(cap),
|
||||
supportsPutFull = m.supportsPutFull .intersect(cap),
|
||||
supportsPutPartial = m.supportsPutPartial.intersect(cap),
|
||||
supportsHint = m.supportsHint .intersect(cap)))
|
||||
}
|
||||
}.flatten)
|
||||
})
|
||||
clientFn = { cp => cp.copy(clients = cp.clients.flatMap { c =>
|
||||
val out = Cfilter(c)
|
||||
out.map { o => // Confirm the filter only REMOVES capability
|
||||
require (c.sourceId.contains(o.sourceId))
|
||||
require (c.supportsProbe.contains(o.supportsProbe))
|
||||
require (c.supportsArithmetic.contains(o.supportsArithmetic))
|
||||
require (c.supportsLogical.contains(o.supportsLogical))
|
||||
require (c.supportsGet.contains(o.supportsGet))
|
||||
require (c.supportsPutFull.contains(o.supportsPutFull))
|
||||
require (c.supportsPutPartial.contains(o.supportsPutPartial))
|
||||
require (c.supportsHint.contains(o.supportsHint))
|
||||
require (!c.requestFifo || o.requestFifo)
|
||||
}
|
||||
out
|
||||
})},
|
||||
managerFn = { mp => mp.copy(managers = mp.managers.flatMap { m =>
|
||||
val out = Mfilter(m)
|
||||
out.map { o => // Confirm the filter only REMOVES capability
|
||||
o.address.foreach { a => require (m.address.map(_.contains(a)).reduce(_||_)) }
|
||||
require (o.regionType <= m.regionType)
|
||||
// we allow executable to be changed both ways
|
||||
require (m.supportsAcquireT.contains(o.supportsAcquireT))
|
||||
require (m.supportsAcquireB.contains(o.supportsAcquireB))
|
||||
require (m.supportsArithmetic.contains(o.supportsArithmetic))
|
||||
require (m.supportsLogical.contains(o.supportsLogical))
|
||||
require (m.supportsGet.contains(o.supportsGet))
|
||||
require (m.supportsPutFull.contains(o.supportsPutFull))
|
||||
require (m.supportsPutPartial.contains(o.supportsPutPartial))
|
||||
require (m.supportsHint.contains(o.supportsHint))
|
||||
require (m.fifoId == o.fifoId) // could relax this, but hard to validate
|
||||
}
|
||||
out
|
||||
})})
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
@ -45,9 +59,40 @@ class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
|
||||
|
||||
object TLFilter
|
||||
{
|
||||
def Midentity: TLManagerParameters => Option[TLManagerParameters] = { m => Some(m) }
|
||||
def Cidentity: TLClientParameters => Option[TLClientParameters] = { c => Some(c) }
|
||||
def Mmask(select: AddressSet): TLManagerParameters => Option[TLManagerParameters] = { m =>
|
||||
val filtered = m.address.map(_.intersect(select)).flatten
|
||||
val alignment = select.alignment /* alignment 0 means 'select' selected everything */
|
||||
val maxTransfer = 1 << 30
|
||||
val capTransfer = if (alignment == 0 || alignment > maxTransfer) maxTransfer else alignment.toInt
|
||||
val cap = TransferSizes(1, capTransfer)
|
||||
if (filtered.isEmpty) { None } else {
|
||||
Some(m.copy(
|
||||
address = filtered,
|
||||
supportsAcquireT = m.supportsAcquireT .intersect(cap),
|
||||
supportsAcquireB = m.supportsAcquireB .intersect(cap),
|
||||
supportsArithmetic = m.supportsArithmetic.intersect(cap),
|
||||
supportsLogical = m.supportsLogical .intersect(cap),
|
||||
supportsGet = m.supportsGet .intersect(cap),
|
||||
supportsPutFull = m.supportsPutFull .intersect(cap),
|
||||
supportsPutPartial = m.supportsPutPartial.intersect(cap),
|
||||
supportsHint = m.supportsHint .intersect(cap)))
|
||||
}
|
||||
}
|
||||
def Mnocache: TLManagerParameters => Option[TLManagerParameters] = { m =>
|
||||
if (m.supportsAcquireB) None else Some(m)
|
||||
}
|
||||
def Cnocache: TLClientParameters => Option[TLClientParameters] = { c =>
|
||||
if (c.supportsProbe) None else Some(c)
|
||||
}
|
||||
|
||||
// applied to the TL source node; y.node := TLBuffer(x.node)
|
||||
def apply(select: AddressSet)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||
val filter = LazyModule(new TLFilter(select))
|
||||
def apply(
|
||||
Mfilter: TLManagerParameters => Option[TLManagerParameters] = TLFilter.Midentity,
|
||||
Cfilter: TLClientParameters => Option[TLClientParameters] = TLFilter.Cidentity
|
||||
)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||
val filter = LazyModule(new TLFilter(Mfilter, Cfilter))
|
||||
filter.node := x
|
||||
filter.node
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user