From adaec18bec11af88570a18de37467747361bb20c Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Thu, 14 Jan 2016 22:01:42 -0800 Subject: [PATCH] add TL manager for MMIO requests --- uncore/src/main/scala/converters.scala | 68 ++++++++++++++++++++++++++ uncore/src/main/scala/uncore.scala | 1 + 2 files changed, 69 insertions(+) diff --git a/uncore/src/main/scala/converters.scala b/uncore/src/main/scala/converters.scala index 22e9532a..509aa2b4 100644 --- a/uncore/src/main/scala/converters.scala +++ b/uncore/src/main/scala/converters.scala @@ -729,3 +729,71 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String) } } else { io.out <> io.in } } + +class MMIOTileLinkManagerData(implicit p: Parameters) + extends TLBundle()(p) + with HasClientId + with HasClientTransactionId + +class MMIOTileLinkManager(implicit p: Parameters) + extends CoherenceAgentModule()(p) { + val io = new ManagerTLIO + + // MMIO requests should never need probe or release + io.inner.probe.valid := Bool(false) + io.inner.release.ready := Bool(false) + + val multibeat_fire = io.outer.acquire.fire() && io.oacq().hasMultibeatData() + val multibeat_start = multibeat_fire && io.oacq().addr_beat === UInt(0) + val multibeat_end = multibeat_fire && io.oacq().addr_beat === UInt(outerDataBeats - 1) + + // Acquire and Grant are basically passthru, + // except client_id and client_xact_id need to be converted. + // Associate the inner client_id and client_xact_id + // with the outer client_xact_id. + val xact_pending = Reg(init = UInt(0, maxManagerXacts)) + val xact_id_sel = PriorityEncoder(~xact_pending) + val xact_id_reg = RegEnable(xact_id_sel, multibeat_start) + val xact_multibeat = Reg(init = Bool(false)) + val outer_xact_id = Mux(xact_multibeat, xact_id_reg, xact_id_sel) + val xact_free = !xact_pending.andR + val xact_buffer = Reg(Vec(maxManagerXacts, new MMIOTileLinkManagerData)) + + io.inner.acquire.ready := io.outer.acquire.ready && xact_free + io.outer.acquire.valid := io.inner.acquire.valid && xact_free + io.outer.acquire.bits := io.inner.acquire.bits + io.outer.acquire.bits.client_xact_id := outer_xact_id + + def isLastBeat[T <: TileLinkChannel with HasTileLinkBeatId](in: T): Bool = + !in.hasMultibeatData() || in.addr_beat === UInt(outerDataBeats - 1) + + def addPendingBitOnAcq[T <: AcquireMetadata](in: DecoupledIO[T]): UInt = + Mux(in.fire() && isLastBeat(in.bits), UIntToOH(in.bits.client_xact_id), UInt(0)) + + def clearPendingBitOnGnt[T <: GrantMetadata](in: DecoupledIO[T]): UInt = + ~Mux(in.fire() && isLastBeat(in.bits) && !in.bits.requiresAck(), + UIntToOH(in.bits.manager_xact_id), UInt(0)) + + def clearPendingBitOnFin(in: DecoupledIO[Finish]): UInt = + ~Mux(in.fire(), UIntToOH(in.bits.manager_xact_id), UInt(0)) + + xact_pending := (xact_pending | addPendingBitOnAcq(io.outer.acquire)) & + clearPendingBitOnFin(io.inner.finish) & + clearPendingBitOnGnt(io.inner.grant) + + when (io.outer.acquire.fire() && isLastBeat(io.outer.acquire.bits)) { + xact_buffer(outer_xact_id) := io.iacq() + } + + when (multibeat_start) { xact_multibeat := Bool(true) } + when (multibeat_end) { xact_multibeat := Bool(false) } + + val gnt_xact = xact_buffer(io.ognt().client_xact_id) + io.outer.grant.ready := io.inner.grant.ready + io.inner.grant.valid := io.outer.grant.valid + io.inner.grant.bits := io.outer.grant.bits + io.inner.grant.bits.client_id := gnt_xact.client_id + io.inner.grant.bits.client_xact_id := gnt_xact.client_xact_id + io.inner.grant.bits.manager_xact_id := io.ognt().client_xact_id + io.inner.finish.ready := xact_pending(io.inner.finish.bits.manager_xact_id) +} diff --git a/uncore/src/main/scala/uncore.scala b/uncore/src/main/scala/uncore.scala index 3d38f6b2..34405aae 100644 --- a/uncore/src/main/scala/uncore.scala +++ b/uncore/src/main/scala/uncore.scala @@ -32,6 +32,7 @@ trait HasCoherenceAgentParameters { val innerWriteMaskBits = innerTLParams.writeMaskBits val innerBeatAddrBits = log2Up(innerDataBeats) val innerByteAddrBits = log2Up(innerDataBits/8) + val maxManagerXacts = innerTLParams.maxManagerXacts require(outerDataBeats == innerDataBeats) //TODO: fix all xact_data Vecs to remove this requirement }