提交 411c28b9 编写于 作者: Z zhanglinjuan

DCache: add pseudo LRU replacement policy for dcache

上级 1fad9afd
......@@ -216,6 +216,7 @@ trait HasXSParameter {
val dcacheParameters = DCacheParameters(
tagECC = Some("secded"),
dataECC = Some("secded"),
replacer = Some("setplru"),
nMissEntries = 16,
nProbeEntries = 16,
nReleaseEntries = 16,
......
......@@ -3,7 +3,7 @@ package xiangshan.cache
import chisel3._
import chisel3.util._
import freechips.rocketchip.tilelink.{ClientMetadata, TLClientParameters, TLEdgeOut}
import utils.{Code, RandomReplacement, XSDebug, SRAMTemplate, ParallelOR}
import utils.{Code, ReplacementPolicy, XSDebug, SRAMTemplate, ParallelOR}
import scala.math.max
......@@ -19,6 +19,7 @@ case class DCacheParameters
nTLBEntries: Int = 32,
tagECC: Option[String] = None,
dataECC: Option[String] = None,
replacer: Option[String] = Some("random"),
nMissEntries: Int = 1,
nProbeEntries: Int = 1,
nReleaseEntries: Int = 1,
......@@ -30,8 +31,7 @@ case class DCacheParameters
def tagCode: Code = Code.fromString(tagECC)
def dataCode: Code = Code.fromString(dataECC)
def replacement = new RandomReplacement(nWays)
def replacement = ReplacementPolicy.fromString(replacer, nWays, nSets)
}
trait HasDCacheParameters extends HasL1CacheParameters {
......@@ -107,6 +107,11 @@ class L1DataWriteReq extends L1DataReadReq {
val data = Vec(blockRows, Bits(encRowBits.W))
}
class ReplacementAccessBundle extends DCacheBundle {
val set = UInt(log2Up(nSets).W)
val way = UInt(log2Up(nWays).W)
}
abstract class TransposeAbstractDataArray extends DCacheModule {
val io = IO(new DCacheBundle {
val read = Vec(LoadPipelineWidth, Flipped(DecoupledIO(new L1DataReadReq)))
......
......@@ -324,6 +324,18 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
assert (!bus.d.fire())
}
//----------------------------------------
// update replacement policy
val replacer = cacheParams.replacement
val access_bundles = ldu.map(_.io.replace_access) ++ Seq(mainPipe.io.replace_access)
val sets = access_bundles.map(_.bits.set)
val touch_ways = Seq.fill(LoadPipelineWidth + 1)(Wire(ValidIO(UInt(log2Up(nWays).W))))
(touch_ways zip access_bundles).map{ case (w, access) =>
w.valid := access.valid
w.bits := access.bits.way
}
replacer.access(sets, touch_ways)
// dcache should only deal with DRAM addresses
when (bus.a.fire()) {
......
......@@ -22,6 +22,9 @@ class LoadPipe extends DCacheModule {
// send miss request to miss queue
val miss_req = DecoupledIO(new MissReq)
// update state vec in replacement algo
val replace_access = ValidIO(new ReplacementAccessBundle)
})
val s1_ready = Wire(Bool())
......@@ -94,6 +97,10 @@ class LoadPipe extends DCacheModule {
io.data_read.valid := s1_fire && !s1_nack
io.lsu.s1_data := DontCare
io.replace_access.valid := RegNext(io.meta_read.fire()) && s1_tag_match && s1_valid
io.replace_access.bits.set := get_idx(s1_req.addr)
io.replace_access.bits.way := OHToUInt(s1_tag_match_way)
// --------------------------------------------------------------------------------
// stage 2
......
......@@ -83,6 +83,9 @@ class MainPipe extends DCacheModule {
// lrsc locked block should block probe
val lrsc_locked_block = Output(Valid(UInt(PAddrBits.W)))
// update state vec in replacement algo
val replace_access = ValidIO(new ReplacementAccessBundle)
})
// assign default value to output signals
......@@ -199,6 +202,7 @@ class MainPipe extends DCacheModule {
val s1_need_data = RegEnable(need_data, s0_fire)
val s1_fire = s1_valid && s2_ready && (!s1_need_data || io.data_read.fire())
val s1_req = RegEnable(s0_req, s0_fire)
val s1_set = get_idx(s1_req.addr)
val s1_rmask = RegEnable(s0_rmask, s0_fire)
val s1_store_wmask = RegEnable(store_wmask, s0_fire)
......@@ -238,7 +242,7 @@ class MainPipe extends DCacheModule {
// replacement policy
val replacer = cacheParams.replacement
val s1_repl_way_en = WireInit(0.U(nWays.W))
s1_repl_way_en := Mux(RegNext(s0_fire), UIntToOH(replacer.way), RegNext(s1_repl_way_en))
s1_repl_way_en := Mux(RegNext(s0_fire), UIntToOH(replacer.way(s1_set)), RegNext(s1_repl_way_en))
val s1_repl_meta = Mux1H(s1_repl_way_en, wayMap((w: Int) => meta_resp(w)))
val s1_repl_coh = s1_repl_meta.coh
......@@ -249,14 +253,11 @@ class MainPipe extends DCacheModule {
val s1_meta = Mux(s1_need_replacement, s1_repl_meta, s1_hit_meta)
val s1_coh = Mux(s1_need_replacement, s1_repl_coh, s1_hit_coh)
// for now, since we are using random replacement
// we only need to update replacement states after every valid replacement decision
// we only do replacement when we are true miss(not permission miss)
when (s1_fire) {
when (s1_need_replacement) {
replacer.miss
}
}
// when (s1_fire) {
// when (s1_need_replacement) {
// replacer.miss
// }
// }
// read data
io.data_read.valid := s1_valid/* && s2_ready*/ && s1_need_data && !(s3_valid && need_write_data)
......@@ -584,6 +585,12 @@ class MainPipe extends DCacheModule {
(!update_meta || io.meta_write.ready) &&
(!need_write_data || io.data_write.ready)
// --------------------------------------------------------------------------------
// update replacement policy
io.replace_access.valid := RegNext(s3_fire) && (RegNext(update_meta) || RegNext(need_write_data))
io.replace_access.bits.set := RegNext(get_idx(s3_req.addr))
io.replace_access.bits.way := RegNext(s3_way_en)
// --------------------------------------------------------------------------------
// send store/amo miss to miss queue
val store_amo_miss = !s3_req.miss && !s3_req.probe && !s3_hit && (s3_req.source === STORE_SOURCE.U || s3_req.source === AMO_SOURCE.U)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册