Skip to content

Commit

Permalink
L1CacheErrorInfo: code refactor for correct and convenient clockgate (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxpicca-Li committed Jun 15, 2024
1 parent 8fe4f15 commit 0184a80
Show file tree
Hide file tree
Showing 15 changed files with 73 additions and 76 deletions.
6 changes: 1 addition & 5 deletions src/main/scala/xiangshan/Bundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -606,11 +606,7 @@ class L1CacheErrorInfo(implicit p: Parameters) extends XSBundle {
// bus error unit will receive error info iff ecc_error.valid
val report_to_beu = Output(Bool())

// there is an valid error
// l1 cache error will always be report to CACHE_ERROR csr
val valid = Output(Bool())

def toL1BusErrorUnitInfo(): L1BusErrorUnitInfo = {
def toL1BusErrorUnitInfo(valid: Bool): L1BusErrorUnitInfo = {
val beu_info = Wire(new L1BusErrorUnitInfo)
beu_info.ecc_error.valid := valid && report_to_beu
beu_info.ecc_error.bits := paddr
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/xiangshan/XSCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
memBlock.io.hartId := io.hartId
memBlock.io.outer_reset_vector := io.reset_vector
// frontend -> memBlock
memBlock.io.inner_beu_errors_icache <> frontend.io.error.toL1BusErrorUnitInfo()
memBlock.io.inner_beu_errors_icache <> frontend.io.error.bits.toL1BusErrorUnitInfo(frontend.io.error.valid)
memBlock.io.inner_l2_pf_enable := backend.io.csrCustomCtrl.l2_pf_enable
memBlock.io.inner_cpu_halt := backend.io.toTop.cpuHalted
memBlock.io.ooo_to_mem.issueLda <> backend.io.mem.issueLda
Expand Down Expand Up @@ -233,7 +233,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)

io.cpu_halt := memBlock.io.outer_cpu_halt
io.beu_errors.icache <> memBlock.io.outer_beu_errors_icache
io.beu_errors.dcache <> memBlock.io.error.toL1BusErrorUnitInfo()
io.beu_errors.dcache <> memBlock.io.error.bits.toL1BusErrorUnitInfo(memBlock.io.error.valid)
io.beu_errors.l2 <> DontCare
io.l2_pf_enable := memBlock.io.outer_l2_pf_enable
// Modules are reset one by one
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/xiangshan/backend/MemBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
val fetch_to_mem = new fetch_to_mem

// misc
val error = new L1CacheErrorInfo
val error = ValidIO(new L1CacheErrorInfo)
val memInfo = new Bundle {
val sqFull = Output(Bool())
val lqFull = Output(Bool())
Expand Down Expand Up @@ -320,9 +320,9 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
dcache.io.csr.distribute_csr <> csrCtrl.distribute_csr
dcache.io.l2_pf_store_only := RegNext(io.ooo_to_mem.csrCtrl.l2_pf_store_only, false.B)
io.mem_to_ooo.csrUpdate := RegNext(dcache.io.csr.update)
io.error <> RegNext(RegNext(dcache.io.error))
io.error <> DelayNWithValid(dcache.io.error, 2)
when(!csrCtrl.cache_error_enable){
io.error.report_to_beu := false.B
io.error.bits.report_to_beu := false.B
io.error.valid := false.B
}

Expand Down
33 changes: 15 additions & 18 deletions src/main/scala/xiangshan/cache/CacheInstruction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class CSRCacheOpDecoder(decoder_name: String, id: Int)(implicit p: Parameters) e
val cache = new L1CacheInnerOpIO
val cache_req_dup = Vec(DCacheDupNum, Valid(new CacheCtrlReqInfo))
val cacheOp_req_bits_opCode_dup = Output(Vec(DCacheDupNum, UInt(XLEN.W)))
val error = Flipped(new L1CacheErrorInfo)
val error = Flipped(ValidIO(new L1CacheErrorInfo))
})

// CSRCacheOpDecoder state
Expand Down Expand Up @@ -272,11 +272,8 @@ class CSRCacheOpDecoder(decoder_name: String, id: Int)(implicit p: Parameters) e
data_transfer_cnt := 0.U
}

val error = Wire(io.error.cloneType)
val (error_valid,error_bits) = DelayNWithValid(io.error, io.error.valid, 1)
error <> error_bits
error.valid := error_valid
when(error.report_to_beu && error.valid) {
val error = DelayNWithValid(io.error, 1)
when(error.bits.report_to_beu && error.valid) {
io.csr.update.w.bits.addr := (CacheInstrucion.CacheInsRegisterList("CACHE_ERROR")("offset").toInt + Scachebase).U
io.csr.update.w.bits.data := error.asUInt
io.csr.update.w.valid := true.B
Expand All @@ -293,20 +290,20 @@ class CSRCacheErrorDecoder(implicit p: Parameters) extends CacheCtrlModule {
printf(" " + desc + "\n")
}
}
val decoded_cache_error = WireInit(encoded_cache_error.asTypeOf(new L1CacheErrorInfo))
val decoded_cache_error = WireInit(encoded_cache_error.asTypeOf(ValidIO(new L1CacheErrorInfo)))
when(decoded_cache_error.valid && !RegNext(decoded_cache_error.valid)){
printf("CACHE_ERROR CSR reported an error:\n")
printf(" paddr 0x%x\n", decoded_cache_error.paddr)
print_cache_error_flag(decoded_cache_error.report_to_beu, "report to bus error unit")
print_cache_error_flag(decoded_cache_error.source.tag, "tag")
print_cache_error_flag(decoded_cache_error.source.data, "data")
print_cache_error_flag(decoded_cache_error.source.l2, "l2")
print_cache_error_flag(decoded_cache_error.opType.fetch, "fetch")
print_cache_error_flag(decoded_cache_error.opType.load, "load")
print_cache_error_flag(decoded_cache_error.opType.store, "store")
print_cache_error_flag(decoded_cache_error.opType.probe, "probe")
print_cache_error_flag(decoded_cache_error.opType.release, "release")
print_cache_error_flag(decoded_cache_error.opType.atom, "atom")
printf(" paddr 0x%x\n", decoded_cache_error.bits.paddr)
print_cache_error_flag(decoded_cache_error.bits.report_to_beu, "report to bus error unit")
print_cache_error_flag(decoded_cache_error.bits.source.tag, "tag")
print_cache_error_flag(decoded_cache_error.bits.source.data, "data")
print_cache_error_flag(decoded_cache_error.bits.source.l2, "l2")
print_cache_error_flag(decoded_cache_error.bits.opType.fetch, "fetch")
print_cache_error_flag(decoded_cache_error.bits.opType.load, "load")
print_cache_error_flag(decoded_cache_error.bits.opType.store, "store")
print_cache_error_flag(decoded_cache_error.bits.opType.probe, "probe")
print_cache_error_flag(decoded_cache_error.bits.opType.release, "release")
print_cache_error_flag(decoded_cache_error.bits.opType.atom, "atom")
printf("It should not happen in normal execution flow\n")
}
}
8 changes: 6 additions & 2 deletions src/main/scala/xiangshan/cache/dcache/DCacheWrapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ class DCacheIO(implicit p: Parameters) extends DCacheBundle {
val l2_pf_store_only = Input(Bool())
val lsu = new DCacheToLsuIO
val csr = new L1CacheToCsrIO
val error = new L1CacheErrorInfo
val error = ValidIO(new L1CacheErrorInfo)
val mshrFull = Output(Bool())
val memSetPattenDetected = Output(Bool())
val lqEmpty = Input(Bool())
Expand Down Expand Up @@ -885,7 +885,11 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame

val errors = ldu.map(_.io.error) ++ // load error
Seq(mainPipe.io.error) // store / misc error
io.error <> RegNext(Mux1H(errors.map(e => RegNext(e.valid) -> RegNext(e))))
val error_valid = errors.map(e => e.valid).reduce(_|_)
io.error.bits <> RegEnable(
Mux1H(errors.map(e => RegNext(e.valid) -> RegEnable(e.bits, e.valid))),
RegNext(error_valid))
io.error.valid := RegNext(RegNext(error_valid, init = false.B), init = false.B)

//----------------------------------------
// meta array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ abstract class AbstractDataArray(implicit p: Parameters) extends DCacheModule {
val write = Flipped(DecoupledIO(new L1DataWriteReq))
val resp = Output(Vec(3, Vec(blockRows, Bits(encRowBits.W))))
val nacks = Output(Vec(3, Bool()))
val errors = Output(Vec(3, new L1CacheErrorInfo))
val errors = Output(Vec(3, ValidIO(new L1CacheErrorInfo)))
})

def pipeMap[T <: Data](f: Int => T) = VecInit((0 until 3).map(f))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ abstract class AbstractBankedDataArray(implicit p: Parameters) extends DCacheMod
val read_resp_delayed = Output(Vec(LoadPipelineWidth, Vec(VLEN/DCacheSRAMRowBits, new L1BankedDataReadResult())))
val read_error_delayed = Output(Vec(LoadPipelineWidth,Vec(VLEN/DCacheSRAMRowBits, Bool())))
// val nacks = Output(Vec(LoadPipelineWidth, Bool()))
// val errors = Output(Vec(LoadPipelineWidth + 1, new L1CacheErrorInfo)) // read ports + readline port
// val errors = Output(Vec(LoadPipelineWidth + 1, ValidIO(new L1CacheErrorInfo))) // read ports + readline port
// when bank_conflict, read (1) port should be ignored
val bank_conflict_slow = Output(Vec(LoadPipelineWidth, Bool()))
val disable_ld_fast_wakeup = Output(Vec(LoadPipelineWidth, Bool()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ class DuplicatedDataArray(implicit p: Parameters) extends AbstractDataArray {
data
}
})
io.errors(j).report_to_beu := RegNext(io.read(j).fire) && Cat(row_error.flatten).orR
io.errors(j).paddr := RegNext(io.read(j).bits.addr)
io.errors(j).bits.report_to_beu := RegNext(io.read(j).fire) && Cat(row_error.flatten).orR
io.errors(j).bits.paddr := RegNext(io.read(j).bits.addr)
}

io.nacks(j) := false.B
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/xiangshan/cache/dcache/loadpipe/LoadPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class LoadPipe(id: Int)(implicit p: Parameters) extends DCacheModule with HasPer
val disable_ld_fast_wakeup = Input(Bool())

// ecc error
val error = Output(new L1CacheErrorInfo())
val error = Output(ValidIO(new L1CacheErrorInfo))

val prefetch_info = new Bundle {
val naive = new Bundle {
Expand Down Expand Up @@ -489,13 +489,13 @@ class LoadPipe(id: Int)(implicit p: Parameters) extends DCacheModule with HasPer
resp.bits.replacementUpdated := io.replace_access.valid

// report tag / data / l2 error (with paddr) to bus error unit
io.error := 0.U.asTypeOf(new L1CacheErrorInfo())
io.error.report_to_beu := (s3_tag_error || s3_data_error) && s3_valid
io.error.paddr := s3_paddr
io.error.source.tag := s3_tag_error
io.error.source.data := s3_data_error
io.error.source.l2 := s3_flag_error
io.error.opType.load := true.B
io.error := 0.U.asTypeOf(ValidIO(new L1CacheErrorInfo))
io.error.bits.report_to_beu := (s3_tag_error || s3_data_error) && s3_valid
io.error.bits.paddr := s3_paddr
io.error.bits.source.tag := s3_tag_error
io.error.bits.source.data := s3_data_error
io.error.bits.source.l2 := s3_flag_error
io.error.bits.opType.load := true.B
// report tag error / l2 corrupted to CACHE_ERROR csr
io.error.valid := s3_error && s3_valid

Expand Down
22 changes: 11 additions & 11 deletions src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w
val block_lr = Output(Bool())

// ecc error
val error = Output(new L1CacheErrorInfo())
val error = Output(ValidIO(new L1CacheErrorInfo))
// force write
val force_write = Input(Bool())

Expand Down Expand Up @@ -1622,20 +1622,20 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w
io.mainpipe_info.s3_refill_resp := RegNext(s2_valid && s2_req.miss && s2_fire_to_s3)

// report error to beu and csr, 1 cycle after read data resp
io.error := 0.U.asTypeOf(new L1CacheErrorInfo())
io.error := 0.U.asTypeOf(ValidIO(new L1CacheErrorInfo))
// report error, update error csr
io.error.valid := s3_error && RegNext(s2_fire)
// only tag_error and data_error will be reported to beu
// l2_error should not be reported (l2 will report that)
io.error.report_to_beu := (RegEnable(s2_tag_error, s2_fire) || s3_data_error) && RegNext(s2_fire)
io.error.paddr := RegEnable(s2_req.addr, s2_fire)
io.error.source.tag := RegEnable(s2_tag_error, s2_fire)
io.error.source.data := s3_data_error
io.error.source.l2 := RegEnable(s2_flag_error || s2_l2_error, s2_fire)
io.error.opType.store := RegEnable(s2_req.isStore && !s2_req.probe, s2_fire)
io.error.opType.probe := RegEnable(s2_req.probe, s2_fire)
io.error.opType.release := RegEnable(s2_req.replace, s2_fire)
io.error.opType.atom := RegEnable(s2_req.isAMO && !s2_req.probe, s2_fire)
io.error.bits.report_to_beu := (RegEnable(s2_tag_error, s2_fire) || s3_data_error) && RegNext(s2_fire)
io.error.bits.paddr := RegEnable(s2_req.addr, s2_fire)
io.error.bits.source.tag := RegEnable(s2_tag_error, s2_fire)
io.error.bits.source.data := s3_data_error
io.error.bits.source.l2 := RegEnable(s2_flag_error || s2_l2_error, s2_fire)
io.error.bits.opType.store := RegEnable(s2_req.isStore && !s2_req.probe, s2_fire)
io.error.bits.opType.probe := RegEnable(s2_req.probe, s2_fire)
io.error.bits.opType.release := RegEnable(s2_req.replace, s2_fire)
io.error.bits.opType.atom := RegEnable(s2_req.isAMO && !s2_req.probe, s2_fire)

val perfEvents = Seq(
("dcache_mp_req ", s0_fire ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class L1MetadataArray(onReset: () => L1Metadata)(implicit p: Parameters) extends
val read = Flipped(Decoupled(new L1MetaReadReq))
val write = Flipped(Decoupled(new L1MetaWriteReq))
val resp = Output(Vec(nWays, UInt(encMetaBits.W)))
val error = Output(new L1CacheErrorInfo)
val error = Output(ValidIO(new L1CacheErrorInfo))
})
val rst_cnt = RegInit(0.U(log2Up(nSets + 1).W))
val rst = rst_cnt < nSets.U
Expand Down Expand Up @@ -90,8 +90,8 @@ class L1MetadataArray(onReset: () => L1Metadata)(implicit p: Parameters) extends
val ecc_errors = tag_array.io.r.resp.data.zipWithIndex.map({ case (d, w) =>
cacheParams.tagCode.decode(d).error && RegNext(io.read.bits.way_en(w))
})
io.error.report_to_beu := RegNext(io.read.fire) && Cat(ecc_errors).orR
io.error.paddr := Cat(io.read.bits.idx, 0.U(pgUntagBits.W))
io.error.bits.report_to_beu := RegNext(io.read.fire) && Cat(ecc_errors).orR
io.error.bits.paddr := Cat(io.read.bits.idx, 0.U(pgUntagBits.W))

io.write.ready := !rst
io.read.ready := !wen
Expand Down Expand Up @@ -134,7 +134,7 @@ class DuplicatedMetaArray(numReadPorts: Int)(implicit p: Parameters) extends DCa
val read = Vec(numReadPorts, Flipped(DecoupledIO(new L1MetaReadReq)))
val write = Flipped(DecoupledIO(new L1MetaWriteReq))
val resp = Output(Vec(numReadPorts, Vec(nWays, UInt(encMetaBits.W))))
val errors = Output(Vec(numReadPorts, new L1CacheErrorInfo))
val errors = Output(Vec(numReadPorts, ValidIO(new L1CacheErrorInfo)))
})
val meta = Seq.fill(numReadPorts) {
Module(new L1MetadataArray(onReset _))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ class StorePipe(id: Int)(implicit p: Parameters) extends DCacheModule{
val replace_way = new ReplacementWayReqIO

// ecc error
val error = Output(new L1CacheErrorInfo())
val error = Output(ValidIO(new L1CacheErrorInfo))
})

// TODO: error
io.error := DontCare
io.error := 0.U.asTypeOf(ValidIO(new L1CacheErrorInfo))

/** S0:
* send tag and meta read req
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/xiangshan/frontend/Frontend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer)
val tlbCsr = Input(new TlbCsrBundle)
val csrCtrl = Input(new CustomCSRCtrlIO)
val csrUpdate = new DistributedCSRUpdateReq
val error = new L1CacheErrorInfo
val error = ValidIO(new L1CacheErrorInfo)
val frontendInfo = new Bundle {
val ibufFull = Output(Bool())
val bpuInfo = new Bundle {
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/xiangshan/frontend/icache/ICache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ class ICacheIO(implicit p: Parameters) extends ICacheBundle
val pmp = Vec(PortNumber + prefetchPipeNum, new ICachePMPBundle)
val itlb = Vec(PortNumber + prefetchPipeNum, new TlbRequestIO)
val perfInfo = Output(new ICachePerfInfo)
val error = new L1CacheErrorInfo
val error = ValidIO(new L1CacheErrorInfo)
/* Cache Instruction */
val csr = new L1CacheToCsrIO
/* CSR control signal */
Expand Down Expand Up @@ -629,7 +629,7 @@ class ICacheImp(outer: ICache) extends LazyModuleImp(outer) with HasICacheParame

//Parity error port
val errors = mainPipe.io.errors
io.error <> RegEnable(Mux1H(errors.map(e => e.valid -> e)),errors.map(e => e.valid).reduce(_|_))
io.error.bits <> RegEnable(Mux1H(errors.map(e => e.valid -> e.bits)),errors.map(e => e.valid).reduce(_|_))
io.error.valid := RegNext(errors.map(e => e.valid).reduce(_|_),init = false.B)


Expand Down
28 changes: 14 additions & 14 deletions src/main/scala/xiangshan/frontend/icache/ICacheMainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class ICacheMainPipeInterface(implicit p: Parameters) extends ICacheBundle {
val ICacheMainPipeInfo = new ICacheMainPipeInfo

val mshr = Vec(PortNumber, new ICacheMSHRBundle)
val errors = Output(Vec(PortNumber, new L1CacheErrorInfo))
val errors = Output(Vec(PortNumber, ValidIO(new L1CacheErrorInfo)))
/*** outside interface ***/
//val fetch = Vec(PortNumber, new ICacheMainPipeBundle)
/* when ftq.valid is high in T + 1 cycle
Expand Down Expand Up @@ -676,25 +676,25 @@ class ICacheMainPipe(implicit p: Parameters) extends ICacheModule
for(i <- 0 until PortNumber){
val valid = s2_parity_error(i) && s1_fire_delay2
io.errors(i).valid := RegNext(valid)
io.errors(i).report_to_beu := RegNext(valid)
io.errors(i).paddr := RegEnable(RegEnable(s2_req_paddr(i), s1_fire_delay1), valid)
io.errors(i).source := DontCare
io.errors(i).source.tag := RegEnable(RegEnable(s2_parity_meta_error(i), s1_fire_delay1), valid)
io.errors(i).source.data := RegEnable(s2_parity_data_error(i), valid)
io.errors(i).source.l2 := false.B
io.errors(i).opType := DontCare
io.errors(i).opType.fetch := true.B
io.errors(i).bits.report_to_beu := RegNext(valid)
io.errors(i).bits.paddr := RegEnable(RegEnable(s2_req_paddr(i), s1_fire_delay1), valid)
io.errors(i).bits.source := DontCare
io.errors(i).bits.source.tag := RegEnable(RegEnable(s2_parity_meta_error(i), s1_fire_delay1), valid)
io.errors(i).bits.source.data := RegEnable(s2_parity_data_error(i), valid)
io.errors(i).bits.source.l2 := false.B
io.errors(i).bits.opType := DontCare
io.errors(i).bits.opType.fetch := true.B
}

// MSHR error
(0 until PortNumber).map{ i =>
when(RegNext(s2_fire && s2_corrupt(i))){
io.errors(i).valid := true.B
io.errors(i).report_to_beu := false.B // l2 should have report that to bus error unit, no need to do it again
io.errors(i).paddr := RegEnable(s2_req_paddr(i),s1_fire_delay1)
io.errors(i).source.tag := false.B
io.errors(i).source.data := false.B
io.errors(i).source.l2 := true.B
io.errors(i).bits.report_to_beu := false.B // l2 should have report that to bus error unit, no need to do it again
io.errors(i).bits.paddr := RegEnable(s2_req_paddr(i),s1_fire_delay1)
io.errors(i).bits.source.tag := false.B
io.errors(i).bits.source.data := false.B
io.errors(i).bits.source.l2 := true.B
}
}

Expand Down

0 comments on commit 0184a80

Please sign in to comment.