Skip to content

Commit

Permalink
fdip: use a simple sram to replace the prefetch meta with bank (OpenX…
Browse files Browse the repository at this point in the history
  • Loading branch information
ssszwic authored Oct 16, 2023
1 parent 9eca914 commit 9de7804
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 11 deletions.
6 changes: 3 additions & 3 deletions src/main/scala/xiangshan/frontend/icache/ICache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -548,16 +548,16 @@ class ICacheImp(outer: ICache) extends LazyModuleImp(outer) with HasICacheParame

val metaArray = Module(new ICacheMetaArray)
val dataArray = Module(new ICacheDataArray)
val prefetchMetaArray = Module(new ICacheBankedMetaArray(prefetchPipeNum)) // need add 1 port for IPF filter
val prefetchMetaArray = Module(new ICacheMetaArrayNoBanked)
val mainPipe = Module(new ICacheMainPipe)
val missUnit = Module(new ICacheMissUnit(edge))
val fdipPrefetch = Module(new FDIPPrefetch(edge))

fdipPrefetch.io.hartId := io.hartId
fdipPrefetch.io.fencei := io.fencei
fdipPrefetch.io.ftqReq <> io.prefetch
fdipPrefetch.io.metaReadReq <> prefetchMetaArray.io.read(0)
fdipPrefetch.io.metaReadResp <> prefetchMetaArray.io.readResp(0)
fdipPrefetch.io.metaReadReq <> prefetchMetaArray.io.read
fdipPrefetch.io.metaReadResp <> prefetchMetaArray.io.readResp
fdipPrefetch.io.ICacheMissUnitInfo <> missUnit.io.ICacheMissUnitInfo
fdipPrefetch.io.ICacheMainPipeInfo <> mainPipe.io.ICacheMainPipeInfo
fdipPrefetch.io.IPFBufferRead <> mainPipe.io.IPFBufferRead
Expand Down
121 changes: 117 additions & 4 deletions src/main/scala/xiangshan/frontend/icache/ICacheBankedArray.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import xiangshan.cache._
import utils._
import utility._

class ICacheMetaReadReqBundle(implicit p: Parameters) extends ICacheBundle {
class PrefetchMetaReadBundle(implicit p: Parameters) extends ICacheBundle {
val idx = UInt(idxBits.W)
}

class ICacheMetaReadRespBundle(implicit p: Parameters) extends ICacheBundle {
class PrefetchMetaRespBundle(implicit p: Parameters) extends ICacheBundle {
val metaData = Vec(nWays, new ICacheMetadata)
val errors = Vec(nWays ,Bool())
val entryValid = Vec(nWays, Bool())
Expand Down Expand Up @@ -57,9 +57,9 @@ class ICacheBankedMetaArray(readPortNum: Int)(implicit p: Parameters) extends IC
val metaEntryBits = cacheParams.tagCode.width(metaBits)

val io=IO{new Bundle{
val read = Vec(ICacheMetaReadPortNum, Flipped(DecoupledIO(new ICacheMetaReadReqBundle)))
val read = Vec(ICacheMetaReadPortNum, Flipped(DecoupledIO(new PrefetchMetaReadBundle)))
// TODO : does need support old read bundle?
val readResp = Vec(ICacheMetaReadPortNum, Output(new ICacheMetaReadRespBundle))
val readResp = Vec(ICacheMetaReadPortNum, Output(new PrefetchMetaRespBundle))
val write = Flipped(DecoupledIO(new ICacheMetaWriteBundle))
val cacheOp = Flipped(new L1CacheInnerOpIO)
val fencei = Input(Bool())
Expand Down Expand Up @@ -186,6 +186,119 @@ class ICacheBankedMetaArray(readPortNum: Int)(implicit p: Parameters) extends IC
)
io.cacheOp.resp.bits.read_tag_ecc := DontCare

// fencei logic : reset valid_array
when (io.fencei) {
(0 until nWays).foreach( way =>
valid_array(way) := 0.U
)
}
}


class ICacheMetaArrayNoBanked()(implicit p: Parameters) extends ICacheArray
{
def onReset = ICacheMetadata(0.U)
val metaBits = onReset.getWidth
val metaEntryBits = cacheParams.tagCode.width(metaBits)

val io=IO{new Bundle{
val read = Flipped(DecoupledIO(new PrefetchMetaReadBundle))
val readResp = Output(new PrefetchMetaRespBundle)
val write = Flipped(DecoupledIO(new ICacheMetaWriteBundle))
val cacheOp = Flipped(new L1CacheInnerOpIO)
val fencei = Input(Bool())
}}

io.read.ready := !io.write.valid

val write_meta_bits = Wire(UInt(metaEntryBits.W))

val tagArray = Module(new SRAMTemplate(
UInt(metaEntryBits.W),
set = nSets,
way = nWays,
shouldReset = true,
holdRead = true,
singlePort = true
))
tagArray.io.r.req.valid := io.read.valid
tagArray.io.r.req.bits.apply(setIdx=io.read.bits.idx)
tagArray.io.w.req.valid := io.write.valid
tagArray.io.w.req.bits.apply(data=write_meta_bits, setIdx=io.write.bits.virIdx, waymask=io.write.bits.waymask)

val read_set_idx_next = RegEnable(io.read.bits.idx, io.read.fire)
val valid_array = RegInit(VecInit(Seq.fill(nWays)(0.U(nSets.W))))
val valid_metas = Wire(Vec(nWays, Bool()))
(0 until nWays).foreach( way =>
valid_metas(way) := valid_array(way)(read_set_idx_next)
)
io.readResp.entryValid := valid_metas

// Parity Decode
val read_metas = Wire(Vec(nWays,new ICacheMetadata()))
val read_meta_bits = tagArray.io.r.resp.asTypeOf(Vec(nWays,UInt(metaEntryBits.W)))
val read_meta_decoded = read_meta_bits.map{ way_bits => cacheParams.tagCode.decode(way_bits)}
val read_meta_wrong = read_meta_decoded.map{ way_bits_decoded => way_bits_decoded.error}
val read_meta_corrected = VecInit(read_meta_decoded.map{ way_bits_decoded => way_bits_decoded.corrected})
read_metas := read_meta_corrected.asTypeOf(Vec(nWays,new ICacheMetadata()))
(0 until nWays).map{ w => io.readResp.errors(w) := RegNext(read_meta_wrong(w)) && RegNext(RegNext(io.read.fire))}

// Parity Encode
val write = io.write.bits
write_meta_bits := cacheParams.tagCode.encode(ICacheMetadata(tag = write.phyTag).asUInt)

// valid write
val way_num = OHToUInt(io.write.bits.waymask)
when (io.write.valid) {
valid_array(way_num) := valid_array(way_num).bitSet(io.write.bits.virIdx, true.B)
}

XSPerfAccumulate("meta_refill_num", io.write.valid)

io.readResp.metaData := read_metas

io.write.ready := true.B // TODO : has bug ? should be !io.cacheOp.req.valid
// deal with customized cache op
require(nWays <= 32)
io.cacheOp.resp.bits := DontCare
val cacheOpShouldResp = WireInit(false.B)
when(io.cacheOp.req.valid){
when(
CacheInstrucion.isReadTag(io.cacheOp.req.bits.opCode) ||
CacheInstrucion.isReadTagECC(io.cacheOp.req.bits.opCode)
){
tagArray.io.r.req.valid := true.B
tagArray.io.r.req.bits.apply(setIdx = io.cacheOp.req.bits.index)
cacheOpShouldResp := true.B
}
when(CacheInstrucion.isWriteTag(io.cacheOp.req.bits.opCode)){
tagArray.io.w.req.valid := true.B
tagArray.io.w.req.bits.apply(
data = io.cacheOp.req.bits.write_tag_low,
setIdx = io.cacheOp.req.bits.index,
waymask = UIntToOH(io.cacheOp.req.bits.wayNum(4, 0))
)
cacheOpShouldResp := true.B
}
// TODO
// when(CacheInstrucion.isWriteTagECC(io.cacheOp.req.bits.opCode)){
// for (i <- 0 until readPorts) {
// array(i).io.ecc_write.valid := true.B
// array(i).io.ecc_write.bits.idx := io.cacheOp.req.bits.index
// array(i).io.ecc_write.bits.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0))
// array(i).io.ecc_write.bits.ecc := io.cacheOp.req.bits.write_tag_ecc
// }
// cacheOpShouldResp := true.B
// }
}
io.cacheOp.resp.valid := RegNext(io.cacheOp.req.valid && cacheOpShouldResp)
io.cacheOp.resp.bits.read_tag_low := Mux(io.cacheOp.resp.valid,
tagArray.io.r.resp.asTypeOf(Vec(nWays, UInt(tagBits.W)))(io.cacheOp.req.bits.wayNum),
0.U
)
io.cacheOp.resp.bits.read_tag_ecc := DontCare // TODO
// TODO: deal with duplicated array

// fencei logic : reset valid_array
when (io.fencei) {
(0 until nWays).foreach( way =>
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/xiangshan/frontend/icache/IPrefetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ class IPredfetchIO(implicit p: Parameters) extends IPrefetchBundle {
val ftqReq = Flipped(new FtqPrefechBundle)
val iTLBInter = new TlbRequestIO
val pmp = new ICachePMPBundle
val metaReadReq = Decoupled(new ICacheMetaReadReqBundle)
val metaReadResp = Input(new ICacheMetaReadRespBundle)
val metaReadReq = Decoupled(new PrefetchMetaReadBundle)
val metaReadResp = Input(new PrefetchMetaRespBundle)
val prefetchReq = DecoupledIO(new PrefetchReq)

val IPFFilterRead = Flipped(new IPFBufferFilterRead)
Expand Down Expand Up @@ -822,8 +822,8 @@ class FDIPPrefetchIO(edge: TLEdgeOut)(implicit p: Parameters) extends IPrefetchB
val ftqReq = Flipped(new FtqPrefechBundle)
val iTLBInter = new TlbRequestIO
val pmp = new ICachePMPBundle
val metaReadReq = Decoupled(new ICacheMetaReadReqBundle)
val metaReadResp = Input(new ICacheMetaReadRespBundle)
val metaReadReq = Decoupled(new PrefetchMetaReadBundle)
val metaReadResp = Input(new PrefetchMetaRespBundle)

val ICacheMissUnitInfo = Flipped(new ICacheMissUnitInfo)
val ICacheMainPipeInfo = Flipped(new ICacheMainPipeInfo)
Expand Down

0 comments on commit 9de7804

Please sign in to comment.