1
0

L2-specific metadataarray wrapper, hookups to tshrfile

This commit is contained in:
Henry Cook 2014-05-07 01:51:46 -07:00
parent bc3ef1011e
commit 0e39346a12

View File

@ -43,6 +43,7 @@ case class L2CacheConfig(
def rowoffbits = log2Up(rowbytes) def rowoffbits = log2Up(rowbytes)
def refillcycles = tl.dataBits/(rowbits) def refillcycles = tl.dataBits/(rowbits)
def statebits = log2Up(states) def statebits = log2Up(states)
def nTSHRs = nReleaseTransactions + nAcquireTransactions
require(states > 0) require(states > 0)
require(isPow2(sets)) require(isPow2(sets))
@ -60,6 +61,16 @@ abstract trait L2CacheBundle extends Bundle {
override def clone = this.getClass.getConstructors.head.newInstance(l2cacheconf).asInstanceOf[this.type] override def clone = this.getClass.getConstructors.head.newInstance(l2cacheconf).asInstanceOf[this.type]
} }
trait HasL2Id extends L2CacheBundle {
val id = UInt(width = log2Up(l2cacheconf.nTSHRs))
}
trait HasL2InternalRequestState extends L2CacheBundle {
val tag_match = Bool()
val old_meta = new L2MetaData
val way_en = Bits(width = l2cacheconf.ways)
}
abstract class ReplacementPolicy { abstract class ReplacementPolicy {
def way: UInt def way: UInt
def miss: Unit def miss: Unit
@ -80,20 +91,6 @@ abstract class MetaData(implicit val cacheconf: CacheConfig) extends CacheBundle
val tag = Bits(width = cacheconf.tagbits) val tag = Bits(width = cacheconf.tagbits)
} }
class L2MetaData(implicit val l2cacheconf: L2CacheConfig) extends MetaData
with L2CacheBundle {
val state = UInt(width = l2cacheconf.statebits)
val sharers = Bits(width = l2cacheconf.tl.ln.nClients)
}
/*
class L3MetaData(implicit conf: L3CacheConfig) extends MetaData()(conf) {
val cstate = UInt(width = cacheconf.cstatebits)
val mstate = UInt(width = cacheconf.mstatebits)
val sharers = Bits(width = cacheconf.tl.ln.nClients)
}
*/
class MetaReadReq(implicit val cacheconf: CacheConfig) extends CacheBundle { class MetaReadReq(implicit val cacheconf: CacheConfig) extends CacheBundle {
val idx = Bits(width = cacheconf.idxbits) val idx = Bits(width = cacheconf.idxbits)
} }
@ -137,49 +134,125 @@ class MetaDataArray[T <: MetaData](gen: () => T)(implicit conf: CacheConfig) ext
io.write.ready := !rst io.write.ready := !rst
} }
class L2DataReadReq(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle { object L2MetaData {
def apply(tag: Bits, state: UInt, sharers: UInt)(implicit conf: L2CacheConfig) = {
val meta = new L2MetaData
meta.tag := tag
meta.state := state
meta.sharers := sharers
meta
}
}
class L2MetaData(implicit val l2cacheconf: L2CacheConfig) extends MetaData
with L2CacheBundle {
val state = UInt(width = l2cacheconf.statebits)
val sharers = Bits(width = l2cacheconf.tl.ln.nClients)
}
/*
class L3MetaData(implicit conf: L3CacheConfig) extends MetaData()(conf) {
val cstate = UInt(width = cacheconf.cstatebits)
val mstate = UInt(width = cacheconf.mstatebits)
val sharers = Bits(width = cacheconf.tl.ln.nClients)
}
*/
class L2MetaReadReq(implicit val l2cacheconf: L2CacheConfig) extends MetaReadReq
with HasL2Id {
val tag = Bits(width = l2cacheconf.tagbits)
}
class L2MetaWriteReq(implicit val l2cacheconf: L2CacheConfig) extends MetaWriteReq[L2MetaData](new L2MetaData)
with HasL2Id
class L2MetaResp(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle
with HasL2Id
with HasL2InternalRequestState
class L2MetaDataArray(implicit conf: L2CacheConfig) extends Module {
implicit val tl = conf.tl
val io = new Bundle {
val read = Decoupled(new L2MetaReadReq).flip
val write = Decoupled(new L2MetaWriteReq).flip
val resp = Valid(new L2MetaResp)
}
val meta = Module(new MetaDataArray(() => L2MetaData(UInt(0), tl.co.newStateOnFlush, UInt(0))))
meta.io.read <> io.read
meta.io.write <> io.write
val s1_clk_en = Reg(next = io.read.fire())
val s1_tag = RegEnable(io.read.bits.tag, io.read.valid)
val s1_id = RegEnable(io.read.bits.id, io.read.valid)
def wayMap[T <: Data](f: Int => T) = Vec((0 until conf.ways).map(f))
val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === s1_tag)
val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && tl.co.isValid(meta.io.resp(w).state)).toBits
val s2_tag_match_way = RegEnable(s1_tag_match_way, s1_clk_en)
val s2_tag_match = s2_tag_match_way.orR
val s2_hit_state = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEnable(meta.io.resp(w).state, s1_clk_en)))
val s2_hit_sharers = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEnable(meta.io.resp(w).sharers, s1_clk_en)))
val replacer = new RandomReplacement
val s1_replaced_way_en = UIntToOH(replacer.way)
val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en))
val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) =>
RegEnable(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq)
io.resp.valid := Reg(next = s1_clk_en)
io.resp.bits.id := RegEnable(s1_id, s1_clk_en)
io.resp.bits.tag_match := s2_tag_match
io.resp.bits.old_meta := Mux(s2_tag_match,
L2MetaData(s2_repl_meta.tag, s2_hit_state, s2_hit_sharers),
s2_repl_meta)
io.resp.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
}
class L2DataReadReq(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle
with HasL2Id {
val way_en = Bits(width = l2cacheconf.ways) val way_en = Bits(width = l2cacheconf.ways)
val addr = Bits(width = l2cacheconf.tl.addrBits) val addr = Bits(width = l2cacheconf.tl.addrBits)
} }
class L2DataWriteReq(implicit conf: L2CacheConfig) extends L2DataReadReq()(conf) { class L2DataWriteReq(implicit l2cacheconf: L2CacheConfig) extends L2DataReadReq {
val wmask = Bits(width = conf.tl.writeMaskBits) val wmask = Bits(width = l2cacheconf.tl.writeMaskBits)
val data = Bits(width = conf.tl.dataBits) val data = Bits(width = l2cacheconf.tl.dataBits)
}
class L2DataResp(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle
with HasL2Id {
val data = Bits(width = l2cacheconf.tl.dataBits)
} }
class L2DataArray(implicit conf: L2CacheConfig) extends Module { class L2DataArray(implicit conf: L2CacheConfig) extends Module {
val io = new Bundle { val io = new Bundle {
val read = Decoupled(new L2DataReadReq).flip val read = Decoupled(new L2DataReadReq).flip
val write = Decoupled(new L2DataWriteReq).flip val write = Decoupled(new L2DataWriteReq).flip
val resp = Vec.fill(conf.ways){Bits(OUTPUT, conf.tl.dataBits)} val resp = Valid(new L2DataResp)
} }
val waddr = io.write.bits.addr val waddr = io.write.bits.addr
val raddr = io.read.bits.addr val raddr = io.read.bits.addr
val wmask = FillInterleaved(conf.wordbits, io.write.bits.wmask) val wmask = FillInterleaved(conf.wordbits, io.write.bits.wmask)
for (w <- 0 until conf.ways) { val resp = (0 until conf.ways).map { w =>
val array = Mem(Bits(width=conf.rowbits), conf.sets*conf.refillcycles, seqRead = true) val array = Mem(Bits(width=conf.rowbits), conf.sets*conf.refillcycles, seqRead = true)
when (io.write.bits.way_en(w) && io.write.valid) { when (io.write.bits.way_en(w) && io.write.valid) {
array.write(waddr, io.write.bits.data, wmask) array.write(waddr, io.write.bits.data, wmask)
} }
io.resp(w) := array(RegEnable(raddr, io.read.bits.way_en(w) && io.read.valid)) array(RegEnable(raddr, io.read.bits.way_en(w) && io.read.valid))
} }
io.resp.valid := ShiftRegister(io.read.valid, 2)
io.resp.bits.id := ShiftRegister(io.read.bits.id, 2)
io.resp.bits.data := Mux1H(ShiftRegister(io.read.bits.way_en, 2), resp)
io.read.ready := Bool(true) io.read.ready := Bool(true)
io.write.ready := Bool(true) io.write.ready := Bool(true)
} }
trait L2InternalRequestState extends L2CacheBundle {
val tag_match = Bool()
val old_meta = new L2MetaData
val way_en = Bits(width = l2cacheconf.ways)
}
class L2InternalAcquire(implicit val l2cacheconf: L2CacheConfig) extends Acquire()(l2cacheconf.tl) class L2InternalAcquire(implicit val l2cacheconf: L2CacheConfig) extends Acquire()(l2cacheconf.tl)
with L2InternalRequestState with HasL2InternalRequestState
class L2InternalRelease(implicit val l2cacheconf: L2CacheConfig) extends Release()(l2cacheconf.tl) class L2InternalRelease(implicit val l2cacheconf: L2CacheConfig) extends Release()(l2cacheconf.tl)
with L2InternalRequestState with HasL2InternalRequestState
class InternalTileLinkIO(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle { class InternalTileLinkIO(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle {
implicit val (tl, ln) = (l2cacheconf.tl, l2cacheconf.tl.ln) implicit val (tl, ln) = (l2cacheconf.tl, l2cacheconf.tl.ln)
@ -194,23 +267,16 @@ class L2HellaCache(bankId: Int)(implicit conf: L2CacheConfig) extends CoherenceA
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
val tshrfile = Module(new TSHRFile(bankId)) val tshrfile = Module(new TSHRFile(bankId))
val meta = Module(new L2MetaDataArray)
// tags
val meta = Module(new MetaDataArray(() => new L2MetaData))
// data
val data = Module(new L2DataArray) val data = Module(new L2DataArray)
// replacement policy
val replacer = new RandomReplacement
/*
val s1_replaced_way_en = UIntToOH(replacer.way)
val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en))
val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) =>
RegEnable(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq)
*/
tshrfile.io.inner <> io.inner tshrfile.io.inner <> io.inner
tshrfile.io.meta_read <> meta.io.read
tshrfile.io.meta_write <> meta.io.write
tshrfile.io.meta_resp <> meta.io.resp
tshrfile.io.data_read <> data.io.read
tshrfile.io.data_write <> data.io.write
tshrfile.io.data_resp <> data.io.resp
io.outer <> tshrfile.io.outer io.outer <> tshrfile.io.outer
io.incoherent <> tshrfile.io.incoherent io.incoherent <> tshrfile.io.incoherent
} }
@ -219,19 +285,31 @@ class L2HellaCache(bankId: Int)(implicit conf: L2CacheConfig) extends CoherenceA
class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module { class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
val io = new Bundle { val io = new Bundle {
val inner = (new InternalTileLinkIO).flip val inner = (new TileLinkIO).flip
val outer = new UncachedTileLinkIO val outer = new UncachedTileLinkIO
val incoherent = Vec.fill(ln.nClients){Bool()}.asInput val incoherent = Vec.fill(ln.nClients){Bool()}.asInput
val meta_read_req = Decoupled(new MetaReadReq) val meta_read = Decoupled(new L2MetaReadReq)
val meta_write_req = Decoupled(new MetaWriteReq(new L2MetaData)) val meta_write = Decoupled(new L2MetaWriteReq)
val data_read_req = Decoupled(new L2DataReadReq) val meta_resp = Valid(new L2MetaResp).flip
val data_write_req = Decoupled(new L2DataWriteReq) val data_read = Decoupled(new L2DataReadReq)
val data_write = Decoupled(new L2DataWriteReq)
val data_resp = Valid(new L2DataResp).flip
}
// Wiring helper funcs
def doOutputArbitration[T <: Data](out: DecoupledIO[T], ins: Seq[DecoupledIO[T]]) {
val arb = Module(new RRArbiter(out.bits.clone, ins.size))
out <> arb.io.out
arb.io.in zip ins map { case (a, i) => a <> i }
} }
// Create TSHRs for outstanding transactions // Create TSHRs for outstanding transactions
val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions
val trackerList = (0 until conf.nReleaseTransactions).map(id => Module(new L2VoluntaryReleaseTracker(id, bankId))) ++ val trackerList = (0 until conf.nReleaseTransactions).map { id =>
(conf.nReleaseTransactions until nTrackers).map(id => Module(new L2AcquireTracker(id, bankId))) Module(new L2VoluntaryReleaseTracker(id, bankId))
} ++ (conf.nReleaseTransactions until nTrackers).map { id =>
Module(new L2AcquireTracker(id, bankId))
}
// Propagate incoherence flags // Propagate incoherence flags
trackerList.map(_.io.tile_incoherent := io.incoherent.toBits) trackerList.map(_.io.tile_incoherent := io.incoherent.toBits)
@ -251,10 +329,11 @@ class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module {
acquire.ready := trackerList.map(_.io.inner.acquire.ready).reduce(_||_) && !block_acquires acquire.ready := trackerList.map(_.io.inner.acquire.ready).reduce(_||_) && !block_acquires
alloc_arb.io.out.ready := acquire.valid && !block_acquires alloc_arb.io.out.ready := acquire.valid && !block_acquires
// Handle probe request generation // Handle probe requests
val probe_arb = Module(new Arbiter(new LogicalNetworkIO(new Probe), trackerList.size)) doOutputArbitration(io.inner.probe, trackerList.map(_.io.inner.probe))
io.inner.probe <> probe_arb.io.out //val probe_arb = Module(new Arbiter(new LogicalNetworkIO(new Probe), trackerList.size))
probe_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.inner.probe } //io.inner.probe <> probe_arb.io.out
//probe_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.inner.probe }
// Handle releases, which might be voluntary and might have data // Handle releases, which might be voluntary and might have data
val release = io.inner.release val release = io.inner.release
@ -272,9 +351,10 @@ class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module {
release.ready := Vec(trackerList.map(_.io.inner.release.ready)).read(release_idx) && !block_releases release.ready := Vec(trackerList.map(_.io.inner.release.ready)).read(release_idx) && !block_releases
// Reply to initial requestor // Reply to initial requestor
val grant_arb = Module(new Arbiter(new LogicalNetworkIO(new Grant), trackerList.size)) doOutputArbitration(io.inner.grant, trackerList.map(_.io.inner.grant))
io.inner.grant <> grant_arb.io.out //val grant_arb = Module(new Arbiter(new LogicalNetworkIO(new Grant), trackerList.size))
grant_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.inner.grant } //io.inner.grant <> grant_arb.io.out
//grant_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.inner.grant }
// Free finished transactions // Free finished transactions
val ack = io.inner.finish val ack = io.inner.finish
@ -282,21 +362,35 @@ class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module {
trackerList.map(_.io.inner.finish.bits := ack.bits) trackerList.map(_.io.inner.finish.bits := ack.bits)
ack.ready := Bool(true) ack.ready := Bool(true)
// Create an arbiter for the one memory port // Arbitrate for the outer memory port
val outer_arb = Module(new UncachedTileLinkIOArbiterThatPassesId(trackerList.size)) val outer_arb = Module(new UncachedTileLinkIOArbiterThatPassesId(trackerList.size))
outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.outer } outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.outer }
io.outer <> outer_arb.io.out io.outer <> outer_arb.io.out
// Local memory
doOutputArbitration(io.meta_read, trackerList.map(_.io.meta_read))
doOutputArbitration(io.meta_write, trackerList.map(_.io.meta_write))
doOutputArbitration(io.data_read, trackerList.map(_.io.data_read))
doOutputArbitration(io.data_write, trackerList.map(_.io.data_write))
} }
abstract class L2XactTracker()(implicit conf: L2CacheConfig) extends Module { abstract class L2XactTracker()(implicit conf: L2CacheConfig) extends Module {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
val io = new Bundle { val io = new Bundle {
val inner = (new InternalTileLinkIO).flip val inner = (new TileLinkIO).flip
val outer = new UncachedTileLinkIO val outer = new UncachedTileLinkIO
val tile_incoherent = Bits(INPUT, ln.nClients) val tile_incoherent = Bits(INPUT, ln.nClients)
val has_acquire_conflict = Bool(OUTPUT) val has_acquire_conflict = Bool(OUTPUT)
val has_release_conflict = Bool(OUTPUT) val has_release_conflict = Bool(OUTPUT)
val meta_read = Decoupled(new L2MetaReadReq)
val meta_write = Decoupled(new L2MetaWriteReq)
val meta_resp = Valid(new L2MetaResp).flip
val data_read = Decoupled(new L2DataReadReq)
val data_write = Decoupled(new L2DataWriteReq)
val data_resp = Valid(new L2DataResp).flip
} }
val c_acq = io.inner.acquire.bits val c_acq = io.inner.acquire.bits