added PairedData link type with matching crossbar, ported tilelink and uncore to use
This commit is contained in:
parent
9a3b2e7006
commit
4c1f105ce9
@ -3,9 +3,9 @@ package uncore
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Constants._
|
import Constants._
|
||||||
|
|
||||||
trait CoherenceAgentRole
|
abstract trait CoherenceAgentRole
|
||||||
trait ClientCoherenceAgent extends CoherenceAgentRole
|
abstract trait ClientCoherenceAgent extends CoherenceAgentRole
|
||||||
trait MasterCoherenceAgent extends CoherenceAgentRole
|
abstract trait MasterCoherenceAgent extends CoherenceAgentRole
|
||||||
|
|
||||||
abstract class CoherencePolicy {
|
abstract class CoherencePolicy {
|
||||||
def isHit (cmd: Bits, state: UFix): Bool
|
def isHit (cmd: Bits, state: UFix): Bool
|
||||||
|
@ -9,8 +9,9 @@ import scala.collection.mutable.Stack
|
|||||||
implicit def toOption[A](a: A) = Option(a)
|
implicit def toOption[A](a: A) = Option(a)
|
||||||
|
|
||||||
class PairedDataIO[M <: Data, D <: Data]()(m: => M, d: => D) extends Bundle {
|
class PairedDataIO[M <: Data, D <: Data]()(m: => M, d: => D) extends Bundle {
|
||||||
val meta = (new FIFOIO()){ m }
|
val meta = new FIFOIO()(m)
|
||||||
val data = (new FIFOIO()){ d }
|
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 {
|
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 out = new PairedDataIO()(m,d)
|
||||||
val meta_chosen = Bits(OUTPUT, log2Up(n))
|
val meta_chosen = Bits(OUTPUT, log2Up(n))
|
||||||
val data_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))
|
require(isPow2(count))
|
||||||
val io = new PairedArbiterIO(n)(meta,data)
|
val io = new PairedArbiterIO(n)(meta,data)
|
||||||
val locked = if(count > 1) Reg(resetVal = Bool(false)) else Bool(false)
|
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 grant = List.fill(n)(Bool())
|
||||||
val meta_chosen = Bits(width = log2Up(n))
|
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))
|
val chosen_meta_has_data = needsLock.map(_(io.in(meta_chosen).meta.bits)).getOrElse(Bool(true))
|
||||||
(0 until n).map(i => io.in(i).meta.ready := grant(i) && io.out.meta.ready)
|
val valid_meta_has_data = io.in(meta_chosen).meta.valid && chosen_meta_has_data
|
||||||
(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)
|
val grant_chosen_meta = !(locked && chosen_meta_has_data)
|
||||||
io.out.meta.valid := io.in(meta_chosen).meta.valid
|
(0 until n).map(i => io.in(i).meta.ready := grant(i) && grant_chosen_meta && io.out.meta.ready)
|
||||||
io.out.data.valid := Mux(locked, io.in(lockIdx).data.valid, io.in(meta_chosen).data.valid && chosen_meta_has_data)
|
(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.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.out.data.bits := Mux(locked, io.in(lockIdx).data.bits, io.in(meta_chosen).data.bits)
|
||||||
io.meta_chosen := meta_chosen
|
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 }
|
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)
|
case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int)
|
||||||
|
|
||||||
class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
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
|
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 io = new Bundle {
|
||||||
val in = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}}.flip
|
val in = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}}.flip
|
||||||
val out = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}}
|
val out = Vec(conf.nEndpoints){(new FIFOIO){(new BasicCrossbarIO){data}}}
|
||||||
|
@ -116,82 +116,55 @@ class Grant extends MasterSourcedMessage with HasMemData with HasClientTransacti
|
|||||||
|
|
||||||
class GrantAck extends ClientSourcedMessage with HasMasterTransactionId
|
class GrantAck extends ClientSourcedMessage with HasMasterTransactionId
|
||||||
|
|
||||||
abstract class DirectionalFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data)
|
trait DirectionalIO
|
||||||
class ClientSourcedIO[T <: Data]()(data: => T) extends DirectionalFIFOIO()(data)
|
trait ClientSourcedIO extends DirectionalIO
|
||||||
class ClientSourcedDataIO[T <: Data]()(data: => T) extends ClientSourcedIO()(data)
|
trait MasterSourcedIO extends DirectionalIO
|
||||||
class MasterSourcedIO[T <: Data]()(data: => T) extends DirectionalFIFOIO()(data) {flip()}
|
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 {
|
class UncachedTileLinkIO(implicit conf: LogicalNetworkConfiguration) extends Bundle {
|
||||||
val acquire = (new ClientSourcedIO){(new LogicalNetworkIO){new Acquire }}
|
val acquire = new ClientSourcedDataIO()(new LogicalNetworkIO()(new Acquire), new LogicalNetworkIO()(new AcquireData))
|
||||||
val acquire_data = (new ClientSourcedDataIO){(new LogicalNetworkIO){new AcquireData }}
|
val grant = new MasterSourcedFIFOIO()(new LogicalNetworkIO()(new Grant))
|
||||||
val grant = (new MasterSourcedIO) {(new LogicalNetworkIO){new Grant }}
|
val grant_ack = new ClientSourcedFIFOIO()(new LogicalNetworkIO()(new GrantAck))
|
||||||
val grant_ack = (new ClientSourcedIO){(new LogicalNetworkIO){new GrantAck }}
|
|
||||||
override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] }
|
override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
class TileLinkIO(implicit conf: LogicalNetworkConfiguration) extends UncachedTileLinkIO()(conf) {
|
class TileLinkIO(implicit conf: LogicalNetworkConfiguration) extends UncachedTileLinkIO()(conf) {
|
||||||
val probe = (new MasterSourcedIO){(new LogicalNetworkIO){new Probe }}
|
val probe = new MasterSourcedFIFOIO()(new LogicalNetworkIO()(new Probe))
|
||||||
val release = (new ClientSourcedIO){(new LogicalNetworkIO){new Release }}
|
val release = new ClientSourcedDataIO()(new LogicalNetworkIO()(new Release), new LogicalNetworkIO()(new ReleaseData))
|
||||||
val release_data = (new ClientSourcedDataIO){(new LogicalNetworkIO){new ReleaseData }}
|
|
||||||
override def clone = { new TileLinkIO().asInstanceOf[this.type] }
|
override def clone = { new TileLinkIO().asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
object UncachedTileLinkIOArbiterShim {
|
class UncachedTileLinkIOArbiter(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Component {
|
||||||
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 {
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Vec(n) { new UncachedTileLinkIO }.flip
|
val in = Vec(n) { new UncachedTileLinkIO }.flip
|
||||||
val out = new UncachedTileLinkIO
|
val out = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
|
|
||||||
val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES)))
|
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
||||||
val mem_cnt_next = mem_cnt + UFix(1)
|
val acq_arb = new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData})
|
||||||
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} }
|
|
||||||
io.out.acquire <> acq_arb.io.out
|
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
|
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 }
|
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
||||||
|
|
||||||
|
@ -31,23 +31,22 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: UncoreConfiguration) extends
|
|||||||
|
|
||||||
// Handle acquire transaction initiation
|
// Handle acquire transaction initiation
|
||||||
val acquire = io.client.acquire
|
val acquire = io.client.acquire
|
||||||
val acquire_data = io.client.acquire_data
|
|
||||||
val any_acquire_conflict = trackerList.map(_.io.has_acquire_conflict).reduce(_||_)
|
val any_acquire_conflict = trackerList.map(_.io.has_acquire_conflict).reduce(_||_)
|
||||||
val block_acquires = any_acquire_conflict
|
val block_acquires = any_acquire_conflict
|
||||||
|
|
||||||
val alloc_arb = (new Arbiter(trackerList.size)) { Bool() }
|
val alloc_arb = (new Arbiter(trackerList.size)) { Bool() }
|
||||||
for( i <- 0 until trackerList.size ) {
|
for( i <- 0 until trackerList.size ) {
|
||||||
val t = trackerList(i).io.client
|
val t = trackerList(i).io.client
|
||||||
alloc_arb.io.in(i).valid := t.acquire.ready
|
alloc_arb.io.in(i).valid := t.acquire.meta.ready
|
||||||
t.acquire.bits := acquire.bits
|
t.acquire.meta.bits := acquire.meta.bits
|
||||||
t.acquire.valid := alloc_arb.io.in(i).ready
|
t.acquire.meta.valid := alloc_arb.io.in(i).ready
|
||||||
|
|
||||||
t.acquire_data.bits := acquire_data.bits
|
t.acquire.data.bits := acquire.data.bits
|
||||||
t.acquire_data.valid := acquire_data.valid
|
t.acquire.data.valid := acquire.data.valid
|
||||||
}
|
}
|
||||||
acquire.ready := trackerList.map(_.io.client.acquire.ready).reduce(_||_) && !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(_||_)
|
acquire.data.ready := trackerList.map(_.io.client.acquire.data.ready).reduce(_||_)
|
||||||
alloc_arb.io.out.ready := acquire.valid && !block_acquires
|
alloc_arb.io.out.ready := acquire.meta.valid && !block_acquires
|
||||||
|
|
||||||
// Handle probe request generation
|
// Handle probe request generation
|
||||||
val probe_arb = (new Arbiter(trackerList.size)){(new LogicalNetworkIO){ new Probe }}
|
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
|
// Handle releases, which might be voluntary and might have data
|
||||||
val release = io.client.release
|
val release = io.client.release
|
||||||
val release_data = io.client.release_data
|
val voluntary = co.isVoluntary(release.meta.bits.payload)
|
||||||
val voluntary = co.isVoluntary(release.bits.payload)
|
|
||||||
val any_release_conflict = trackerList.tail.map(_.io.has_release_conflict).reduce(_||_)
|
val any_release_conflict = trackerList.tail.map(_.io.has_release_conflict).reduce(_||_)
|
||||||
val block_releases = Bool(false)
|
val block_releases = Bool(false)
|
||||||
val conflict_idx = Vec(trackerList.map(_.io.has_release_conflict)){Bool()}.lastIndexWhere{b: Bool => b}
|
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, 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 ) {
|
for( i <- 0 until trackerList.size ) {
|
||||||
val t = trackerList(i).io.client
|
val t = trackerList(i).io.client
|
||||||
t.release.bits := release.bits
|
t.release.meta.bits := release.meta.bits
|
||||||
t.release.valid := release.valid && (release_idx === UFix(i)) && !block_releases
|
t.release.meta.valid := release.meta.valid && (release_idx === UFix(i)) && !block_releases
|
||||||
t.release_data.bits := release_data.bits
|
t.release.data.bits := release.data.bits
|
||||||
t.release_data.valid := release_data.valid
|
t.release.data.valid := release.data.valid
|
||||||
}
|
}
|
||||||
release.ready := Vec(trackerList.map(_.io.client.release.ready)){Bool()}(release_idx) && !block_releases
|
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(_||_)
|
release.data.ready := trackerList.map(_.io.client.release.data.ready).reduce(_||_)
|
||||||
|
|
||||||
// Reply to initial requestor
|
// Reply to initial requestor
|
||||||
val grant_arb = (new Arbiter(trackerList.size)){(new LogicalNetworkIO){ new Grant }}
|
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)
|
ack.ready := Bool(true)
|
||||||
|
|
||||||
// Create an arbiter for the one memory port
|
// 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 }
|
outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.master }
|
||||||
io.master <> outer_arb.io.out
|
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))
|
val cmd_to_read = co.getUncachedReadAcquire(xact.addr, UFix(trackerId))
|
||||||
|
|
||||||
io.has_acquire_conflict := Bool(false)
|
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.grant.ready := Bool(false)
|
||||||
io.master.acquire.valid := Bool(false)
|
io.master.acquire.meta.valid := Bool(false)
|
||||||
io.master.acquire.bits.payload := cmd_to_write
|
io.master.acquire.meta.bits.payload := cmd_to_write
|
||||||
//TODO io.master.acquire.bits.header.dst
|
//TODO io.master.acquire.bits.header.dst
|
||||||
io.master.acquire.bits.header.src := UFix(bankId)
|
io.master.acquire.meta.bits.header.src := UFix(bankId)
|
||||||
io.master.acquire_data.valid := Bool(false)
|
io.master.acquire.data.valid := Bool(false)
|
||||||
io.master.acquire_data.bits.payload.data := UFix(0)
|
io.master.acquire.data.bits.payload.data := UFix(0)
|
||||||
//TODO io.master.acquire_data.bits.header.dst
|
//TODO io.master.acquire_data.bits.header.dst
|
||||||
io.master.acquire_data.bits.header.src := UFix(bankId)
|
io.master.acquire.data.bits.header.src := UFix(bankId)
|
||||||
io.client.acquire.ready := Bool(false)
|
io.client.acquire.meta.ready := Bool(false)
|
||||||
io.client.acquire_data.ready := Bool(false)
|
io.client.acquire.data.ready := Bool(false)
|
||||||
io.client.probe.valid := Bool(false)
|
io.client.probe.valid := Bool(false)
|
||||||
io.client.release.ready := Bool(false)
|
io.client.release.meta.ready := Bool(false)
|
||||||
io.client.release_data.ready := Bool(false) // DNC
|
io.client.release.data.ready := Bool(false) // DNC
|
||||||
io.client.grant.valid := Bool(false)
|
io.client.grant.valid := Bool(false)
|
||||||
io.client.grant.bits.payload.g_type := co.getGrantType(xact, UFix(0))
|
io.client.grant.bits.payload.g_type := co.getGrantType(xact, UFix(0))
|
||||||
io.client.grant.bits.payload.client_xact_id := xact.client_xact_id
|
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) {
|
switch (state) {
|
||||||
is(s_idle) {
|
is(s_idle) {
|
||||||
io.client.release.ready := Bool(true)
|
io.client.release.meta.ready := Bool(true)
|
||||||
when( io.client.release.valid ) {
|
when( io.client.release.meta.valid ) {
|
||||||
xact := io.client.release.bits.payload
|
xact := io.client.release.meta.bits.payload
|
||||||
init_client_id_ := io.client.release.bits.header.src
|
init_client_id_ := io.client.release.meta.bits.header.src
|
||||||
release_data_needs_write := co.messageHasData(io.client.release.bits.payload)
|
release_data_needs_write := co.messageHasData(io.client.release.meta.bits.payload)
|
||||||
mem_cnt := UFix(0)
|
mem_cnt := UFix(0)
|
||||||
mem_cmd_sent := Bool(false)
|
mem_cmd_sent := Bool(false)
|
||||||
state := s_mem
|
state := s_mem
|
||||||
@ -153,10 +151,9 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: Uncore
|
|||||||
}
|
}
|
||||||
is(s_mem) {
|
is(s_mem) {
|
||||||
when (release_data_needs_write) {
|
when (release_data_needs_write) {
|
||||||
doOuterReqWrite(io.master.acquire,
|
doOuterReqWrite(io.master.acquire,
|
||||||
io.master.acquire_data,
|
io.client.release.data,
|
||||||
io.client.release_data,
|
release_data_needs_write,
|
||||||
release_data_needs_write,
|
|
||||||
mem_cmd_sent,
|
mem_cmd_sent,
|
||||||
init_client_id_)
|
init_client_id_)
|
||||||
} . otherwise { state := s_ack }
|
} . otherwise { state := s_ack }
|
||||||
@ -192,20 +189,20 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura
|
|||||||
if (conf.ln.nClients > 1) {
|
if (conf.ln.nClients > 1) {
|
||||||
// issue self-probes for uncached read xacts to facilitate I$ coherence
|
// issue self-probes for uncached read xacts to facilitate I$ coherence
|
||||||
val probe_self = Bool(true) //co.needsSelfProbe(io.client.acquire.bits.payload)
|
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)
|
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_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.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.valid := Bool(false)
|
io.master.acquire.meta.valid := Bool(false)
|
||||||
io.master.acquire.bits.payload := co.getUncachedReadAcquire(xact.addr, UFix(trackerId))
|
io.master.acquire.meta.bits.payload := co.getUncachedReadAcquire(xact.addr, UFix(trackerId))
|
||||||
//TODO io.master.acquire.bits.header.dst
|
//TODO io.master.acquire.bits.header.dst
|
||||||
io.master.acquire.bits.header.src := UFix(bankId)
|
io.master.acquire.meta.bits.header.src := UFix(bankId)
|
||||||
io.master.acquire_data.valid := Bool(false)
|
io.master.acquire.data.valid := Bool(false)
|
||||||
io.master.acquire_data.bits.payload.data := UFix(0)
|
io.master.acquire.data.bits.payload.data := UFix(0)
|
||||||
//TODO io.master.acquire_data.bits.header.dst
|
//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.valid := Bool(false)
|
||||||
io.client.probe.bits.payload.p_type := co.getProbeType(xact.a_type, UFix(0))
|
io.client.probe.bits.payload.p_type := co.getProbeType(xact.a_type, UFix(0))
|
||||||
io.client.probe.bits.payload.master_xact_id := UFix(trackerId)
|
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.dst := init_client_id_
|
||||||
io.client.grant.bits.header.src := UFix(bankId)
|
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.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.meta.ready := Bool(false)
|
||||||
io.client.acquire_data.ready := Bool(false)
|
io.client.acquire.data.ready := Bool(false)
|
||||||
io.client.release.ready := Bool(false)
|
io.client.release.meta.ready := Bool(false)
|
||||||
io.client.release_data.ready := Bool(false)
|
io.client.release.data.ready := Bool(false)
|
||||||
io.master.grant.ready := io.client.grant.ready
|
io.master.grant.ready := io.client.grant.ready
|
||||||
io.client.grant_ack.valid := Bool(false)
|
io.client.grant_ack.valid := Bool(false)
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
is(s_idle) {
|
is(s_idle) {
|
||||||
io.client.acquire.ready := Bool(true)
|
io.client.acquire.meta.ready := Bool(true)
|
||||||
when( io.client.acquire.valid ) {
|
when( io.client.acquire.meta.valid ) {
|
||||||
xact := io.client.acquire.bits.payload
|
xact := io.client.acquire.meta.bits.payload
|
||||||
init_client_id_ := io.client.acquire.bits.header.src
|
init_client_id_ := io.client.acquire.meta.bits.header.src
|
||||||
init_sharer_cnt_ := UFix(conf.ln.nClients) // TODO: Broadcast only
|
init_sharer_cnt_ := UFix(conf.ln.nClients) // TODO: Broadcast only
|
||||||
acquire_data_needs_write := co.messageHasData(io.client.acquire.bits.payload)
|
acquire_data_needs_write := co.messageHasData(io.client.acquire.meta.bits.payload)
|
||||||
x_needs_read := co.needsOuterRead(io.client.acquire.bits.payload.a_type, UFix(0))
|
x_needs_read := co.needsOuterRead(io.client.acquire.meta.bits.payload.a_type, UFix(0))
|
||||||
probe_flags := probe_initial_flags
|
probe_flags := probe_initial_flags
|
||||||
mem_cnt := UFix(0)
|
mem_cnt := UFix(0)
|
||||||
r_w_mem_cmd_sent := Bool(false)
|
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) {
|
when(io.client.probe.ready) {
|
||||||
probe_flags := probe_flags & ~(UFixToOH(curr_p_id))
|
probe_flags := probe_flags & ~(UFixToOH(curr_p_id))
|
||||||
}
|
}
|
||||||
io.client.release.ready := Bool(true)
|
io.client.release.meta.ready := Bool(true)
|
||||||
when(io.client.release.valid) {
|
when(io.client.release.meta.valid) {
|
||||||
if(conf.ln.nClients > 1) release_count := release_count - UFix(1)
|
if(conf.ln.nClients > 1) release_count := release_count - UFix(1)
|
||||||
when(release_count === UFix(1)) {
|
when(release_count === UFix(1)) {
|
||||||
state := s_mem
|
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_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) {
|
when (release_data_needs_write) {
|
||||||
doOuterReqWrite(io.master.acquire,
|
doOuterReqWrite(io.master.acquire,
|
||||||
io.master.acquire_data,
|
io.client.release.data,
|
||||||
io.client.release_data,
|
|
||||||
release_data_needs_write,
|
release_data_needs_write,
|
||||||
r_w_mem_cmd_sent,
|
r_w_mem_cmd_sent,
|
||||||
release_data_client_id)
|
release_data_client_id)
|
||||||
@ -275,18 +271,16 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura
|
|||||||
}
|
}
|
||||||
is(s_mem) {
|
is(s_mem) {
|
||||||
when (release_data_needs_write) {
|
when (release_data_needs_write) {
|
||||||
doOuterReqWrite(io.master.acquire,
|
doOuterReqWrite(io.master.acquire,
|
||||||
io.master.acquire_data,
|
io.client.release.data,
|
||||||
io.client.release_data,
|
release_data_needs_write,
|
||||||
release_data_needs_write,
|
r_w_mem_cmd_sent,
|
||||||
r_w_mem_cmd_sent,
|
|
||||||
release_data_client_id)
|
release_data_client_id)
|
||||||
} . elsewhen(acquire_data_needs_write) {
|
} . elsewhen(acquire_data_needs_write) {
|
||||||
doOuterReqWrite(io.master.acquire,
|
doOuterReqWrite(io.master.acquire,
|
||||||
io.master.acquire_data,
|
io.client.acquire.data,
|
||||||
io.client.acquire_data,
|
acquire_data_needs_write,
|
||||||
acquire_data_needs_write,
|
a_w_mem_cmd_sent,
|
||||||
a_w_mem_cmd_sent,
|
|
||||||
init_client_id_)
|
init_client_id_)
|
||||||
} . elsewhen (x_needs_read) {
|
} . elsewhen (x_needs_read) {
|
||||||
doOuterReqRead(io.master.acquire, 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 = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES)))
|
||||||
val mem_cnt_next = mem_cnt + UFix(1)
|
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)
|
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.meta.bits.payload := cmd_to_write
|
||||||
master_acq_data.bits.payload := client_data.bits.payload
|
master_acq.data.bits.payload := client_data.bits.payload
|
||||||
when(master_acq.ready && master_acq.valid) {
|
when(master_acq.meta.fire()) {
|
||||||
cmd_sent := Bool(true)
|
cmd_sent := Bool(true)
|
||||||
}
|
}
|
||||||
when (do_write) {
|
when (do_write) {
|
||||||
master_acq.valid := !cmd_sent && master_acq_data.ready
|
master_acq.meta.valid := !cmd_sent
|
||||||
when (master_acq.ready || cmd_sent) {
|
when (master_acq.meta.ready || cmd_sent) {
|
||||||
master_acq_data.valid := client_data.valid
|
master_acq.data.valid := client_data.valid
|
||||||
when(master_acq_data.ready) {
|
when(master_acq.data.ready) {
|
||||||
client_data.ready:= Bool(true)
|
client_data.ready:= Bool(true)
|
||||||
mem_cnt := mem_cnt_next
|
mem_cnt := mem_cnt_next
|
||||||
when(mem_cnt === UFix(REFILL_CYCLES-1)) {
|
when(mem_cnt === UFix(REFILL_CYCLES-1)) {
|
||||||
@ -335,10 +329,10 @@ abstract trait OuterRequestGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def doOuterReqRead(master_acq: FIFOIO[LogicalNetworkIO[Acquire]], trigger: Bool) {
|
def doOuterReqRead(master_acq: PairedDataIO[LogicalNetworkIO[Acquire],LogicalNetworkIO[AcquireData]], trigger: Bool) {
|
||||||
master_acq.valid := Bool(true)
|
master_acq.meta.valid := Bool(true)
|
||||||
master_acq.bits.payload := cmd_to_read
|
master_acq.meta.bits.payload := cmd_to_read
|
||||||
when(master_acq.ready) {
|
when(master_acq.meta.ready) {
|
||||||
trigger := Bool(false)
|
trigger := Bool(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user