1
0

Merge pull request #1012 from freechipsproject/halt-and-catch-fire

Halt and Catch Fire
This commit is contained in:
Henry Cook 2017-09-22 09:30:30 -07:00 committed by GitHub
commit 5662d1de0b
6 changed files with 50 additions and 20 deletions

View File

@ -11,7 +11,8 @@ import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._ import freechips.rocketchip.util._
import TLMessages._ import TLMessages._
class DCacheErrors(implicit p: Parameters) extends L1HellaCacheBundle()(p) { class DCacheErrors(implicit p: Parameters) extends L1HellaCacheBundle()(p)
with CanHaveErrors {
val correctable = (cacheParams.tagECC.canCorrect || cacheParams.dataECC.canCorrect).option(Valid(UInt(width = paddrBits))) val correctable = (cacheParams.tagECC.canCorrect || cacheParams.dataECC.canCorrect).option(Valid(UInt(width = paddrBits)))
val uncorrectable = (cacheParams.tagECC.canDetect || cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits))) val uncorrectable = (cacheParams.tagECC.canDetect || cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
val bus = Valid(UInt(width = paddrBits)) val bus = Valid(UInt(width = paddrBits))
@ -41,9 +42,9 @@ class DCacheDataArray(implicit p: Parameters) extends L1HellaCacheModule()(p) {
val wMask = if (nWays == 1) eccMask else (0 until nWays).flatMap(i => eccMask.map(_ && io.req.bits.way_en(i))) val wMask = if (nWays == 1) eccMask else (0 until nWays).flatMap(i => eccMask.map(_ && io.req.bits.way_en(i)))
val wWords = io.req.bits.wdata.grouped(encBits * (wordBits / eccBits)) val wWords = io.req.bits.wdata.grouped(encBits * (wordBits / eccBits))
val addr = io.req.bits.addr >> rowOffBits val addr = io.req.bits.addr >> rowOffBits
val dcache_data_arrays = Seq.fill(rowBytes / wordBytes) { SeqMem(nSets * refillCycles, Vec(nWays * (wordBits / eccBits), UInt(width = encBits))) } val data_arrays = Seq.fill(rowBytes / wordBytes) { SeqMem(nSets * refillCycles, Vec(nWays * (wordBits / eccBits), UInt(width = encBits))) }
val rdata = for ((array, i) <- dcache_data_arrays zipWithIndex) yield { val rdata = for ((array, i) <- data_arrays zipWithIndex) yield {
val valid = io.req.valid && (Bool(dcache_data_arrays.size == 1) || io.req.bits.wordMask(i)) val valid = io.req.valid && (Bool(data_arrays.size == 1) || io.req.bits.wordMask(i))
when (valid && io.req.bits.write) { when (valid && io.req.bits.write) {
val wData = wWords(i).grouped(encBits) val wData = wWords(i).grouped(encBits)
array.write(addr, Vec((0 until nWays).flatMap(i => wData)), wMask) array.write(addr, Vec((0 until nWays).flatMap(i => wData)), wMask)
@ -78,7 +79,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
// tags // tags
val replacer = cacheParams.replacement val replacer = cacheParams.replacement
val metaArb = Module(new Arbiter(new DCacheMetadataReq, 8)) val metaArb = Module(new Arbiter(new DCacheMetadataReq, 8))
val dcache_tag_array = SeqMem(nSets, Vec(nWays, UInt(width = tECC.width(metaArb.io.out.bits.data.getWidth)))) val tag_array = SeqMem(nSets, Vec(nWays, UInt(width = tECC.width(metaArb.io.out.bits.data.getWidth))))
// data // data
val data = Module(new DCacheDataArray) val data = Module(new DCacheDataArray)
@ -188,9 +189,9 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
when (metaReq.valid && metaReq.bits.write) { when (metaReq.valid && metaReq.bits.write) {
val wdata = tECC.encode(metaReq.bits.data.asUInt) val wdata = tECC.encode(metaReq.bits.data.asUInt)
val wmask = if (nWays == 1) Seq(true.B) else metaReq.bits.way_en.toBools val wmask = if (nWays == 1) Seq(true.B) else metaReq.bits.way_en.toBools
dcache_tag_array.write(metaIdx, Vec.fill(nWays)(wdata), wmask) tag_array.write(metaIdx, Vec.fill(nWays)(wdata), wmask)
} }
val s1_meta = dcache_tag_array.read(metaIdx, metaReq.valid && !metaReq.bits.write) val s1_meta = tag_array.read(metaIdx, metaReq.valid && !metaReq.bits.write)
val s1_meta_uncorrected = s1_meta.map(tECC.decode(_).uncorrected.asTypeOf(new L1Metadata)) val s1_meta_uncorrected = s1_meta.map(tECC.decode(_).uncorrected.asTypeOf(new L1Metadata))
val s1_tag = s1_paddr >> untagBits val s1_tag = s1_paddr >> untagBits
val s1_meta_hit_way = s1_meta_uncorrected.map(r => r.coh.isValid() && r.tag === s1_tag).asUInt val s1_meta_hit_way = s1_meta_uncorrected.map(r => r.coh.isValid() && r.tag === s1_tag).asUInt

View File

@ -36,7 +36,9 @@ 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 { class ICacheErrors(implicit p: Parameters) extends CoreBundle()(p)
with HasL1ICacheParameters
with CanHaveErrors {
val correctable = (cacheParams.tagECC.canDetect || cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits))) 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))) val uncorrectable = (cacheParams.itimAddr.nonEmpty && cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
} }
@ -174,13 +176,13 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
v v
} }
val icache_tag_array = SeqMem(nSets, Vec(nWays, UInt(width = tECC.width(1 + tagBits)))) val tag_array = SeqMem(nSets, Vec(nWays, UInt(width = tECC.width(1 + tagBits))))
val tag_rdata = icache_tag_array.read(s0_vaddr(untagBits-1,blockOffBits), !refill_done && s0_valid) val tag_rdata = tag_array.read(s0_vaddr(untagBits-1,blockOffBits), !refill_done && s0_valid)
val accruedRefillError = Reg(Bool()) val accruedRefillError = Reg(Bool())
val refillError = tl_out.d.bits.error || (refill_cnt > 0 && accruedRefillError) val refillError = tl_out.d.bits.error || (refill_cnt > 0 && accruedRefillError)
when (refill_done) { when (refill_done) {
val enc_tag = tECC.encode(Cat(refillError, refill_tag)) val enc_tag = tECC.encode(Cat(refillError, refill_tag))
icache_tag_array.write(refill_idx, Vec.fill(nWays)(enc_tag), Seq.tabulate(nWays)(repl_way === _)) tag_array.write(refill_idx, Vec.fill(nWays)(enc_tag), Seq.tabulate(nWays)(repl_way === _))
} }
val vb_array = Reg(init=Bits(0, nSets*nWays)) val vb_array = Reg(init=Bits(0, nSets*nWays))
@ -222,8 +224,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
assert(!(s1_valid || s1_slaveValid) || PopCount(s1_tag_hit zip s1_tag_disparity map { case (h, d) => h && !d }) <= 1) assert(!(s1_valid || s1_slaveValid) || PopCount(s1_tag_hit zip s1_tag_disparity map { case (h, d) => h && !d }) <= 1)
require(tl_out.d.bits.data.getWidth % wordBits == 0) require(tl_out.d.bits.data.getWidth % wordBits == 0)
val icache_data_arrays = Seq.fill(tl_out.d.bits.data.getWidth / wordBits) { SeqMem(nSets * refillCycles, Vec(nWays, UInt(width = dECC.width(wordBits)))) } val data_arrays = Seq.fill(tl_out.d.bits.data.getWidth / wordBits) { SeqMem(nSets * refillCycles, Vec(nWays, UInt(width = dECC.width(wordBits)))) }
for ((data_array, i) <- icache_data_arrays zipWithIndex) { for ((data_array, i) <- data_arrays zipWithIndex) {
def wordMatch(addr: UInt) = addr.extract(log2Ceil(tl_out.d.bits.data.getWidth/8)-1, log2Ceil(wordBits/8)) === i def wordMatch(addr: UInt) = addr.extract(log2Ceil(tl_out.d.bits.data.getWidth/8)-1, log2Ceil(wordBits/8)) === i
def row(addr: UInt) = addr(untagBits-1, blockOffBits-log2Ceil(refillCycles)) def row(addr: UInt) = addr(untagBits-1, blockOffBits-log2Ceil(refillCycles))
val s0_ren = (s0_valid && wordMatch(s0_vaddr)) || (s0_slaveValid && wordMatch(s0_slaveAddr)) val s0_ren = (s0_valid && wordMatch(s0_vaddr)) || (s0_slaveValid && wordMatch(s0_slaveAddr))

View File

@ -628,12 +628,12 @@ class DataArray(implicit p: Parameters) extends L1HellaCacheModule()(p) {
val resp = Wire(Vec(rowWords, Bits(width = encRowBits))) val resp = Wire(Vec(rowWords, Bits(width = encRowBits)))
val r_raddr = RegEnable(io.read.bits.addr, io.read.valid) val r_raddr = RegEnable(io.read.bits.addr, io.read.valid)
for (i <- 0 until resp.size) { for (i <- 0 until resp.size) {
val nbdcache_data_array = SeqMem(nSets*refillCycles, Vec(rowWords, Bits(width=encDataBits))) val array = SeqMem(nSets*refillCycles, Vec(rowWords, Bits(width=encDataBits)))
when (wway_en.orR && io.write.valid && io.write.bits.wmask(i)) { when (wway_en.orR && io.write.valid && io.write.bits.wmask(i)) {
val data = Vec.fill(rowWords)(io.write.bits.data(encDataBits*(i+1)-1,encDataBits*i)) val data = Vec.fill(rowWords)(io.write.bits.data(encDataBits*(i+1)-1,encDataBits*i))
nbdcache_data_array.write(waddr, data, wway_en.toBools) array.write(waddr, data, wway_en.toBools)
} }
resp(i) := nbdcache_data_array.read(raddr, rway_en.orR && io.read.valid).asUInt resp(i) := array.read(raddr, rway_en.orR && io.read.valid).asUInt
} }
for (dw <- 0 until rowWords) { for (dw <- 0 until rowWords) {
val r = Vec(resp.map(_(encDataBits*(dw+1)-1,encDataBits*dw))) val r = Vec(resp.map(_(encDataBits*(dw+1)-1,encDataBits*dw)))
@ -645,12 +645,12 @@ class DataArray(implicit p: Parameters) extends L1HellaCacheModule()(p) {
} }
} else { } else {
for (w <- 0 until nWays) { for (w <- 0 until nWays) {
val nbdcache_data_array = SeqMem(nSets*refillCycles, Vec(rowWords, Bits(width=encDataBits))) val array = SeqMem(nSets*refillCycles, Vec(rowWords, Bits(width=encDataBits)))
when (io.write.bits.way_en(w) && io.write.valid) { when (io.write.bits.way_en(w) && io.write.valid) {
val data = Vec.tabulate(rowWords)(i => io.write.bits.data(encDataBits*(i+1)-1,encDataBits*i)) val data = Vec.tabulate(rowWords)(i => io.write.bits.data(encDataBits*(i+1)-1,encDataBits*i))
nbdcache_data_array.write(waddr, data, io.write.bits.wmask.toBools) array.write(waddr, data, io.write.bits.wmask.toBools)
} }
io.resp(w) := nbdcache_data_array.read(raddr, io.read.bits.way_en(w) && io.read.valid).asUInt io.resp(w) := array.read(raddr, io.read.bits.way_en(w) && io.read.valid).asUInt
} }
} }

View File

@ -20,6 +20,7 @@ case class RocketTileParams(
dataScratchpadBytes: Int = 0, dataScratchpadBytes: Int = 0,
boundaryBuffers: Boolean = false, boundaryBuffers: Boolean = false,
trace: Boolean = false, trace: Boolean = false,
hcfOnUncorrectable: Boolean = false,
name: Option[String] = Some("tile"), name: Option[String] = Some("tile"),
externalMasterBuffers: Int = 0, externalMasterBuffers: Int = 0,
externalSlaveBuffers: Int = 0) extends TileParams { externalSlaveBuffers: Int = 0) extends TileParams {
@ -131,6 +132,9 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
class RocketTileBundle(outer: RocketTile) extends BaseTileBundle(outer) class RocketTileBundle(outer: RocketTile) extends BaseTileBundle(outer)
with HasExternalInterruptsBundle with HasExternalInterruptsBundle
with CanHaveScratchpadBundle with CanHaveScratchpadBundle
with CanHaltAndCatchFire {
val halt_and_catch_fire = outer.rocketParams.hcfOnUncorrectable.option(Bool(OUTPUT))
}
class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer)) class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer))
with HasExternalInterruptsModule with HasExternalInterruptsModule
@ -138,9 +142,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
with CanHaveScratchpadModule { with CanHaveScratchpadModule {
val core = Module(p(BuildCore)(outer.p)) val core = Module(p(BuildCore)(outer.p))
val uncorrectable = RegInit(Bool(false))
decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
core.io.hartid := io.hartid // Pass through the hartid core.io.hartid := io.hartid // Pass through the hartid
io.trace.foreach { _ := core.io.trace } io.trace.foreach { _ := core.io.trace }
io.halt_and_catch_fire.foreach { _ := uncorrectable }
outer.frontend.module.io.cpu <> core.io.imem outer.frontend.module.io.cpu <> core.io.imem
outer.frontend.module.io.reset_vector := io.reset_vector outer.frontend.module.io.reset_vector := io.reset_vector
outer.frontend.module.io.hartid := io.hartid outer.frontend.module.io.hartid := io.hartid
@ -154,6 +161,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
core.io.rocc.busy := roccCore.busy core.io.rocc.busy := roccCore.busy
core.io.rocc.interrupt := roccCore.interrupt core.io.rocc.interrupt := roccCore.interrupt
when(!uncorrectable) { uncorrectable :=
List(outer.frontend.module.io.errors, outer.dcache.module.io.errors)
.flatMap { e => e.uncorrectable.map(_.valid) }
.reduceOption(_||_)
.getOrElse(false.B)
}
// TODO eliminate this redundancy // TODO eliminate this redundancy
val h = dcachePorts.size val h = dcachePorts.size
@ -207,18 +220,23 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
} }
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new CoreBundle with HasExternallyDrivenTileConstants with CanHaveInstructionTracePort { val io = new CoreBundle
with HasExternallyDrivenTileConstants
with CanHaveInstructionTracePort
with CanHaltAndCatchFire {
val master = masterNode.bundleOut val master = masterNode.bundleOut
val slave = slaveNode.bundleIn val slave = slaveNode.bundleIn
val outputInterrupts = intOutputNode.map(_.bundleOut) val outputInterrupts = intOutputNode.map(_.bundleOut)
val asyncInterrupts = asyncIntNode.bundleIn val asyncInterrupts = asyncIntNode.bundleIn
val periphInterrupts = periphIntNode.bundleIn val periphInterrupts = periphIntNode.bundleIn
val coreInterrupts = coreIntNode.bundleIn val coreInterrupts = coreIntNode.bundleIn
val halt_and_catch_fire = rocket.module.io.halt_and_catch_fire.map(_.cloneType)
} }
// signals that do not change based on crossing type: // signals that do not change based on crossing type:
rocket.module.io.hartid := io.hartid rocket.module.io.hartid := io.hartid
rocket.module.io.reset_vector := io.reset_vector rocket.module.io.reset_vector := io.reset_vector
io.trace.foreach { _ := rocket.module.io.trace.get } io.trace.foreach { _ := rocket.module.io.trace.get }
io.halt_and_catch_fire.foreach { _ := rocket.module.io.halt_and_catch_fire.get }
} }
} }

View File

@ -173,3 +173,8 @@ class SECDEDTest extends Module
io.correctable := d.correctable io.correctable := d.correctable
io.uncorrectable := d.uncorrectable io.uncorrectable := d.uncorrectable
} }
trait CanHaveErrors extends Bundle {
val correctable: Option[ValidIO[UInt]]
val uncorrectable: Option[ValidIO[UInt]]
}

View File

@ -26,6 +26,10 @@ trait Clocked extends Bundle {
val reset = Bool() val reset = Bool()
} }
trait CanHaltAndCatchFire extends Bundle {
val halt_and_catch_fire: Option[Bool]
}
object DecoupledHelper { object DecoupledHelper {
def apply(rvs: Bool*) = new DecoupledHelper(rvs) def apply(rvs: Bool*) = new DecoupledHelper(rvs)
} }