未验证 提交 77decb47 编写于 作者: Z zhanglinjuan 提交者: GitHub

dcache: remove redundant ecc array (#1358)

* dcache: fix bug in ecc check

* dcache: remove redundant ecc array

* CacheInstruction: fix typo

* dcache: fix bugs in cache instruction on ecc

* MetaArray: wrap ecc array as a single module
上级 a1351e5d
......@@ -180,7 +180,7 @@ class CSRCacheOpDecoder(decoder_name: String, id: Int)(implicit p: Parameters) e
update_cache_req_when_write("CACHE_BANK_NUM", translated_cache_req.bank_num)
update_cache_req_when_write("CACHE_TAG_HIGH", translated_cache_req.write_tag_high)
update_cache_req_when_write("CACHE_TAG_LOW", translated_cache_req.write_tag_low)
update_cache_req_when_write("CACHE_DATA_ECC", translated_cache_req.write_tag_ecc)
update_cache_req_when_write("CACHE_TAG_ECC", translated_cache_req.write_tag_ecc)
update_cache_req_when_write("CACHE_DATA_0", translated_cache_req.write_data_vec(0))
update_cache_req_when_write("CACHE_DATA_1", translated_cache_req.write_data_vec(1))
update_cache_req_when_write("CACHE_DATA_2", translated_cache_req.write_data_vec(2))
......@@ -239,13 +239,13 @@ class CSRCacheOpDecoder(decoder_name: String, id: Int)(implicit p: Parameters) e
when(schedule_csr_op_resp_data){
io.csr.update.w.bits.addr := Mux1H(List(
isReadTagECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_TAG_ECC")("offset").toInt + Scachebase).U,
isReadDataECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_BANK_NUM")("offset").toInt + Scachebase).U,
isReadDataECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_DATA_ECC")("offset").toInt + Scachebase).U,
isReadTag -> ((CacheInstrucion.CacheInsRegisterList("CACHE_TAG_LOW")("offset").toInt + Scachebase).U + data_transfer_cnt),
isReadData -> ((CacheInstrucion.CacheInsRegisterList("CACHE_DATA_0")("offset").toInt + Scachebase).U + data_transfer_cnt),
))
io.csr.update.w.bits.data := Mux1H(List(
isReadTagECC -> raw_cache_resp.read_tag_ecc,
isReadDataECC -> raw_cache_resp.read_tag_ecc,
isReadDataECC -> raw_cache_resp.read_data_ecc,
isReadTag -> raw_cache_resp.read_tag_low,
isReadData -> raw_cache_resp.read_data_vec(data_transfer_cnt),
))
......
......@@ -372,12 +372,10 @@ class BankedDataArray(implicit p: Parameters) extends AbstractBankedDataArray {
// deal with customized cache op
require(nWays <= 32)
io.cacheOp.resp.bits := DontCare
val cacheOpShouldResp = WireInit(false.B)
val cacheOpShouldResp = WireInit(false.B)
val eccReadResult = Wire(Vec(DCacheBanks, UInt(eccBits.W)))
when(io.cacheOp.req.valid){
when(
CacheInstrucion.isReadData(io.cacheOp.req.bits.opCode) ||
CacheInstrucion.isReadDataECC(io.cacheOp.req.bits.opCode)
){
when (CacheInstrucion.isReadData(io.cacheOp.req.bits.opCode)) {
for (bank_index <- 0 until DCacheBanks) {
val data_bank = data_banks(bank_index)
data_bank.io.r.en := true.B
......@@ -386,6 +384,14 @@ class BankedDataArray(implicit p: Parameters) extends AbstractBankedDataArray {
}
cacheOpShouldResp := true.B
}
when (CacheInstrucion.isReadDataECC(io.cacheOp.req.bits.opCode)) {
for (bank_index <- 0 until DCacheBanks) {
val ecc_bank = ecc_banks(bank_index)
ecc_bank.io.r.req.valid := true.B
ecc_bank.io.r.req.bits.setIdx := io.cacheOp.req.bits.index
}
cacheOpShouldResp := true.B
}
when(CacheInstrucion.isWriteData(io.cacheOp.req.bits.opCode)){
for (bank_index <- 0 until DCacheBanks) {
val data_bank = data_banks(bank_index)
......@@ -412,9 +418,10 @@ class BankedDataArray(implicit p: Parameters) extends AbstractBankedDataArray {
io.cacheOp.resp.valid := RegNext(io.cacheOp.req.valid && cacheOpShouldResp)
for (bank_index <- 0 until DCacheBanks) {
io.cacheOp.resp.bits.read_data_vec(bank_index) := bank_result(bank_index).raw_data
eccReadResult(bank_index) := ecc_banks(bank_index).io.r.resp.data(RegNext(io.cacheOp.req.bits.wayNum(4, 0)))
}
io.cacheOp.resp.bits.read_data_ecc := Mux(io.cacheOp.resp.valid,
bank_result(io.cacheOp.req.bits.bank_num).ecc,
eccReadResult(RegNext(io.cacheOp.req.bits.bank_num)),
0.U
)
}
......@@ -21,6 +21,7 @@ import chipsalliance.rocketchip.config.Parameters
import chisel3._
import chisel3.util._
import xiangshan.L1CacheErrorInfo
import xiangshan.cache.CacheInstrucion._
class Meta(implicit p: Parameters) extends DCacheBundle {
val coh = new ClientMetadata
......@@ -58,6 +59,68 @@ class MetaWriteReq(implicit p: Parameters) extends MetaReadReq {
val tag = UInt(tagBits.W) // used to calculate ecc
}
class ECCReadReq(implicit p: Parameters) extends MetaReadReq
class ECCWriteReq(implicit p: Parameters) extends ECCReadReq {
val ecc = UInt()
}
class AsynchronousECCArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
def metaAndTagOnReset = MetaAndTag(ClientMetadata.onReset, 0.U)
// enc bits encode both tag and meta, but is saved in meta array
val metaAndTagBits = metaAndTagOnReset.getWidth
val encMetaAndTagBits = cacheParams.tagCode.width(metaAndTagBits)
val encMetaBits = encMetaAndTagBits - tagBits
val encBits = encMetaAndTagBits - metaAndTagBits
val io = IO(new Bundle() {
val read = Vec(readPorts, Flipped(ValidIO(new ECCReadReq)))
val resp = Output(Vec(readPorts, Vec(nWays, UInt(encBits.W))))
val write = Vec(writePorts, Flipped(ValidIO(new ECCWriteReq)))
val cacheOp = Flipped(new DCacheInnerOpIO)
})
val ecc_array = Reg(Vec(nSets, Vec(nWays, UInt(encBits.W))))
when (reset.asBool()) {
ecc_array := 0.U.asTypeOf(ecc_array.cloneType)
}
io.read.zip(io.resp).foreach {
case (read, resp) =>
resp := RegEnable(ecc_array(read.bits.idx), read.valid)
}
io.write.foreach {
case write =>
write.bits.way_en.asBools.zipWithIndex.foreach {
case (wen, i) =>
when (write.valid && wen) {
ecc_array(write.bits.idx)(i) := write.bits.ecc
}
}
}
// deal with customized cache op
val cacheOpShouldResp = WireInit(false.B)
when (io.cacheOp.req.valid) {
when (isReadTagECC(io.cacheOp.req.bits.opCode)) {
cacheOpShouldResp := true.B
}
when (isWriteTagECC(io.cacheOp.req.bits.opCode)) {
ecc_array(io.cacheOp.req.bits.index)(io.cacheOp.req.bits.wayNum(4, 0)) :=
io.cacheOp.req.bits.write_tag_ecc
cacheOpShouldResp := true.B
}
}
io.cacheOp.resp.valid := RegNext(io.cacheOp.req.valid && cacheOpShouldResp)
io.cacheOp.resp.bits := DontCare
io.cacheOp.resp.bits.read_tag_ecc := Mux(
io.cacheOp.resp.valid,
RegNext(ecc_array(io.cacheOp.req.bits.index)(io.cacheOp.req.bits.wayNum(4, 0))),
0.U
)
}
class AsynchronousMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
def metaAndTagOnReset = MetaAndTag(ClientMetadata.onReset, 0.U)
......@@ -65,44 +128,47 @@ class AsynchronousMetaArray(readPorts: Int, writePorts: Int)(implicit p: Paramet
val metaAndTagBits = metaAndTagOnReset.getWidth
val encMetaAndTagBits = cacheParams.tagCode.width(metaAndTagBits)
val encMetaBits = encMetaAndTagBits - tagBits
val encBits = encMetaAndTagBits - metaAndTagBits
val io = IO(new Bundle() {
// TODO: this is made of regs, so we don't need to use DecoupledIO
val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
val resp = Output(Vec(readPorts, Vec(nWays, UInt(encMetaBits.W))))
val write = Vec(writePorts, Flipped(DecoupledIO(new MetaWriteReq)))
// customized cache op port
// customized cache op port
val cacheOp = Flipped(new DCacheInnerOpIO)
})
// val meta_array = VecInit(Seq.fill(nSets)(
// VecInit(Seq.fill(nWays)(
// RegInit(0.U(encMetaBits.W))))
// ))
val meta_array = Reg(Vec(nSets, Vec(nWays, UInt(encMetaBits.W))))
val meta_array = Reg(Vec(nSets, Vec(nWays, new Meta)))
val ecc_array = Module(new AsynchronousECCArray(readPorts, writePorts))
when (reset.asBool()) {
meta_array := 0.U.asTypeOf(meta_array.cloneType)
}
io.read.zip(io.resp).foreach {
case (read, resp) =>
(io.read.zip(io.resp)).zipWithIndex.foreach {
case ((read, resp), i) =>
read.ready := true.B
resp := RegEnable(meta_array(read.bits.idx), read.valid)
ecc_array.io.read(i).valid := read.fire()
ecc_array.io.read(i).bits := read.bits
resp := VecInit(RegEnable(meta_array(read.bits.idx), read.valid).zip(
ecc_array.io.resp(i)
).map { case (m, ecc) => Cat(ecc, m.asUInt) })
}
io.write.foreach {
case write =>
io.write.zip(ecc_array.io.write).foreach {
case (write, ecc_write) =>
write.ready := true.B
val ecc = cacheParams.tagCode.encode(MetaAndTag(write.bits.meta.coh, write.bits.tag).asUInt)(encMetaAndTagBits - 1, metaAndTagBits)
val encMeta = Cat(ecc, write.bits.meta.asUInt)
require(encMeta.getWidth == encMetaBits)
ecc_write.valid := write.fire()
ecc_write.bits.idx := write.bits.idx
ecc_write.bits.way_en := write.bits.way_en
ecc_write.bits.ecc := ecc
write.bits.way_en.asBools.zipWithIndex.foreach {
case (wen, i) =>
when (write.valid && wen) {
meta_array(write.bits.idx)(i) := encMeta
meta_array(write.bits.idx)(i) := write.bits.meta
}
}
}
// deal with customized cache op
io.cacheOp.resp := DontCare // TODO
}
ecc_array.io.cacheOp <> io.cacheOp
}
\ No newline at end of file
......@@ -39,8 +39,8 @@ class TagArray(implicit p: Parameters) extends DCacheModule {
val read = Flipped(DecoupledIO(new TagReadReq))
val resp = Output(Vec(nWays, UInt(tagBits.W)))
val write = Flipped(DecoupledIO(new TagWriteReq))
val ecc_write = Flipped(DecoupledIO(new TagEccWriteReq))
val ecc_resp = Output(Vec(nWays, UInt(eccTagBits.W)))
// val ecc_write = Flipped(DecoupledIO(new TagEccWriteReq))
// val ecc_resp = Output(Vec(nWays, UInt(eccTagBits.W)))
})
// TODO: reset is unnecessary?
val rst_cnt = RegInit(0.U(log2Up(nSets + 1).W))
......@@ -57,8 +57,8 @@ class TagArray(implicit p: Parameters) extends DCacheModule {
val tag_array = Module(new SRAMTemplate(UInt(tagBits.W), set = nSets, way = nWays,
shouldReset = false, holdRead = false, singlePort = true))
val ecc_array = Module(new SRAMTemplate(UInt(eccTagBits.W), set = nSets, way = nWays,
shouldReset = false, holdRead = false, singlePort = true))
// val ecc_array = Module(new SRAMTemplate(UInt(eccTagBits.W), set = nSets, way = nWays,
// shouldReset = false, holdRead = false, singlePort = true))
// tag write
def getECCFromEncTag(encTag: UInt) = {
......@@ -73,12 +73,12 @@ class TagArray(implicit p: Parameters) extends DCacheModule {
data = wdata,
waymask = VecInit(wmask).asUInt()
)
ecc_array.io.w.req.valid := wen
ecc_array.io.w.req.bits.apply(
setIdx = waddr,
data = getECCFromEncTag(cacheParams.tagCode.encode(wdata)),
waymask = VecInit(wmask).asUInt()
)
// ecc_array.io.w.req.valid := wen
// ecc_array.io.w.req.bits.apply(
// setIdx = waddr,
// data = getECCFromEncTag(cacheParams.tagCode.encode(wdata)),
// waymask = VecInit(wmask).asUInt()
// )
// tag read
val ren = io.read.fire()
......@@ -87,23 +87,23 @@ class TagArray(implicit p: Parameters) extends DCacheModule {
tag_array.io.r.req.bits.apply(setIdx = io.read.bits.idx)
io.resp := tag_array.io.r.resp.data
ecc_array.io.r.req.valid := ren
ecc_array.io.r.req.bits.apply(setIdx = io.read.bits.idx)
io.ecc_resp := ecc_array.io.r.resp.data
// cache op tag ecc write
val ecc_force_wen = io.ecc_write.valid
ecc_array.io.w.req.valid := ecc_force_wen
when(ecc_force_wen){
ecc_array.io.w.req.bits.apply(
setIdx = io.ecc_write.bits.idx,
data = io.ecc_write.bits.ecc,
waymask = io.ecc_write.bits.way_en
)
}
// ecc_array.io.r.req.valid := ren
// ecc_array.io.r.req.bits.apply(setIdx = io.read.bits.idx)
// io.ecc_resp := ecc_array.io.r.resp.data
//
// // cache op tag ecc write
// val ecc_force_wen = io.ecc_write.valid
// ecc_array.io.w.req.valid := ecc_force_wen
// when(ecc_force_wen){
// ecc_array.io.w.req.bits.apply(
// setIdx = io.ecc_write.bits.idx,
// data = io.ecc_write.bits.ecc,
// waymask = io.ecc_write.bits.way_en
// )
// }
io.write.ready := !rst
io.ecc_write.ready := !rst
// io.ecc_write.ready := !rst
io.read.ready := !wen
}
......@@ -125,8 +125,8 @@ class DuplicatedTagArray(readPorts: Int)(implicit p: Parameters) extends DCacheM
array(i).io.read <> io.read(i)
io.resp(i) <> array(i).io.resp
// extra ports for cache op
array(i).io.ecc_write.valid := false.B
array(i).io.ecc_write.bits := DontCare
// array(i).io.ecc_write.valid := false.B
// array(i).io.ecc_write.bits := DontCare
}
io.write.ready := true.B
......@@ -136,8 +136,8 @@ class DuplicatedTagArray(readPorts: Int)(implicit p: Parameters) extends DCacheM
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)
CacheInstrucion.isReadTag(io.cacheOp.req.bits.opCode)/* ||
CacheInstrucion.isReadTagECC(io.cacheOp.req.bits.opCode)*/
){
for (i <- 0 until readPorts) {
array(i).io.read.valid := true.B
......@@ -155,18 +155,18 @@ class DuplicatedTagArray(readPorts: Int)(implicit p: Parameters) extends DCacheM
}
cacheOpShouldResp := true.B
}
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
}
// 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, array(0).io.resp(io.cacheOp.req.bits.wayNum), 0.U)
io.cacheOp.resp.bits.read_tag_ecc := Mux(io.cacheOp.resp.valid, array(0).io.ecc_resp(io.cacheOp.req.bits.wayNum), 0.U)
// io.cacheOp.resp.bits.read_tag_ecc := Mux(io.cacheOp.resp.valid, array(0).io.ecc_resp(io.cacheOp.req.bits.wayNum), 0.U)
// TODO: deal with duplicated array
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册