From eb9e998c085589f60efb30f79ef5509b0a83b16a Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 18 Jul 2016 13:09:44 -0700 Subject: [PATCH] Add ManagerToClientStatelessBridge --- .../main/scala/agents/StatelessBridge.scala | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 uncore/src/main/scala/agents/StatelessBridge.scala diff --git a/uncore/src/main/scala/agents/StatelessBridge.scala b/uncore/src/main/scala/agents/StatelessBridge.scala new file mode 100644 index 00000000..efc7e2ab --- /dev/null +++ b/uncore/src/main/scala/agents/StatelessBridge.scala @@ -0,0 +1,61 @@ +// See LICENSE for license details. + +package uncore.agents + +import Chisel._ +import uncore.coherence._ +import uncore.tilelink._ +import uncore.constants._ +import uncore.devices._ +import cde.{Parameters, Field, Config} + +/** The ManagerToClientStateless Bridge does not maintain any state for the messages + * which pass through it. It simply passes the messages back and forth without any + * tracking or translation. + * + * This can reduce area and timing in very constrained situations: + * - The Manager and Client implement the same coherence protocol + * - There are no probe or finish messages. + * - The outer transaction ID is large enough to handle all possible inner + * transaction IDs, such that no remapping state must be maintained. + * + */ + +class ManagerToClientStatelessBridge(implicit p: Parameters) extends HierarchicalCoherenceAgent()(p) { + + val icid = io.inner.acquire.bits.client_id.getWidth + val ixid = io.inner.acquire.bits.client_xact_id.getWidth + val oxid = io.outer.acquire.bits.client_xact_id.getWidth + + // Stateless Bridge is only usable in certain constrained situations. + // Sanity check its usage here. + // Additional requirements are that the inner and outer Coherence policies + // are the same (e.g. MEI != MESI), and that NTiles == 1, + // but this is not checked here. + require (p(NTiles) == 1) + + require(icid + ixid <= oxid) + require(icid == io.inner.release.bits.client_id.getWidth) + require(ixid == io.inner.release.bits.client_xact_id.getWidth) + require(oxid == io.outer.release.bits.client_xact_id.getWidth) + + io.outer.acquire.valid := io.inner.acquire.valid + io.inner.acquire.ready := io.outer.acquire.ready + io.outer.acquire.bits := io.inner.acquire.bits + io.outer.acquire.bits.client_xact_id := Cat(io.inner.acquire.bits.client_id, io.inner.acquire.bits.client_xact_id) + + io.outer.release.valid := io.inner.release.valid + io.inner.release.ready := io.outer.release.ready + io.outer.release.bits := io.inner.release.bits + io.outer.release.bits.client_xact_id := Cat(io.inner.release.bits.client_id, io.inner.release.bits.client_xact_id) + + io.inner.grant.valid := io.outer.grant.valid + io.outer.grant.ready := io.inner.grant.ready + io.inner.grant.bits := io.outer.grant.bits + io.inner.grant.bits.client_xact_id := io.outer.grant.bits.client_xact_id(ixid-1, 0) + io.inner.grant.bits.client_id := io.outer.grant.bits.client_xact_id(icid+ixid-1, ixid) + + io.inner.probe.valid := Bool(false) + io.inner.finish.ready := Bool(true) +} +