2016-08-31 00:52:04 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
|
|
|
package uncore.tilelink2
|
|
|
|
|
|
|
|
import Chisel._
|
2016-09-05 02:03:10 +02:00
|
|
|
import chisel3.internal.sourceinfo.SourceInfo
|
2016-08-31 00:52:04 +02:00
|
|
|
|
|
|
|
// Acks Hints for managers that don't support them or Acks all Hints if !passthrough
|
2016-08-31 19:25:46 +02:00
|
|
|
class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true) extends LazyModule
|
2016-08-31 00:52:04 +02:00
|
|
|
{
|
|
|
|
val node = TLAdapterNode(
|
2016-08-31 01:16:45 +02:00
|
|
|
clientFn = { case Seq(c) => if (supportClients) c.copy(clients = c.clients .map(_.copy(supportsHint = true))) else c },
|
|
|
|
managerFn = { case Seq(m) => if (supportManagers) m.copy(managers = m.managers.map(_.copy(supportsHint = true))) else m })
|
2016-08-31 00:52:04 +02:00
|
|
|
|
2016-09-02 20:13:43 +02:00
|
|
|
lazy val module = new LazyModuleImp(this) {
|
2016-08-31 00:52:04 +02:00
|
|
|
val io = new Bundle {
|
|
|
|
val in = node.bundleIn
|
|
|
|
val out = node.bundleOut
|
|
|
|
}
|
|
|
|
|
|
|
|
val in = io.in(0)
|
|
|
|
val out = io.out(0)
|
|
|
|
val edgeIn = node.edgesIn(0)
|
|
|
|
val edgeOut = node.edgesOut(0)
|
|
|
|
|
2016-09-01 02:44:48 +02:00
|
|
|
// Don't add support for clients if there is no BCE channel
|
|
|
|
val bce = edgeOut.manager.anySupportAcquire && edgeIn.client.anySupportProbe
|
|
|
|
require (!supportClients || bce)
|
|
|
|
|
2016-08-31 01:16:45 +02:00
|
|
|
if (supportManagers) {
|
2016-09-07 08:46:44 +02:00
|
|
|
val handleA = if (passthrough) !edgeOut.manager.supportsHint(edgeIn.address(in.a.bits)) else Bool(true)
|
2016-08-31 01:16:45 +02:00
|
|
|
val bypassD = handleA && in.a.bits.opcode === TLMessages.Hint
|
|
|
|
|
|
|
|
// Prioritize existing D traffic over HintAck
|
|
|
|
in.d.valid := out.d.valid || (bypassD && in.a.valid)
|
|
|
|
out.d.ready := in.d.ready
|
2016-09-07 08:46:44 +02:00
|
|
|
in.d.bits := Mux(out.d.valid, out.d.bits, edgeIn.HintAck(in.a.bits))
|
2016-08-31 01:16:45 +02:00
|
|
|
|
|
|
|
in.a.ready := Mux(bypassD, in.d.ready && !out.d.valid, out.a.ready)
|
|
|
|
out.a.valid := in.a.valid && !bypassD
|
|
|
|
out.a.bits := in.a.bits
|
|
|
|
} else {
|
|
|
|
out.a.valid := in.a.valid
|
|
|
|
in.a.ready := out.a.ready
|
|
|
|
out.a.bits := in.a.bits
|
|
|
|
|
|
|
|
in.d.valid := out.d.valid
|
|
|
|
out.d.ready := in.d.ready
|
|
|
|
in.d.bits := out.d.bits
|
|
|
|
}
|
|
|
|
|
|
|
|
if (supportClients) {
|
|
|
|
val handleB = if (passthrough) !edgeIn.client.supportsHint(out.b.bits.source) else Bool(true)
|
|
|
|
val bypassC = handleB && out.b.bits.opcode === TLMessages.Hint
|
|
|
|
|
|
|
|
// Prioritize existing C traffic over HintAck
|
|
|
|
out.c.valid := in.c.valid || (bypassC && in.b.valid)
|
|
|
|
in.c.ready := out.c.ready
|
2016-09-07 08:46:44 +02:00
|
|
|
out.c.bits := Mux(in.c.valid, in.c.bits, edgeOut.HintAck(out.b.bits))
|
2016-08-31 01:16:45 +02:00
|
|
|
|
|
|
|
out.b.ready := Mux(bypassC, out.c.ready && !in.c.valid, in.b.ready)
|
|
|
|
in.b.valid := out.b.valid && !bypassC
|
|
|
|
in.b.bits := out.b.bits
|
2016-09-01 02:44:48 +02:00
|
|
|
} else if (bce) {
|
2016-08-31 01:16:45 +02:00
|
|
|
in.b.valid := out.b.valid
|
|
|
|
out.b.ready := in.b.ready
|
|
|
|
in.b.bits := out.b.bits
|
|
|
|
|
|
|
|
out.c.valid := in.c.valid
|
|
|
|
in.c.ready := out.c.ready
|
|
|
|
out.c.bits := in.c.bits
|
2016-09-05 01:47:18 +02:00
|
|
|
} else {
|
|
|
|
in.b.valid := Bool(false)
|
|
|
|
in.c.ready := Bool(true)
|
|
|
|
out.b.ready := Bool(true)
|
|
|
|
out.c.valid := Bool(false)
|
2016-08-31 01:16:45 +02:00
|
|
|
}
|
2016-08-31 01:10:42 +02:00
|
|
|
|
2016-09-01 02:44:48 +02:00
|
|
|
if (bce) {
|
|
|
|
// Pass E through unchanged
|
|
|
|
out.e.valid := in.e.valid
|
|
|
|
in.e.ready := out.e.ready
|
|
|
|
out.e.bits := in.e.bits
|
2016-09-05 01:47:18 +02:00
|
|
|
} else {
|
|
|
|
in.e.ready := Bool(true)
|
|
|
|
out.e.valid := Bool(false)
|
2016-09-01 02:44:48 +02:00
|
|
|
}
|
2016-09-02 20:13:43 +02:00
|
|
|
}
|
2016-08-31 00:52:04 +02:00
|
|
|
}
|
2016-09-01 01:45:18 +02:00
|
|
|
|
|
|
|
object TLHintHandler
|
|
|
|
{
|
2016-09-09 08:06:59 +02:00
|
|
|
// applied to the TL source node; y.node := TLHintHandler(x.node)
|
|
|
|
def apply(x: TLBaseNode, supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit sourceInfo: SourceInfo): TLBaseNode = {
|
2016-09-02 20:13:43 +02:00
|
|
|
val hints = LazyModule(new TLHintHandler(supportManagers, supportClients, passthrough))
|
2016-09-09 08:06:59 +02:00
|
|
|
hints.node := x
|
2016-09-01 01:45:18 +02:00
|
|
|
hints.node
|
|
|
|
}
|
|
|
|
}
|