1
0

tilelink: Filter now support arbitrary filter functions

This commit is contained in:
Wesley W. Terpstra 2017-07-31 16:00:21 -07:00
parent 7adfd5c431
commit 13d3ffbcaa
2 changed files with 71 additions and 26 deletions

View File

@ -68,7 +68,7 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu
for (bank <- 0 until nBanksPerChannel) { for (bank <- 0 until nBanksPerChannel) {
val offset = (bank * nMemoryChannels) + channel val offset = (bank * nMemoryChannels) + channel
in := sbus.toMemoryBus in := sbus.toMemoryBus
mbus.fromCoherenceManager := TLFilter(AddressSet(offset * blockBytes, mask))(out) mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * blockBytes, mask)))(out)
} }
mbus mbus
} }

View File

@ -8,12 +8,60 @@ import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import scala.math.{min,max} 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( val node = TLAdapterNode(
clientFn = { cp => cp }, clientFn = { cp => cp.copy(clients = cp.clients.flatMap { c =>
managerFn = { mp => val out = Cfilter(c)
mp.copy(managers = mp.managers.map { m => 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 {
val in = node.bundleIn
val out = node.bundleOut
}
io.out <> io.in
}
}
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 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 */
val maxTransfer = 1 << 30 val maxTransfer = 1 << 30
@ -31,23 +79,20 @@ class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
supportsPutPartial = m.supportsPutPartial.intersect(cap), supportsPutPartial = m.supportsPutPartial.intersect(cap),
supportsHint = m.supportsHint .intersect(cap))) supportsHint = m.supportsHint .intersect(cap)))
} }
}.flatten)
})
lazy val module = new LazyModuleImp(this) {
val io = new Bundle {
val in = node.bundleIn
val out = node.bundleOut
} }
io.out <> io.in 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)
} }
object TLFilter
{
// applied to the TL source node; y.node := TLBuffer(x.node) // applied to the TL source node; y.node := TLBuffer(x.node)
def apply(select: AddressSet)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = { def apply(
val filter = LazyModule(new TLFilter(select)) 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 := x
filter.node filter.node
} }