Merge pull request #39 from OpenXiangShan/ecc

ecc: integrate ecc to ctrlUnit
This commit is contained in:
wakafa 2021-10-21 15:10:17 +08:00 committed by GitHub
commit 779921a972
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 20 deletions

View File

@ -60,6 +60,7 @@ abstract class BaseMSHRIO[T_RESULT <: BaseDirResult, T_DIR_W <: BaseDirWrite, T_
val dirResult: Valid[T_RESULT] // = Flipped(ValidIO(new DirResult))
val resps = Flipped(new MSHRResps)
val nestedwb = Input(new NestedWriteback)
val ecc = Output(new EccInfo)
}
abstract class BaseMSHR[T_RESULT <: BaseDirResult, T_DIR_W <: BaseDirWrite, T_TAG_W <: BaseTagWrite](

View File

@ -27,6 +27,7 @@ class CtrlUnitImp(wrapper: CtrlUnit) extends LazyModuleImp(wrapper) {
val req = IO(DecoupledIO(new CtrlReq()))
val resp = IO(Flipped(DecoupledIO(new CtrlResp())))
val ecc = IO(Flipped(DecoupledIO(new EccInfo())))
val node = wrapper.node
val ctlnode = wrapper.ctlnode
@ -66,10 +67,14 @@ class CtrlUnitImp(wrapper: CtrlUnit) extends LazyModuleImp(wrapper) {
val ctl_way = RegInit(0.U(64.W))
val ctl_dir = RegInit(0.U(64.W))
val ctl_data = Seq.fill(cacheParams.blockBytes / 8){ RegInit(0.U(64.W)) }
val ctl_ecc = RegInit(0.U(64.W))
val ctl_client = RegInit(0.U(64.W))
val ctl_cmd = RegInit(0.U(64.W))
val ecc_code = RegInit(0.U(64.W)) // assume non-zero as ECC error
val ecc_tag = RegInit(0.U(64.W))
val ecc_set = RegInit(0.U(64.W))
val ecc_way = RegInit(0.U(64.W))
val cmd_in_valid = RegInit(false.B)
val cmd_in_ready = WireInit(false.B)
val cmd_out_valid = RegInit(false.B)
@ -80,8 +85,10 @@ class CtrlUnitImp(wrapper: CtrlUnit) extends LazyModuleImp(wrapper) {
val ctl_config_regs = (
Seq(ctl_tag, ctl_set, ctl_way) ++
ctl_data ++ Seq(ctl_dir, ctl_ecc, ctl_client)
).map(reg => RegField(64, reg, RegWriteFn(reg)))
ctl_data ++
Seq(ctl_dir, ctl_client) ++
Seq(ecc_code, ecc_tag, ecc_set, ecc_way)
).map(reg => RegField(64, reg, RegWriteFn(reg)))
ctlnode.regmap(
0x000 -> RegFieldGroup(
@ -106,6 +113,7 @@ class CtrlUnitImp(wrapper: CtrlUnit) extends LazyModuleImp(wrapper) {
cmd_out_valid := true.B
}
resp.ready := !cmd_out_valid
ecc.ready := ecc_code === 0.U // Block multiple ecc req
req.valid := cmd_in_valid
req.bits.cmd := ctl_cmd
req.bits.data.zip(ctl_data).foreach(x => x._1 := x._2)
@ -115,7 +123,7 @@ class CtrlUnitImp(wrapper: CtrlUnit) extends LazyModuleImp(wrapper) {
req.bits.dir := ctl_dir
req.bits.client := ctl_client
when(resp.fire()){
when(resp.fire()) {
switch(resp.bits.cmd){
is(CacheCMD.CMD_R_S_TAG){
ctl_tag := resp.bits.data(0)
@ -134,6 +142,10 @@ class CtrlUnitImp(wrapper: CtrlUnit) extends LazyModuleImp(wrapper) {
}
}
}
when(ecc.fire()) {
ecc_code := ecc.bits.errCode
}
}
class CtrlReq() extends Bundle {
@ -151,6 +163,14 @@ class CtrlResp() extends Bundle {
val data = Vec(8, UInt(64.W))
}
class EccInfo() extends Bundle {
val errCode = UInt(8.W)
def ERR_NO = 0.U(8.W)
def ERR_SELF_DIR = 1.U(8.W)
def ERR_CLIENT_DIR = 2.U(8.W)
def ERR_DATA = 3.U(8.W)
}
object CacheCMD {
def CMD_R_S_TAG = 0.U(8.W)
def CMD_R_C_TAG = 1.U(8.W)

View File

@ -36,6 +36,7 @@ class DataStorage(implicit p: Parameters) extends HuanCunModule {
val sourceD_wdata = Input(new DSData)
val sinkC_waddr = Flipped(DecoupledIO(new DSAddress))
val sinkC_wdata = Input(new DSData)
val ecc = Output(new EccInfo)
})
/* Define some internal parameters */
@ -133,6 +134,7 @@ class DataStorage(implicit p: Parameters) extends HuanCunModule {
val outData = Wire(Vec(nrBanks, UInt((8 * bankBytes).W)))
val data_en = Wire(Vec(nrBanks, Bool()))
val errVec = Wire(Vec(nrBanks, Bool()))
for (i <- 0 until nrBanks) {
val en = reqs.map(_.bankEn(i)).reduce(_ || _) && SReg.sren()
@ -151,11 +153,14 @@ class DataStorage(implicit p: Parameters) extends HuanCunModule {
data_en(i) := SReg.pipe(en && !selectedReq.wen)
val decode = dataCode.decode(bankedData(i).io.r.resp.data(0))
outData(i) := RegEnable(decode.uncorrected, data_en(i))
when(data_en(i)) {
assert(!decode.error)
}
errVec(i) := decode.error
// when(data_en(i)) {
// assert(!decode.error)
// }
}
io.ecc.errCode := Mux(Cat(errVec).orR(), io.ecc.ERR_DATA, io.ecc.ERR_NO)
/* Pack out-data to channels */
val sourceDlatch = RegNext(SReg.pipe(sourceD_rreq.bankEn))
val sourceClatch = RegNext(SReg.pipe(sourceC_req.bankEn))

View File

@ -26,6 +26,7 @@ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.{BundleField, BundleFieldBase, UIntToOH1}
import huancun.prefetch._
import huancun.utils.NoopNode
trait HasHuanCunParameters {
val p: Parameters
@ -195,6 +196,10 @@ class HuanCun(implicit p: Parameters) extends LazyModule with HasHuanCunParamete
val ctrl_unit = cacheParams.ctrl.map(_ => LazyModule(new CtrlUnit(node)))
val ctlnode = ctrl_unit.map(_.ctlnode)
if (ctlnode.nonEmpty) {
val noopNode = LazyModule(new NoopNode())
ctlnode.get := noopNode.clientNode
}
lazy val module = new LazyModuleImp(this) {
val sizeBytes = cacheParams.sets * cacheParams.ways * cacheParams.blockBytes
@ -277,11 +282,16 @@ class HuanCun(implicit p: Parameters) extends LazyModule with HasHuanCunParamete
val arb = Module(new Arbiter(new CtrlResp, slices.size))
arb.io.in <> VecInit(slices.map(_.io.ctl_resp))
c.module.resp <> arb.io.out
val ecc_arb = Module(new Arbiter(new EccInfo, slices.size))
ecc_arb.io.in <> VecInit(slices.map(_.io.ctl_ecc))
c.module.ecc <> ecc_arb.io.out
}
if(ctrl_unit.isEmpty){
if (ctrl_unit.isEmpty) {
slices.foreach(_.io.ctl_req <> DontCare)
slices.foreach(_.io.ctl_req.valid := false.B)
slices.foreach(_.io.ctl_resp.ready := false.B)
slices.foreach(_.io.ctl_ecc.ready := false.B)
}
node.edges.in.headOption.foreach { n =>
n.client.clients.zipWithIndex.foreach {

View File

@ -23,6 +23,7 @@ import chipsalliance.rocketchip.config.Parameters
import chisel3._
import chisel3.util._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.leftOR
import huancun.noninclusive.{MSHR, ProbeHelper, SliceCtrl}
import huancun.prefetch._
@ -33,18 +34,10 @@ class Slice()(implicit p: Parameters) extends HuanCunModule {
val prefetch = prefetchOpt.map(_ => Flipped(new PrefetchIO))
val ctl_req = Flipped(DecoupledIO(new CtrlReq()))
val ctl_resp = DecoupledIO(new CtrlResp())
val ctl_ecc = DecoupledIO(new EccInfo())
})
val ctrl = cacheParams.ctrl.map(_ => Module(new SliceCtrl()))
if(ctrl.nonEmpty){
ctrl.get.io.req <> io.ctl_req
io.ctl_resp <> ctrl.get.io.resp
} else {
io.ctl_req <> DontCare
io.ctl_resp <> DontCare
io.ctl_req.ready := false.B
io.ctl_resp.valid := false.B
}
def ctrl_arb[T <: Data](source: DecoupledIO[T], ctrl: Option[DecoupledIO[T]]): DecoupledIO[T] ={
if(ctrl.nonEmpty){
@ -558,4 +551,22 @@ class Slice()(implicit p: Parameters) extends HuanCunModule {
sinkA.io.a_pb_pop <> sourceA.io.pb_pop
sinkA.io.a_pb_beat <> sourceA.io.pb_beat
if (ctrl.nonEmpty) {
ctrl.get.io.req <> io.ctl_req
io.ctl_resp <> ctrl.get.io.resp
io.ctl_ecc <> DontCare
val eccMask = Cat(ms.map(m => m.io.ecc.errCode =/= 0.U && m.io.status.valid))
val valid_eccMask = ~(leftOR(eccMask) << 1) & eccMask
val ms_errCode = VecInit(ms.map(_.io.ecc.errCode))(OHToUInt(valid_eccMask))
io.ctl_ecc.bits.errCode := Mux(dataStorage.io.ecc.errCode =/= 0.U, dataStorage.io.ecc.errCode, ms_errCode)
io.ctl_ecc.valid := Cat(eccMask).orR()
} else {
io.ctl_req <> DontCare
io.ctl_resp <> DontCare
io.ctl_ecc <> DontCare
io.ctl_req.ready := false.B
io.ctl_resp.valid := false.B
io.ctl_ecc.valid := false.B
}
}

View File

@ -694,12 +694,23 @@ class MSHR()(implicit p: Parameters) extends BaseMSHR[DirResult, SelfDirWrite, S
})
}
def handleEcc() = {
// assert(!io.dirResult.bits.self.hit || !io.dirResult.bits.self.error)
// io.dirResult.bits.clients.foreach(r => assert(!r.hit || !r.error))
when(io.dirResult.bits.self.hit && io.dirResult.bits.self.error) {
io.ecc.errCode := io.ecc.ERR_SELF_DIR
}
when(Cat(io.dirResult.bits.clients.map{r => r.hit && r.error}).orR()) {
io.ecc.errCode := io.ecc.ERR_CLIENT_DIR
}
}
io.ecc.errCode := io.ecc.ERR_NO
when(io.dirResult.valid) {
reset_all_flags()
assert(!io.dirResult.bits.self.hit || !io.dirResult.bits.self.error)
io.dirResult.bits.clients.foreach(r => assert(!r.hit || !r.error))
handleEcc()
when(req.fromC) {
c_schedule()

View File

@ -85,6 +85,8 @@ class SliceCtrl()(implicit p: Parameters) extends HuanCunModule {
io.dir_read.bits.idOH := Cat(req_reg.way, "b11".U)
io.dir_read.bits.tag := req_reg.tag
io.dir_read.bits.set := req_reg.set
io.dir_read.bits.way := req_reg.way
io.dir_read.bits.wayMode := false.B // TODO: it seems incorrect
io.dir_read.bits.replacerInfo := DontCare
io.dir_read.bits.source := DontCare

View File

@ -0,0 +1,21 @@
package huancun.utils
import chipsalliance.rocketchip.config.Parameters
import chisel3._
import chisel3.util._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
class NoopNode()(implicit p: Parameters) extends LazyModule {
val clientParameters = TLMasterPortParameters.v1(
Seq(TLMasterParameters.v1(
name = "dcache",
sourceId = IdRange(0, 1)
))
)
val clientNode = TLClientNode(Seq(clientParameters))
lazy val module = new LazyModuleImp(this)
}