1
0

Report I$ errors

This commit is contained in:
Andrew Waterman 2017-09-15 18:41:50 -07:00
parent 9a175b0fb1
commit 034ea722f4
2 changed files with 30 additions and 8 deletions

View File

@ -70,6 +70,7 @@ class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p)
val ptw = new TLBPTWIO() val ptw = new TLBPTWIO()
val tl_out = outer.masterNode.bundleOut val tl_out = outer.masterNode.bundleOut
val tl_in = outer.slaveNode.bundleIn val tl_in = outer.slaveNode.bundleIn
val errors = new ICacheErrors
} }
class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
@ -286,6 +287,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
// performance events // performance events
io.cpu.perf := icache.io.perf io.cpu.perf := icache.io.perf
io.cpu.perf.tlbMiss := io.ptw.req.fire() io.cpu.perf.tlbMiss := io.ptw.req.fire()
io.errors := icache.io.errors
def alignPC(pc: UInt) = ~(~pc | (coreInstBytes - 1)) def alignPC(pc: UInt) = ~(~pc | (coreInstBytes - 1))
} }

View File

@ -36,6 +36,11 @@ class ICacheReq(implicit p: Parameters) extends CoreBundle()(p) with HasL1ICache
val addr = UInt(width = vaddrBits) val addr = UInt(width = vaddrBits)
} }
class ICacheErrors(implicit p: Parameters) extends CoreBundle()(p) with HasL1ICacheParameters {
val correctable = (cacheParams.tagECC.canDetect || cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
val uncorrectable = (cacheParams.itimAddr.nonEmpty && cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
}
class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule { class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule {
lazy val module = new ICacheModule(this) lazy val module = new ICacheModule(this)
val masterNode = TLClientNode(TLClientParameters( val masterNode = TLClientNode(TLClientParameters(
@ -87,6 +92,7 @@ class ICacheBundle(outer: ICache) extends CoreBundle()(outer.p) {
val tl_out = outer.masterNode.bundleOut val tl_out = outer.masterNode.bundleOut
val tl_in = outer.slaveNode.map(_.bundleIn) val tl_in = outer.slaveNode.map(_.bundleIn)
val errors = new ICacheErrors
val perf = new ICachePerfEvents().asOutput val perf = new ICachePerfEvents().asOutput
} }
@ -116,10 +122,10 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
val scratchpadOn = RegInit(false.B) val scratchpadOn = RegInit(false.B)
val scratchpadMax = tl_in.map(tl => Reg(UInt(width = log2Ceil(nSets * (nWays - 1))))) val scratchpadMax = tl_in.map(tl => Reg(UInt(width = log2Ceil(nSets * (nWays - 1)))))
def lineInScratchpad(line: UInt) = scratchpadMax.map(scratchpadOn && line <= _).getOrElse(false.B) def lineInScratchpad(line: UInt) = scratchpadMax.map(scratchpadOn && line <= _).getOrElse(false.B)
def addrMaybeInScratchpad(addr: UInt) = if (outer.icacheParams.itimAddr.isEmpty) false.B else { val scratchpadBase = outer.icacheParams.itimAddr.map { dummy =>
val base = GetPropertyByHartId(p(RocketTilesKey), _.icache.flatMap(_.itimAddr.map(_.U)), io.hartid) GetPropertyByHartId(p(RocketTilesKey), _.icache.flatMap(_.itimAddr.map(_.U)), io.hartid)
addr >= base && addr < base + outer.size
} }
def addrMaybeInScratchpad(addr: UInt) = scratchpadBase.map(base => addr >= base && addr < base + outer.size).getOrElse(false.B)
def addrInScratchpad(addr: UInt) = addrMaybeInScratchpad(addr) && lineInScratchpad(addr(untagBits+log2Ceil(nWays)-1, blockOffBits)) def addrInScratchpad(addr: UInt) = addrMaybeInScratchpad(addr) && lineInScratchpad(addr(untagBits+log2Ceil(nWays)-1, blockOffBits))
def scratchpadWay(addr: UInt) = addr.extract(untagBits+log2Ceil(nWays)-1, untagBits) def scratchpadWay(addr: UInt) = addr.extract(untagBits+log2Ceil(nWays)-1, untagBits)
def scratchpadWayValid(way: UInt) = way < nWays - 1 def scratchpadWayValid(way: UInt) = way < nWays - 1
@ -248,12 +254,15 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
io.resp.valid := s1_valid && s1_hit io.resp.valid := s1_valid && s1_hit
case 2 => case 2 =>
val s2_tag_hit = RegEnable(s1_tag_hit, s1_valid || s1_slaveValid) val s1_clk_en = s1_valid || s1_slaveValid
val s2_dout = RegEnable(s1_dout, s1_valid || s1_slaveValid) val s2_tag_hit = RegEnable(s1_tag_hit, s1_clk_en)
val s2_hit_way = OHToUInt(s2_tag_hit)
val s2_scratchpad_word_addr = Cat(s2_hit_way, io.s2_vaddr(untagBits-1, log2Ceil(wordBits/8)), UInt(0, log2Ceil(wordBits/8)))
val s2_dout = RegEnable(s1_dout, s1_clk_en)
val s2_way_mux = Mux1H(s2_tag_hit, s2_dout) val s2_way_mux = Mux1H(s2_tag_hit, s2_dout)
val s2_tag_disparity = RegEnable(s1_tag_disparity, s1_valid || s1_slaveValid).asUInt.orR val s2_tag_disparity = RegEnable(s1_tag_disparity, s1_clk_en).asUInt.orR
val s2_tl_error = RegEnable(s1_tl_error.asUInt.orR, s1_valid || s1_slaveValid) val s2_tl_error = RegEnable(s1_tl_error.asUInt.orR, s1_clk_en)
val s2_data_decoded = dECC.decode(s2_way_mux) val s2_data_decoded = dECC.decode(s2_way_mux)
val s2_disparity = s2_tag_disparity || s2_data_decoded.error val s2_disparity = s2_tag_disparity || s2_data_decoded.error
when (s2_valid && s2_disparity) { invalidate := true } when (s2_valid && s2_disparity) { invalidate := true }
@ -263,6 +272,17 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
io.resp.bits.replay := s2_disparity io.resp.bits.replay := s2_disparity
io.resp.valid := s2_valid && s2_hit io.resp.valid := s2_valid && s2_hit
val s1_scratchpad_hit = Mux(s1_slaveValid, lineInScratchpad(scratchpadLine(s1s3_slaveAddr)), addrInScratchpad(io.s1_paddr))
val s2_scratchpad_hit = RegEnable(s1_scratchpad_hit, s1_clk_en)
io.errors.correctable.foreach { c =>
c.valid := s2_valid && Mux(s2_scratchpad_hit, s2_data_decoded.correctable, s2_disparity)
c.bits := 0.U
}
io.errors.uncorrectable.foreach { u =>
u.valid := s2_valid && s2_scratchpad_hit && s2_data_decoded.uncorrectable
u.bits := scratchpadBase.get + s2_scratchpad_word_addr
}
tl_in.map { tl => tl_in.map { tl =>
val respValid = RegInit(false.B) val respValid = RegInit(false.B)
tl.a.ready := !(tl_out.d.valid || s1_slaveValid || s2_slaveValid || s3_slaveValid || respValid) tl.a.ready := !(tl_out.d.valid || s1_slaveValid || s2_slaveValid || s3_slaveValid || respValid)
@ -290,7 +310,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
// a structural hazard on s1s3_slaveData/s1s3_slaveAddress). // a structural hazard on s1s3_slaveData/s1s3_slaveAddress).
s3_slaveValid := true s3_slaveValid := true
s1s3_slaveData := s2_data_decoded.corrected s1s3_slaveData := s2_data_decoded.corrected
s1s3_slaveAddr := Cat(OHToUInt(s2_tag_hit), io.s2_vaddr(untagBits-1, log2Ceil(wordBits/8)), s1s3_slaveAddr(log2Ceil(wordBits/8)-1, 0)) s1s3_slaveAddr := s2_scratchpad_word_addr | s1s3_slaveAddr(log2Ceil(wordBits/8)-1, 0)
} }
respValid := s2_slaveValid || (respValid && !tl.d.ready) respValid := s2_slaveValid || (respValid && !tl.d.ready)