diff --git a/src/main/scala/uncore/tilelink2/Fuzzer.scala b/src/main/scala/uncore/tilelink2/Fuzzer.scala index aaaef42c..7c9b2625 100644 --- a/src/main/scala/uncore/tilelink2/Fuzzer.scala +++ b/src/main/scala/uncore/tilelink2/Fuzzer.scala @@ -184,8 +184,8 @@ class TLFuzzRAM extends LazyModule val fuzz = LazyModule(new TLFuzzer(1000)) model.node := fuzz.node - xbar.node := TLWidthWidget(model.node, 16) - ram.node := TLHintHandler(TLFragmenter(TLBuffer(xbar.node), 4, 256)) + xbar.node := TLWidthWidget(TLHintHandler(model.node), 16) + ram.node := TLFragmenter(TLBuffer(xbar.node), 4, 256) lazy val module = new LazyModuleImp(this) with HasUnitTestIO { io.finished := fuzz.module.io.finished diff --git a/src/main/scala/uncore/tilelink2/HintHandler.scala b/src/main/scala/uncore/tilelink2/HintHandler.scala index 6b48e758..3d57f03c 100644 --- a/src/main/scala/uncore/tilelink2/HintHandler.scala +++ b/src/main/scala/uncore/tilelink2/HintHandler.scala @@ -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 bypassD = handleA && in.a.bits.opcode === TLMessages.Hint - // Prioritize existing D traffic over HintAck - in.d.valid := out.d.valid || (bypassD && in.a.valid) + // Prioritize existing D traffic over HintAck (and finish multibeat xfers) + 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 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.bits := in.a.bits } 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 bypassC = handleB && out.b.bits.opcode === TLMessages.Hint - // Prioritize existing C traffic over HintAck - out.c.valid := in.c.valid || (bypassC && in.b.valid) + // Prioritize existing C traffic over HintAck (and finish multibeat xfers) + 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 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.bits := out.b.bits } else if (bce) {