1
0

tilelink2 HintHandler: don't HintAck in the middle of a multibeat op

This commit is contained in:
Wesley W. Terpstra 2016-09-12 19:06:35 -07:00
parent 273d3a73f2
commit 7005422651
2 changed files with 18 additions and 8 deletions

View File

@ -184,8 +184,8 @@ class TLFuzzRAM extends LazyModule
val fuzz = LazyModule(new TLFuzzer(1000)) val fuzz = LazyModule(new TLFuzzer(1000))
model.node := fuzz.node model.node := fuzz.node
xbar.node := TLWidthWidget(model.node, 16) xbar.node := TLWidthWidget(TLHintHandler(model.node), 16)
ram.node := TLHintHandler(TLFragmenter(TLBuffer(xbar.node), 4, 256)) ram.node := TLFragmenter(TLBuffer(xbar.node), 4, 256)
lazy val module = new LazyModuleImp(this) with HasUnitTestIO { lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
io.finished := fuzz.module.io.finished io.finished := fuzz.module.io.finished

View File

@ -36,12 +36,17 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
val handleA = if (passthrough) !edgeOut.manager.supportsHint(address, edgeIn.size(in.a.bits)) else Bool(true) val handleA = if (passthrough) !edgeOut.manager.supportsHint(address, edgeIn.size(in.a.bits)) else Bool(true)
val bypassD = handleA && in.a.bits.opcode === TLMessages.Hint val bypassD = handleA && in.a.bits.opcode === TLMessages.Hint
// Prioritize existing D traffic over HintAck // Prioritize existing D traffic over HintAck (and finish multibeat xfers)
in.d.valid := out.d.valid || (bypassD && in.a.valid) val beats1 = edgeOut.numBeats1(out.d.bits)
val counter = RegInit(UInt(0, width = log2Up(edgeOut.manager.maxTransfer/edgeOut.manager.beatBytes)))
val first = counter === UInt(0)
when (out.d.fire()) { counter := Mux(first, beats1, counter - UInt(1)) }
in.d.valid := out.d.valid || (bypassD && in.a.valid && first)
out.d.ready := in.d.ready out.d.ready := in.d.ready
in.d.bits := Mux(out.d.valid, out.d.bits, edgeIn.HintAck(in.a.bits, edgeOut.manager.findId(address))) in.d.bits := Mux(out.d.valid, out.d.bits, edgeIn.HintAck(in.a.bits, edgeOut.manager.findId(address)))
in.a.ready := Mux(bypassD, in.d.ready && !out.d.valid, out.a.ready) in.a.ready := Mux(bypassD, in.d.ready && first && !out.d.valid, out.a.ready)
out.a.valid := in.a.valid && !bypassD out.a.valid := in.a.valid && !bypassD
out.a.bits := in.a.bits out.a.bits := in.a.bits
} else { } else {
@ -58,12 +63,17 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
val handleB = if (passthrough) !edgeIn.client.supportsHint(out.b.bits.source, edgeOut.size(out.b.bits)) else Bool(true) val handleB = if (passthrough) !edgeIn.client.supportsHint(out.b.bits.source, edgeOut.size(out.b.bits)) else Bool(true)
val bypassC = handleB && out.b.bits.opcode === TLMessages.Hint val bypassC = handleB && out.b.bits.opcode === TLMessages.Hint
// Prioritize existing C traffic over HintAck // Prioritize existing C traffic over HintAck (and finish multibeat xfers)
out.c.valid := in.c.valid || (bypassC && in.b.valid) val beats1 = edgeIn.numBeats1(in.c.bits)
val counter = RegInit(UInt(0, width = log2Up(edgeIn.client.maxTransfer/edgeIn.manager.beatBytes)))
val first = counter === UInt(0)
when (in.c.fire()) { counter := Mux(first, beats1, counter - UInt(1)) }
out.c.valid := in.c.valid || (bypassC && in.b.valid && first)
in.c.ready := out.c.ready in.c.ready := out.c.ready
out.c.bits := Mux(in.c.valid, in.c.bits, edgeOut.HintAck(out.b.bits)) out.c.bits := Mux(in.c.valid, in.c.bits, edgeOut.HintAck(out.b.bits))
out.b.ready := Mux(bypassC, out.c.ready && !in.c.valid, in.b.ready) out.b.ready := Mux(bypassC, out.c.ready && first && !in.c.valid, in.b.ready)
in.b.valid := out.b.valid && !bypassC in.b.valid := out.b.valid && !bypassC
in.b.bits := out.b.bits in.b.bits := out.b.bits
} else if (bce) { } else if (bce) {