From 9a258e7fb467e5d3135fc7b372ef73cb9428ede5 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 22 Apr 2013 16:48:55 -0700 Subject: [PATCH 1/3] use new locking round robin arbiter --- uncore/src/package.scala | 51 ++-------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/uncore/src/package.scala b/uncore/src/package.scala index 4133a9d3..7e1fc7a0 100644 --- a/uncore/src/package.scala +++ b/uncore/src/package.scala @@ -6,6 +6,8 @@ import scala.collection.mutable.Stack //TODO: Remove these Networking classes from the package object once Scala bug //SI-3439 is resolved. +implicit def toOption[A](a: A) = Option(a) + case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int) class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle { @@ -24,55 +26,6 @@ class BasicCrossbarIO[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkCon abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Component -class LockingRRArbiter[T <: Data](n: Int, count: Int)(data: => T) extends Component { - val io = new ioArbiter(n)(data) - - val cnt = Reg(resetVal = UFix(0, width = log2Up(count))) - val cnt_next = cnt + UFix(1) - val locked = Reg(resetVal = Bool(false)) - val lock_idx = Reg(resetVal = UFix(n)) - - if(count > 1){ - when(io.out.valid && io.out.ready) { - cnt := cnt_next - when(!locked) { - locked := Bool(true) - lock_idx := Vec(io.in.map{ in => in.ready && in.valid}){Bool()}.indexWhere{i: Bool => i} - } - when(cnt_next === UFix(0)) { - locked := Bool(false) - } - } - } else { - locked := Bool(false) - lock_idx := UFix(n) - cnt := UFix(0) - } - - - val last_grant = Reg(resetVal = Bits(0, log2Up(n))) - val g = ArbiterCtrl((0 until n).map(i => io.in(i).valid && UFix(i) > last_grant) ++ io.in.map(_.valid)) - val grant = (0 until n).map(i => g(i) && UFix(i) > last_grant || g(i+n)) - (0 until n).map(i => io.in(i).ready := Mux(locked, lock_idx === UFix(i), grant(i)) && io.out.ready) - - var choose = Bits(n-1) - for (i <- n-2 to 0 by -1) - choose = Mux(io.in(i).valid, Bits(i), choose) - for (i <- n-1 to 1 by -1) - choose = Mux(io.in(i).valid && UFix(i) > last_grant, Bits(i), choose) - choose = Mux(locked, lock_idx, choose) - when (io.out.valid && io.out.ready) { - last_grant := choose - } - - val dvec = Vec(n) { data } - (0 until n).map(i => dvec(i) := io.in(i).bits ) - - io.out.valid := Mux(locked, io.in(lock_idx).valid, io.in.map(_.valid).foldLeft(Bool(false))( _ || _)) - io.out.bits := dvec(choose) - io.chosen := choose -} - class BasicCrossbar[T <: Data](count: Int)(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) { val io = new Bundle { val in = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}}.flip From 9a3b2e7006c370b6c37bee57272a0d1788d50e5b Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 1 May 2013 16:48:01 -0700 Subject: [PATCH 2/3] new paired meta/data IO type, and matching arbiter --- uncore/src/package.scala | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/uncore/src/package.scala b/uncore/src/package.scala index 7e1fc7a0..46c39d51 100644 --- a/uncore/src/package.scala +++ b/uncore/src/package.scala @@ -8,6 +8,68 @@ import scala.collection.mutable.Stack implicit def toOption[A](a: A) = Option(a) +class PairedDataIO[M <: Data, D <: Data]()(m: => M, d: => D) extends Bundle { + val meta = (new FIFOIO()){ m } + val data = (new FIFOIO()){ d } +} + +class PairedArbiterIO[M <: Data, D <: Data](n: Int)(m: => M, d: => D) extends Bundle { + val in = Vec(n) { new PairedDataIO()(m,d) }.flip + val out = new PairedDataIO()(m,d) + val meta_chosen = Bits(OUTPUT, log2Up(n)) + val data_chosen = Bits(OUTPUT, log2Up(n)) +} + +class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock: Option[M => Bool] = None)(meta: => M, data: => D) { + require(isPow2(count)) + val io = new PairedArbiterIO(n)(meta,data) + val locked = if(count > 1) Reg(resetVal = Bool(false)) else Bool(false) + val lockIdx = if(count > 1) Reg(resetVal = UFix(n-1)) else UFix(n-1) + val grant = List.fill(n)(Bool()) + val meta_chosen = Bits(width = log2Up(n)) + + val chosen_meta_has_data = io.out.meta.valid && needsLock.map(_(io.out.meta.bits)).getOrElse(Bool(true)) + (0 until n).map(i => io.in(i).meta.ready := grant(i) && io.out.meta.ready) + (0 until n).map(i => io.in(i).data.ready := Mux(locked, lockIdx === UFix(i), grant(i) && chosen_meta_has_data) && io.out.data.ready) + io.out.meta.valid := io.in(meta_chosen).meta.valid + io.out.data.valid := Mux(locked, io.in(lockIdx).data.valid, io.in(meta_chosen).data.valid && chosen_meta_has_data) + io.out.meta.bits := io.in(meta_chosen).meta.bits + io.out.data.bits := Mux(locked, io.in(lockIdx).data.bits, io.in(meta_chosen).data.bits) + io.meta_chosen := meta_chosen + io.data_chosen := Mux(locked, lockIdx, meta_chosen) + + if(count > 1){ + val cnt = Reg(resetVal = UFix(0, width = log2Up(count))) + val cnt_next = cnt + UFix(1) + when(io.out.data.fire()){ + cnt := cnt_next + when(cnt_next === UFix(0)) { + locked := Bool(false) + } + } + when(io.out.meta.fire()) { + when(needsLock.map(_(io.out.meta.bits)).getOrElse(Bool(true))) { + when(!locked) { + locked := Bool(true) + lockIdx := Vec(io.in.map{in => in.meta.fire()}){Bool()}.indexWhere{i: Bool => i} + } + } + } + } + val last_grant = Reg(resetVal = Bits(0, log2Up(n))) + val ctrl = ArbiterCtrl((0 until n).map(i => io.in(i).meta.valid && UFix(i) > last_grant) ++ io.in.map(_.meta.valid)) + (0 until n).map(i => grant(i) := ctrl(i) && UFix(i) > last_grant || ctrl(i + n)) + + var choose = Bits(n-1) + for (i <- n-2 to 0 by -1) + choose = Mux(io.in(i).meta.valid, Bits(i), choose) + for (i <- n-1 to 1 by -1) + choose = Mux(io.in(i).meta.valid && UFix(i) > last_grant, Bits(i), choose) + meta_chosen := choose + + when (io.out.meta.fire()) { last_grant := meta_chosen } +} + case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int) class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle { From 4c1f105ce94eb9dd3ae7902272f5301119278c15 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 21 May 2013 17:19:07 -0700 Subject: [PATCH 3/3] added PairedData link type with matching crossbar, ported tilelink and uncore to use --- uncore/src/coherence.scala | 6 +- uncore/src/package.scala | 50 +++++++++-- uncore/src/tilelink.scala | 93 ++++++++------------ uncore/src/uncore.scala | 168 ++++++++++++++++++------------------- 4 files changed, 158 insertions(+), 159 deletions(-) diff --git a/uncore/src/coherence.scala b/uncore/src/coherence.scala index ec932ec9..6a1eaf80 100644 --- a/uncore/src/coherence.scala +++ b/uncore/src/coherence.scala @@ -3,9 +3,9 @@ package uncore import Chisel._ import Constants._ -trait CoherenceAgentRole -trait ClientCoherenceAgent extends CoherenceAgentRole -trait MasterCoherenceAgent extends CoherenceAgentRole +abstract trait CoherenceAgentRole +abstract trait ClientCoherenceAgent extends CoherenceAgentRole +abstract trait MasterCoherenceAgent extends CoherenceAgentRole abstract class CoherencePolicy { def isHit (cmd: Bits, state: UFix): Bool diff --git a/uncore/src/package.scala b/uncore/src/package.scala index 46c39d51..754621ad 100644 --- a/uncore/src/package.scala +++ b/uncore/src/package.scala @@ -9,8 +9,9 @@ import scala.collection.mutable.Stack implicit def toOption[A](a: A) = Option(a) class PairedDataIO[M <: Data, D <: Data]()(m: => M, d: => D) extends Bundle { - val meta = (new FIFOIO()){ m } - val data = (new FIFOIO()){ d } + val meta = new FIFOIO()(m) + val data = new FIFOIO()(d) + override def clone = { new PairedDataIO()(m,d).asInstanceOf[this.type] } } class PairedArbiterIO[M <: Data, D <: Data](n: Int)(m: => M, d: => D) extends Bundle { @@ -18,9 +19,10 @@ class PairedArbiterIO[M <: Data, D <: Data](n: Int)(m: => M, d: => D) extends Bu val out = new PairedDataIO()(m,d) val meta_chosen = Bits(OUTPUT, log2Up(n)) val data_chosen = Bits(OUTPUT, log2Up(n)) + override def clone = { new PairedArbiterIO(n)(m,d).asInstanceOf[this.type] } } -class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock: Option[M => Bool] = None)(meta: => M, data: => D) { +class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock: Option[M => Bool] = None)(meta: => M, data: => D) extends Component { require(isPow2(count)) val io = new PairedArbiterIO(n)(meta,data) val locked = if(count > 1) Reg(resetVal = Bool(false)) else Bool(false) @@ -28,11 +30,13 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock val grant = List.fill(n)(Bool()) val meta_chosen = Bits(width = log2Up(n)) - val chosen_meta_has_data = io.out.meta.valid && needsLock.map(_(io.out.meta.bits)).getOrElse(Bool(true)) - (0 until n).map(i => io.in(i).meta.ready := grant(i) && io.out.meta.ready) - (0 until n).map(i => io.in(i).data.ready := Mux(locked, lockIdx === UFix(i), grant(i) && chosen_meta_has_data) && io.out.data.ready) - io.out.meta.valid := io.in(meta_chosen).meta.valid - io.out.data.valid := Mux(locked, io.in(lockIdx).data.valid, io.in(meta_chosen).data.valid && chosen_meta_has_data) + val chosen_meta_has_data = needsLock.map(_(io.in(meta_chosen).meta.bits)).getOrElse(Bool(true)) + val valid_meta_has_data = io.in(meta_chosen).meta.valid && chosen_meta_has_data + val grant_chosen_meta = !(locked && chosen_meta_has_data) + (0 until n).map(i => io.in(i).meta.ready := grant(i) && grant_chosen_meta && io.out.meta.ready) + (0 until n).map(i => io.in(i).data.ready := Mux(locked, lockIdx === UFix(i), grant(i) && valid_meta_has_data) && io.out.data.ready) + io.out.meta.valid := io.in(meta_chosen).meta.valid && grant_chosen_meta + io.out.data.valid := Mux(locked, io.in(lockIdx).data.valid, io.in(meta_chosen).data.valid && valid_meta_has_data) io.out.meta.bits := io.in(meta_chosen).meta.bits io.out.data.bits := Mux(locked, io.in(lockIdx).data.bits, io.in(meta_chosen).data.bits) io.meta_chosen := meta_chosen @@ -70,6 +74,34 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock when (io.out.meta.fire()) { last_grant := meta_chosen } } +class PairedCrossbar[M <: Data, D <: Data](count: Int, needsLock: Option[BasicCrossbarIO[M] => Bool] = None)(meta: => M, data: => D)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) { + val io = new Bundle { + val in = Vec(conf.nEndpoints){new PairedDataIO()(new BasicCrossbarIO()(meta),new BasicCrossbarIO()(data))}.flip + val out = Vec(conf.nEndpoints){new PairedDataIO()(new BasicCrossbarIO()(meta),new BasicCrossbarIO()(data))} + } + + val metaRdyVecs = List.fill(conf.nEndpoints)(Vec(conf.nEndpoints){Bool()}) + val dataRdyVecs = List.fill(conf.nEndpoints)(Vec(conf.nEndpoints){Bool()}) + val rdyVecs = metaRdyVecs zip dataRdyVecs + + io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => { + val rrarb = new PairedLockingRRArbiter(conf.nEndpoints, count, needsLock)(io.in(0).meta.bits.clone, io.in(0).data.bits.clone) + rrarb.io.in zip io.in zip rdys._1 zip rdys._2 map { case (((arb, in), meta_rdy), data_rdy) => { + arb.meta.valid := in.meta.valid && (in.meta.bits.header.dst === UFix(i)) + arb.meta.bits := in.meta.bits + meta_rdy := arb.meta.ready && (in.meta.bits.header.dst === UFix(i)) + arb.data.valid := in.data.valid && (in.data.bits.header.dst === UFix(i)) + arb.data.bits := in.data.bits + data_rdy := arb.data.ready && (in.data.bits.header.dst === UFix(i)) + }} + out <> rrarb.io.out + }} + for(i <- 0 until conf.nEndpoints) { + io.in(i).meta.ready := rdyVecs.map(r => r._1(i)).reduceLeft(_||_) + io.in(i).data.ready := rdyVecs.map(r => r._2(i)).reduceLeft(_||_) + } +} + case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int) class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle { @@ -88,7 +120,7 @@ class BasicCrossbarIO[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkCon abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Component -class BasicCrossbar[T <: Data](count: Int)(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) { +class BasicCrossbar[T <: Data](count: Int = 1)(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) { val io = new Bundle { val in = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}}.flip val out = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}} diff --git a/uncore/src/tilelink.scala b/uncore/src/tilelink.scala index c7f82da2..589254f9 100644 --- a/uncore/src/tilelink.scala +++ b/uncore/src/tilelink.scala @@ -116,82 +116,55 @@ class Grant extends MasterSourcedMessage with HasMemData with HasClientTransacti class GrantAck extends ClientSourcedMessage with HasMasterTransactionId -abstract class DirectionalFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) -class ClientSourcedIO[T <: Data]()(data: => T) extends DirectionalFIFOIO()(data) -class ClientSourcedDataIO[T <: Data]()(data: => T) extends ClientSourcedIO()(data) -class MasterSourcedIO[T <: Data]()(data: => T) extends DirectionalFIFOIO()(data) {flip()} +trait DirectionalIO +trait ClientSourcedIO extends DirectionalIO +trait MasterSourcedIO extends DirectionalIO +class ClientSourcedFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) with ClientSourcedIO { + override def clone = { new ClientSourcedFIFOIO()(data).asInstanceOf[this.type] } +} +class ClientSourcedDataIO[M <: Data, D <: Data]()(meta: => M, data: => D) extends PairedDataIO()(meta,data) with ClientSourcedIO { + override def clone = { new ClientSourcedDataIO()(meta,data).asInstanceOf[this.type] } +} +class MasterSourcedFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) with MasterSourcedIO { + flip() + override def clone = { new MasterSourcedFIFOIO()(data).asInstanceOf[this.type] } +} +class MasterSourcedDataIO[M <: Data, D <: Data]()(meta: => M, data: => D) extends PairedDataIO()(meta,data) with MasterSourcedIO { + flip() + override def clone = { new MasterSourcedDataIO()(meta,data).asInstanceOf[this.type] } +} class UncachedTileLinkIO(implicit conf: LogicalNetworkConfiguration) extends Bundle { - val acquire = (new ClientSourcedIO){(new LogicalNetworkIO){new Acquire }} - val acquire_data = (new ClientSourcedDataIO){(new LogicalNetworkIO){new AcquireData }} - val grant = (new MasterSourcedIO) {(new LogicalNetworkIO){new Grant }} - val grant_ack = (new ClientSourcedIO){(new LogicalNetworkIO){new GrantAck }} + val acquire = new ClientSourcedDataIO()(new LogicalNetworkIO()(new Acquire), new LogicalNetworkIO()(new AcquireData)) + val grant = new MasterSourcedFIFOIO()(new LogicalNetworkIO()(new Grant)) + val grant_ack = new ClientSourcedFIFOIO()(new LogicalNetworkIO()(new GrantAck)) override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] } } class TileLinkIO(implicit conf: LogicalNetworkConfiguration) extends UncachedTileLinkIO()(conf) { - val probe = (new MasterSourcedIO){(new LogicalNetworkIO){new Probe }} - val release = (new ClientSourcedIO){(new LogicalNetworkIO){new Release }} - val release_data = (new ClientSourcedDataIO){(new LogicalNetworkIO){new ReleaseData }} + val probe = new MasterSourcedFIFOIO()(new LogicalNetworkIO()(new Probe)) + val release = new ClientSourcedDataIO()(new LogicalNetworkIO()(new Release), new LogicalNetworkIO()(new ReleaseData)) override def clone = { new TileLinkIO().asInstanceOf[this.type] } } -object UncachedTileLinkIOArbiterShim { - def apply[T <: HasClientTransactionId](in: ClientSourcedIO[LogicalNetworkIO[T]], id: Int, max: Int)(implicit lconf: LogicalNetworkConfiguration) = { - val shim = (new UncachedTileLinkIOArbiterShim(id, max)){in.bits.payload.clone} - shim.io.in <> in - shim.io.out - } -} -class UncachedTileLinkIOArbiterShim[T <: HasClientTransactionId](id: Int, max: Int)(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Component { - val io = new Bundle { - val in = (new ClientSourcedIO){(new LogicalNetworkIO){ data }}.flip - val out = (new ClientSourcedIO){(new LogicalNetworkIO){ data }} - } - io.out.bits := io.in.bits - io.out.bits.payload.client_xact_id := Cat(io.in.bits.payload.client_xact_id, UFix(id, log2Up(max))) - io.out.valid := io.in.valid - io.in.ready := io.out.ready -} - - -class UncachedTileLinkIOArbiter(n: Int)(implicit conf: LogicalNetworkConfiguration) extends Component { +class UncachedTileLinkIOArbiter(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Component { val io = new Bundle { val in = Vec(n) { new UncachedTileLinkIO }.flip val out = new UncachedTileLinkIO } - val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES))) - val mem_cnt_next = mem_cnt + UFix(1) - val locked = Reg(resetVal = Bool(false)) - val lock_idx = Reg(resetVal = UFix(n)) - - when(io.out.acquire_data.valid && io.out.acquire_data.ready) { - mem_cnt := mem_cnt_next - when(!locked) { - locked := Bool(true) - lock_idx := Vec(io.in.map{ in => in.acquire_data.ready && in.acquire_data.valid}){Bool()}.indexWhere{i: Bool => i} - } - when(mem_cnt_next === UFix(0)) { - locked := Bool(false) - } - } - - val acqd_grant = ArbiterCtrl(io.in.map(_.acquire_data.valid)) - (0 until n).map(i => io.in(i).acquire_data.ready := Mux(locked, UFix(i) === lock_idx, acqd_grant(i)) && io.out.acquire_data.ready) - var acqd_bits = io.in(n-1).acquire_data.bits - for (i <- n-2 to 0 by -1) { - acqd_bits = Mux(io.in(i).acquire_data.valid, io.in(i).acquire_data.bits, acqd_bits) - } - val locked_req = io.in(lock_idx).acquire_data - io.out.acquire_data.bits := Mux(locked, locked_req.bits, acqd_bits) - io.out.acquire_data.valid := Mux(locked, locked_req.valid, io.in.map(_.acquire_data.valid).reduce(_||_)) - - val acq_arb = (new Arbiter(n)){ (new LogicalNetworkIO){new Acquire} } + def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload) + val acq_arb = new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData}) io.out.acquire <> acq_arb.io.out - io.in.map(_.acquire).zipWithIndex.map{ case(acq, id) => UncachedTileLinkIOArbiterShim(acq, id, n) }.zip(acq_arb.io.in).map{ case (req, arb) => req <> arb} + io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => { + arb.data <> req.data + arb.meta.valid := req.meta.valid + arb.meta.bits := req.meta.bits + arb.meta.bits.payload.client_xact_id := Cat(req.meta.bits.payload.client_xact_id, UFix(id, log2Up(n))) + req.meta.ready := arb.meta.ready + }} - val grant_ack_arb = (new Arbiter(n)){ (new LogicalNetworkIO){new GrantAck} } + val grant_ack_arb = (new RRArbiter(n)){ (new LogicalNetworkIO){new GrantAck} } io.out.grant_ack <> grant_ack_arb.io.out grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack } diff --git a/uncore/src/uncore.scala b/uncore/src/uncore.scala index f0571d89..3a3c36ae 100644 --- a/uncore/src/uncore.scala +++ b/uncore/src/uncore.scala @@ -31,23 +31,22 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: UncoreConfiguration) extends // Handle acquire transaction initiation val acquire = io.client.acquire - val acquire_data = io.client.acquire_data val any_acquire_conflict = trackerList.map(_.io.has_acquire_conflict).reduce(_||_) val block_acquires = any_acquire_conflict val alloc_arb = (new Arbiter(trackerList.size)) { Bool() } for( i <- 0 until trackerList.size ) { val t = trackerList(i).io.client - alloc_arb.io.in(i).valid := t.acquire.ready - t.acquire.bits := acquire.bits - t.acquire.valid := alloc_arb.io.in(i).ready + alloc_arb.io.in(i).valid := t.acquire.meta.ready + t.acquire.meta.bits := acquire.meta.bits + t.acquire.meta.valid := alloc_arb.io.in(i).ready - t.acquire_data.bits := acquire_data.bits - t.acquire_data.valid := acquire_data.valid + t.acquire.data.bits := acquire.data.bits + t.acquire.data.valid := acquire.data.valid } - acquire.ready := trackerList.map(_.io.client.acquire.ready).reduce(_||_) && !block_acquires - acquire_data.ready := trackerList.map(_.io.client.acquire_data.ready).reduce(_||_) - alloc_arb.io.out.ready := acquire.valid && !block_acquires + acquire.meta.ready := trackerList.map(_.io.client.acquire.meta.ready).reduce(_||_) && !block_acquires + acquire.data.ready := trackerList.map(_.io.client.acquire.data.ready).reduce(_||_) + alloc_arb.io.out.ready := acquire.meta.valid && !block_acquires // Handle probe request generation val probe_arb = (new Arbiter(trackerList.size)){(new LogicalNetworkIO){ new Probe }} @@ -56,22 +55,21 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: UncoreConfiguration) extends // Handle releases, which might be voluntary and might have data val release = io.client.release - val release_data = io.client.release_data - val voluntary = co.isVoluntary(release.bits.payload) + val voluntary = co.isVoluntary(release.meta.bits.payload) val any_release_conflict = trackerList.tail.map(_.io.has_release_conflict).reduce(_||_) val block_releases = Bool(false) val conflict_idx = Vec(trackerList.map(_.io.has_release_conflict)){Bool()}.lastIndexWhere{b: Bool => b} //val release_idx = Mux(voluntary, Mux(any_release_conflict, conflict_idx, UFix(0)), release.bits.payload.master_xact_id) // TODO: Add merging logic to allow allocated AcquireTracker to handle conflicts, send all necessary grants, use first sufficient response - val release_idx = Mux(voluntary, release.bits.header.src, release.bits.payload.master_xact_id) + val release_idx = Mux(voluntary, release.meta.bits.header.src, release.meta.bits.payload.master_xact_id) for( i <- 0 until trackerList.size ) { val t = trackerList(i).io.client - t.release.bits := release.bits - t.release.valid := release.valid && (release_idx === UFix(i)) && !block_releases - t.release_data.bits := release_data.bits - t.release_data.valid := release_data.valid + t.release.meta.bits := release.meta.bits + t.release.meta.valid := release.meta.valid && (release_idx === UFix(i)) && !block_releases + t.release.data.bits := release.data.bits + t.release.data.valid := release.data.valid } - release.ready := Vec(trackerList.map(_.io.client.release.ready)){Bool()}(release_idx) && !block_releases - release_data.ready := trackerList.map(_.io.client.release_data.ready).reduce(_||_) + release.meta.ready := Vec(trackerList.map(_.io.client.release.meta.ready)){Bool()}(release_idx) && !block_releases + release.data.ready := trackerList.map(_.io.client.release.data.ready).reduce(_||_) // Reply to initial requestor val grant_arb = (new Arbiter(trackerList.size)){(new LogicalNetworkIO){ new Grant }} @@ -85,7 +83,7 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: UncoreConfiguration) extends ack.ready := Bool(true) // Create an arbiter for the one memory port - val outer_arb = new UncachedTileLinkIOArbiter(trackerList.size) + val outer_arb = new UncachedTileLinkIOArbiter(trackerList.size, conf.co) outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.master } io.master <> outer_arb.io.out } @@ -114,22 +112,22 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: Uncore val cmd_to_read = co.getUncachedReadAcquire(xact.addr, UFix(trackerId)) io.has_acquire_conflict := Bool(false) - io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.bits.payload.addr) && (state != s_idle) + io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.meta.bits.payload.addr) && (state != s_idle) io.master.grant.ready := Bool(false) - io.master.acquire.valid := Bool(false) - io.master.acquire.bits.payload := cmd_to_write + io.master.acquire.meta.valid := Bool(false) + io.master.acquire.meta.bits.payload := cmd_to_write //TODO io.master.acquire.bits.header.dst - io.master.acquire.bits.header.src := UFix(bankId) - io.master.acquire_data.valid := Bool(false) - io.master.acquire_data.bits.payload.data := UFix(0) + io.master.acquire.meta.bits.header.src := UFix(bankId) + io.master.acquire.data.valid := Bool(false) + io.master.acquire.data.bits.payload.data := UFix(0) //TODO io.master.acquire_data.bits.header.dst - io.master.acquire_data.bits.header.src := UFix(bankId) - io.client.acquire.ready := Bool(false) - io.client.acquire_data.ready := Bool(false) + io.master.acquire.data.bits.header.src := UFix(bankId) + io.client.acquire.meta.ready := Bool(false) + io.client.acquire.data.ready := Bool(false) io.client.probe.valid := Bool(false) - io.client.release.ready := Bool(false) - io.client.release_data.ready := Bool(false) // DNC + io.client.release.meta.ready := Bool(false) + io.client.release.data.ready := Bool(false) // DNC io.client.grant.valid := Bool(false) io.client.grant.bits.payload.g_type := co.getGrantType(xact, UFix(0)) io.client.grant.bits.payload.client_xact_id := xact.client_xact_id @@ -141,11 +139,11 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: Uncore switch (state) { is(s_idle) { - io.client.release.ready := Bool(true) - when( io.client.release.valid ) { - xact := io.client.release.bits.payload - init_client_id_ := io.client.release.bits.header.src - release_data_needs_write := co.messageHasData(io.client.release.bits.payload) + io.client.release.meta.ready := Bool(true) + when( io.client.release.meta.valid ) { + xact := io.client.release.meta.bits.payload + init_client_id_ := io.client.release.meta.bits.header.src + release_data_needs_write := co.messageHasData(io.client.release.meta.bits.payload) mem_cnt := UFix(0) mem_cmd_sent := Bool(false) state := s_mem @@ -153,10 +151,9 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: Uncore } is(s_mem) { when (release_data_needs_write) { - doOuterReqWrite(io.master.acquire, - io.master.acquire_data, - io.client.release_data, - release_data_needs_write, + doOuterReqWrite(io.master.acquire, + io.client.release.data, + release_data_needs_write, mem_cmd_sent, init_client_id_) } . otherwise { state := s_ack } @@ -192,20 +189,20 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura if (conf.ln.nClients > 1) { // issue self-probes for uncached read xacts to facilitate I$ coherence val probe_self = Bool(true) //co.needsSelfProbe(io.client.acquire.bits.payload) - val myflag = Mux(probe_self, Bits(0), UFixToOH(io.client.acquire.bits.header.src(log2Up(conf.ln.nClients)-1,0))) + val myflag = Mux(probe_self, Bits(0), UFixToOH(io.client.acquire.meta.bits.header.src(log2Up(conf.ln.nClients)-1,0))) probe_initial_flags := ~(io.tile_incoherent | myflag) } - io.has_acquire_conflict := co.isCoherenceConflict(xact.addr, io.client.acquire.bits.payload.addr) && (state != s_idle) - io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.bits.payload.addr) && (state != s_idle) - io.master.acquire.valid := Bool(false) - io.master.acquire.bits.payload := co.getUncachedReadAcquire(xact.addr, UFix(trackerId)) + io.has_acquire_conflict := co.isCoherenceConflict(xact.addr, io.client.acquire.meta.bits.payload.addr) && (state != s_idle) + io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.meta.bits.payload.addr) && (state != s_idle) + io.master.acquire.meta.valid := Bool(false) + io.master.acquire.meta.bits.payload := co.getUncachedReadAcquire(xact.addr, UFix(trackerId)) //TODO io.master.acquire.bits.header.dst - io.master.acquire.bits.header.src := UFix(bankId) - io.master.acquire_data.valid := Bool(false) - io.master.acquire_data.bits.payload.data := UFix(0) + io.master.acquire.meta.bits.header.src := UFix(bankId) + io.master.acquire.data.valid := Bool(false) + io.master.acquire.data.bits.payload.data := UFix(0) //TODO io.master.acquire_data.bits.header.dst - io.master.acquire_data.bits.header := UFix(bankId) + io.master.acquire.data.bits.header := UFix(bankId) io.client.probe.valid := Bool(false) io.client.probe.bits.payload.p_type := co.getProbeType(xact.a_type, UFix(0)) io.client.probe.bits.payload.master_xact_id := UFix(trackerId) @@ -219,22 +216,22 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura io.client.grant.bits.header.dst := init_client_id_ io.client.grant.bits.header.src := UFix(bankId) io.client.grant.valid := (io.master.grant.valid && (UFix(trackerId) === io.master.grant.bits.payload.client_xact_id)) - io.client.acquire.ready := Bool(false) - io.client.acquire_data.ready := Bool(false) - io.client.release.ready := Bool(false) - io.client.release_data.ready := Bool(false) + io.client.acquire.meta.ready := Bool(false) + io.client.acquire.data.ready := Bool(false) + io.client.release.meta.ready := Bool(false) + io.client.release.data.ready := Bool(false) io.master.grant.ready := io.client.grant.ready io.client.grant_ack.valid := Bool(false) switch (state) { is(s_idle) { - io.client.acquire.ready := Bool(true) - when( io.client.acquire.valid ) { - xact := io.client.acquire.bits.payload - init_client_id_ := io.client.acquire.bits.header.src + io.client.acquire.meta.ready := Bool(true) + when( io.client.acquire.meta.valid ) { + xact := io.client.acquire.meta.bits.payload + init_client_id_ := io.client.acquire.meta.bits.header.src init_sharer_cnt_ := UFix(conf.ln.nClients) // TODO: Broadcast only - acquire_data_needs_write := co.messageHasData(io.client.acquire.bits.payload) - x_needs_read := co.needsOuterRead(io.client.acquire.bits.payload.a_type, UFix(0)) + acquire_data_needs_write := co.messageHasData(io.client.acquire.meta.bits.payload) + x_needs_read := co.needsOuterRead(io.client.acquire.meta.bits.payload.a_type, UFix(0)) probe_flags := probe_initial_flags mem_cnt := UFix(0) r_w_mem_cmd_sent := Bool(false) @@ -253,21 +250,20 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura when(io.client.probe.ready) { probe_flags := probe_flags & ~(UFixToOH(curr_p_id)) } - io.client.release.ready := Bool(true) - when(io.client.release.valid) { + io.client.release.meta.ready := Bool(true) + when(io.client.release.meta.valid) { if(conf.ln.nClients > 1) release_count := release_count - UFix(1) when(release_count === UFix(1)) { state := s_mem } - when( co.messageHasData(io.client.release.bits.payload)) { + when( co.messageHasData(io.client.release.meta.bits.payload)) { release_data_needs_write := Bool(true) - release_data_client_id := io.client.release.bits.header.src + release_data_client_id := io.client.release.meta.bits.header.src } } when (release_data_needs_write) { - doOuterReqWrite(io.master.acquire, - io.master.acquire_data, - io.client.release_data, + doOuterReqWrite(io.master.acquire, + io.client.release.data, release_data_needs_write, r_w_mem_cmd_sent, release_data_client_id) @@ -275,18 +271,16 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura } is(s_mem) { when (release_data_needs_write) { - doOuterReqWrite(io.master.acquire, - io.master.acquire_data, - io.client.release_data, - release_data_needs_write, - r_w_mem_cmd_sent, + doOuterReqWrite(io.master.acquire, + io.client.release.data, + release_data_needs_write, + r_w_mem_cmd_sent, release_data_client_id) } . elsewhen(acquire_data_needs_write) { - doOuterReqWrite(io.master.acquire, - io.master.acquire_data, - io.client.acquire_data, - acquire_data_needs_write, - a_w_mem_cmd_sent, + doOuterReqWrite(io.master.acquire, + io.client.acquire.data, + acquire_data_needs_write, + a_w_mem_cmd_sent, init_client_id_) } . elsewhen (x_needs_read) { doOuterReqRead(io.master.acquire, x_needs_read) @@ -313,18 +307,18 @@ abstract trait OuterRequestGenerator { val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES))) val mem_cnt_next = mem_cnt + UFix(1) - def doOuterReqWrite[T <: Data](master_acq: FIFOIO[LogicalNetworkIO[Acquire]], master_acq_data: FIFOIO[LogicalNetworkIO[AcquireData]], client_data: FIFOIO[LogicalNetworkIO[T]], trigger: Bool, cmd_sent: Bool, desired_client_data_src_id: UFix) { + def doOuterReqWrite[T <: HasMemData](master_acq: PairedDataIO[LogicalNetworkIO[Acquire],LogicalNetworkIO[AcquireData]], client_data: FIFOIO[LogicalNetworkIO[T]], trigger: Bool, cmd_sent: Bool, desired_client_data_src_id: UFix) { val do_write = client_data.valid && (client_data.bits.header.src === desired_client_data_src_id) - master_acq.bits.payload := cmd_to_write - master_acq_data.bits.payload := client_data.bits.payload - when(master_acq.ready && master_acq.valid) { + master_acq.meta.bits.payload := cmd_to_write + master_acq.data.bits.payload := client_data.bits.payload + when(master_acq.meta.fire()) { cmd_sent := Bool(true) } when (do_write) { - master_acq.valid := !cmd_sent && master_acq_data.ready - when (master_acq.ready || cmd_sent) { - master_acq_data.valid := client_data.valid - when(master_acq_data.ready) { + master_acq.meta.valid := !cmd_sent + when (master_acq.meta.ready || cmd_sent) { + master_acq.data.valid := client_data.valid + when(master_acq.data.ready) { client_data.ready:= Bool(true) mem_cnt := mem_cnt_next when(mem_cnt === UFix(REFILL_CYCLES-1)) { @@ -335,10 +329,10 @@ abstract trait OuterRequestGenerator { } } - def doOuterReqRead(master_acq: FIFOIO[LogicalNetworkIO[Acquire]], trigger: Bool) { - master_acq.valid := Bool(true) - master_acq.bits.payload := cmd_to_read - when(master_acq.ready) { + def doOuterReqRead(master_acq: PairedDataIO[LogicalNetworkIO[Acquire],LogicalNetworkIO[AcquireData]], trigger: Bool) { + master_acq.meta.valid := Bool(true) + master_acq.meta.bits.payload := cmd_to_read + when(master_acq.meta.ready) { trigger := Bool(false) } }