1
0
rocket-chip/src/main/scala/uncore/agents/Mmio.scala
2016-11-27 22:15:43 -08:00

76 lines
3.0 KiB
Scala

// See LICENSE.Berkeley for license details.
package uncore.agents
import Chisel._
import uncore.tilelink._
import config._
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 := Bool(true)
}