1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.cache 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import utils._ 22import chisel3.util._ 23import freechips.rocketchip.tilelink.{ClientMetadata, TLClientParameters, TLEdgeOut} 24import utils.{Code, ParallelOR, ReplacementPolicy, SRAMTemplate, XSDebug, XSPerfAccumulate} 25import xiangshan.L1CacheErrorInfo 26 27import scala.math.max 28 29class L1BankedDataReadReq(implicit p: Parameters) extends DCacheBundle 30{ 31 val way_en = Bits(DCacheWays.W) 32 val addr = Bits(PAddrBits.W) 33} 34 35class L1BankedDataReadLineReq(implicit p: Parameters) extends L1BankedDataReadReq 36{ 37 val rmask = Bits(DCacheBanks.W) 38} 39 40// Now, we can write a cache-block in a single cycle 41class L1BankedDataWriteReq(implicit p: Parameters) extends L1BankedDataReadReq 42{ 43 val wmask = Bits(DCacheBanks.W) 44 val data = Vec(DCacheBanks, Bits(DCacheSRAMRowBits.W)) 45} 46 47class L1BankedDataReadResult(implicit p: Parameters) extends DCacheBundle 48{ 49 // you can choose which bank to read to save power 50 val ecc = Bits(eccBits.W) 51 val raw_data = Bits(DCacheSRAMRowBits.W) 52 val error_delayed = Bool() // 1 cycle later than data resp 53 54 def asECCData() = { 55 Cat(ecc, raw_data) 56 } 57} 58 59// Banked DCache Data 60// ----------------------------------------------------------------- 61// | Bank0 | Bank1 | Bank2 | Bank3 | Bank4 | Bank5 | Bank6 | Bank7 | 62// ----------------------------------------------------------------- 63// | Way0 | Way0 | Way0 | Way0 | Way0 | Way0 | Way0 | Way0 | 64// | Way1 | Way1 | Way1 | Way1 | Way1 | Way1 | Way1 | Way1 | 65// | .... | .... | .... | .... | .... | .... | .... | .... | 66// ----------------------------------------------------------------- 67abstract class AbstractBankedDataArray(implicit p: Parameters) extends DCacheModule 68{ 69 val ReadlinePortErrorIndex = LoadPipelineWidth 70 val io = IO(new DCacheBundle { 71 // load pipeline read word req 72 val read = Vec(LoadPipelineWidth, Flipped(DecoupledIO(new L1BankedDataReadReq))) 73 // main pipeline read / write line req 74 val readline_intend = Input(Bool()) 75 val readline = Flipped(DecoupledIO(new L1BankedDataReadLineReq)) 76 val write = Flipped(DecoupledIO(new L1BankedDataWriteReq)) 77 // data bank read resp (all banks) 78 val resp = Output(Vec(DCacheBanks, new L1BankedDataReadResult())) 79 val resp_dup_0 = Output(Vec(DCacheBanks, new L1BankedDataReadResult())) 80 // val nacks = Output(Vec(LoadPipelineWidth, Bool())) 81 // val errors = Output(Vec(LoadPipelineWidth + 1, new L1CacheErrorInfo)) // read ports + readline port 82 val read_error_delayed = Output(Vec(LoadPipelineWidth, Bool())) 83 val readline_error_delayed = Output(Bool()) 84 // when bank_conflict, read (1) port should be ignored 85 val bank_conflict_slow = Output(Vec(LoadPipelineWidth, Bool())) 86 val bank_conflict_fast = Output(Vec(LoadPipelineWidth, Bool())) 87 val disable_ld_fast_wakeup = Output(Vec(LoadPipelineWidth, Bool())) 88 // customized cache op port 89 val cacheOp = Flipped(new L1CacheInnerOpIO) 90 val cacheOp_req_dups = Vec(8, Flipped(Valid(new CacheCtrlReqInfo))) 91 val cacheOp_req_bits_opCode_dups = Input(Vec(8, UInt(XLEN.W))) 92 }) 93 94 def pipeMap[T <: Data](f: Int => T) = VecInit((0 until LoadPipelineWidth).map(f)) 95 96 def dumpRead() = { 97 (0 until LoadPipelineWidth) map { w => 98 when(io.read(w).valid) { 99 XSDebug(s"DataArray Read channel: $w valid way_en: %x addr: %x\n", 100 io.read(w).bits.way_en, io.read(w).bits.addr) 101 } 102 } 103 when(io.readline.valid) { 104 XSDebug(s"DataArray Read Line, valid way_en: %x addr: %x rmask %x\n", 105 io.readline.bits.way_en, io.readline.bits.addr, io.readline.bits.rmask) 106 } 107 } 108 109 def dumpWrite() = { 110 when(io.write.valid) { 111 XSDebug(s"DataArray Write valid way_en: %x addr: %x\n", 112 io.write.bits.way_en, io.write.bits.addr) 113 114 (0 until DCacheBanks) map { r => 115 XSDebug(s"cycle: $r data: %x wmask: %x\n", 116 io.write.bits.data(r), io.write.bits.wmask(r)) 117 } 118 } 119 } 120 121 def dumpResp() = { 122 XSDebug(s"DataArray ReadeResp channel:\n") 123 (0 until DCacheBanks) map { r => 124 XSDebug(s"cycle: $r data: %x\n", io.resp(r).raw_data) 125 } 126 } 127 128 def dump() = { 129 dumpRead 130 dumpWrite 131 dumpResp 132 } 133} 134 135class BankedDataArray(implicit p: Parameters) extends AbstractBankedDataArray { 136 def getECCFromEncWord(encWord: UInt) = { 137 require(encWord.getWidth == encWordBits) 138 encWord(encWordBits - 1, wordBits) 139 } 140 141 val ReduceReadlineConflict = false 142 143 io.write.ready := true.B 144 145 // wrap data rows of 8 ways 146 class DataSRAMBank(index: Int) extends Module { 147 val io = IO(new Bundle() { 148 val w = new Bundle() { 149 val en = Input(Bool()) 150 val addr = Input(UInt()) 151 val way_en = Input(UInt(DCacheWays.W)) 152 val data = Input(UInt(DCacheSRAMRowBits.W)) 153 } 154 155 val r = new Bundle() { 156 val en = Input(Bool()) 157 val addr = Input(UInt()) 158 val way_en = Input(UInt(DCacheWays.W)) 159 val data = Output(UInt(DCacheSRAMRowBits.W)) 160 val data_dup_0 = Output(UInt(DCacheSRAMRowBits.W)) 161 } 162 }) 163 164 val r_way_en_reg = RegNext(io.r.way_en) 165 val r_way_en_reg_dup_0 = RegNext(io.r.way_en) 166 167 // multiway data bank 168 val data_bank = Array.fill(DCacheWays) { 169 Module(new SRAMTemplate( 170 Bits(DCacheSRAMRowBits.W), 171 set = DCacheSets, 172 way = 1, 173 shouldReset = false, 174 holdRead = false, 175 singlePort = true 176 )) 177 } 178 179 for (w <- 0 until DCacheWays) { 180 val wen = io.w.en && io.w.way_en(w) 181 data_bank(w).io.w.req.valid := wen 182 data_bank(w).io.w.req.bits.apply( 183 setIdx = io.w.addr, 184 data = io.w.data, 185 waymask = 1.U 186 ) 187 data_bank(w).io.r.req.valid := io.r.en 188 data_bank(w).io.r.req.bits.apply(setIdx = io.r.addr) 189 } 190 191 val half = nWays / 2 192 val data_read = data_bank.map(_.io.r.resp.data(0)) 193 val data_left = Mux1H(r_way_en_reg.tail(half), data_read.take(half)) 194 val data_left_dup_0 = Mux1H(r_way_en_reg_dup_0.tail(half), data_read.take(half)) 195 val data_right = Mux1H(r_way_en_reg.head(half), data_read.drop(half)) 196 val data_right_dup_0 = Mux1H(r_way_en_reg_dup_0.head(half), data_read.drop(half)) 197 198 val sel_low = r_way_en_reg.tail(half).orR() 199 val sel_low_dup_0 = r_way_en_reg_dup_0.tail(half).orR() 200 val row_data = Mux(sel_low, data_left, data_right) 201 val row_data_dup_0 = Mux(sel_low_dup_0, data_left_dup_0, data_right_dup_0) 202 203 io.r.data := row_data 204 io.r.data_dup_0 := row_data_dup_0 205 206 def dump_r() = { 207 when(RegNext(io.r.en)) { 208 XSDebug("bank read addr %x way_en %x data %x\n", 209 RegNext(io.r.addr), 210 RegNext(io.r.way_en), 211 io.r.data 212 ) 213 } 214 } 215 216 def dump_w() = { 217 when(io.w.en) { 218 XSDebug("bank write addr %x way_en %x data %x\n", 219 io.w.addr, 220 io.w.way_en, 221 io.w.data 222 ) 223 } 224 } 225 226 def dump() = { 227 dump_w() 228 dump_r() 229 } 230 } 231 232 val data_banks = List.tabulate(DCacheBanks)(i => Module(new DataSRAMBank(i))) 233 val ecc_banks = List.fill(DCacheBanks)(Module(new SRAMTemplate( 234 Bits(eccBits.W), 235 set = DCacheSets, 236 way = DCacheWays, 237 shouldReset = false, 238 holdRead = false, 239 singlePort = true 240 ))) 241 242 data_banks.map(_.dump()) 243 244 val way_en = Wire(Vec(LoadPipelineWidth, io.read(0).bits.way_en.cloneType)) 245 val way_en_reg = RegNext(way_en) 246 val set_addrs = Wire(Vec(LoadPipelineWidth, UInt())) 247 val bank_addrs = Wire(Vec(LoadPipelineWidth, UInt())) 248 249 // read data_banks and ecc_banks 250 // for single port SRAM, do not allow read and write in the same cycle 251 val rwhazard = io.write.valid 252 val rrhazard = false.B // io.readline.valid 253 (0 until LoadPipelineWidth).map(rport_index => { 254 set_addrs(rport_index) := addr_to_dcache_set(io.read(rport_index).bits.addr) 255 bank_addrs(rport_index) := addr_to_dcache_bank(io.read(rport_index).bits.addr) 256 257 io.read(rport_index).ready := !(rwhazard || rrhazard) 258 259 // use way_en to select a way after data read out 260 assert(!(RegNext(io.read(rport_index).fire() && PopCount(io.read(rport_index).bits.way_en) > 1.U))) 261 way_en(rport_index) := io.read(rport_index).bits.way_en 262 }) 263 io.readline.ready := !(rwhazard) 264 265 // read each bank, get bank result 266 val bank_result = Wire(Vec(DCacheBanks, new L1BankedDataReadResult())) 267 val bank_result_dup_0 = Wire(Vec(DCacheBanks, new L1BankedDataReadResult())) 268 dontTouch(bank_result) 269 val read_bank_error_delayed = Wire(Vec(DCacheBanks, Bool())) 270 dontTouch(read_bank_error_delayed) 271 val rr_bank_conflict = Seq.tabulate(LoadPipelineWidth)(x => Seq.tabulate(LoadPipelineWidth)(y => 272 bank_addrs(x) === bank_addrs(y) && io.read(x).valid && io.read(y).valid 273 )) 274 val rrl_bank_conflict = Wire(Vec(LoadPipelineWidth, Bool())) 275 if (ReduceReadlineConflict) { 276 (0 until LoadPipelineWidth).foreach(i => rrl_bank_conflict(i) := io.read(i).valid && io.readline.valid && io.readline.bits.rmask(bank_addrs(i))) 277 } else { 278 (0 until LoadPipelineWidth).foreach(i => rrl_bank_conflict(i) := io.read(i).valid && io.readline.valid) 279 } 280 val rrl_bank_conflict_intend = Wire(Vec(LoadPipelineWidth, Bool())) 281 if (ReduceReadlineConflict) { 282 (0 until LoadPipelineWidth).foreach(i => rrl_bank_conflict_intend(i) := io.read(i).valid && io.readline_intend && io.readline.bits.rmask(bank_addrs(i))) 283 } else { 284 (0 until LoadPipelineWidth).foreach(i => rrl_bank_conflict_intend(i) := io.read(i).valid && io.readline_intend) 285 } 286 287 val rw_bank_conflict = VecInit(Seq.tabulate(LoadPipelineWidth)(io.read(_).valid && rwhazard)) 288 val perf_multi_read = PopCount(io.read.map(_.valid)) >= 2.U 289 (0 until LoadPipelineWidth).foreach(i => { 290 io.bank_conflict_fast(i) := rw_bank_conflict(i) || rrl_bank_conflict(i) || 291 (if (i == 0) 0.B else (0 until i).map(rr_bank_conflict(_)(i)).reduce(_ || _)) 292 io.bank_conflict_slow(i) := RegNext(io.bank_conflict_fast(i)) 293 io.disable_ld_fast_wakeup(i) := rw_bank_conflict(i) || rrl_bank_conflict_intend(i) || 294 (if (i == 0) 0.B else (0 until i).map(rr_bank_conflict(_)(i)).reduce(_ || _)) 295 }) 296 XSPerfAccumulate("data_array_multi_read", perf_multi_read) 297 (1 until LoadPipelineWidth).foreach(y => (0 until y).foreach(x => 298 XSPerfAccumulate(s"data_array_rr_bank_conflict_${x}_${y}", rr_bank_conflict(x)(y)) 299 )) 300 (0 until LoadPipelineWidth).foreach(i => { 301 XSPerfAccumulate(s"data_array_rrl_bank_conflict_${i}", rrl_bank_conflict(i)) 302 XSPerfAccumulate(s"data_array_rw_bank_conflict_${i}", rw_bank_conflict(i)) 303 XSPerfAccumulate(s"data_array_read_${i}", io.read(i).valid) 304 }) 305 XSPerfAccumulate("data_array_access_total", PopCount(io.read.map(_.valid))) 306 XSPerfAccumulate("data_array_read_line", io.readline.valid) 307 XSPerfAccumulate("data_array_write", io.write.valid) 308 309 for (bank_index <- 0 until DCacheBanks) { 310 // Set Addr & Read Way Mask 311 // 312 // Pipe 0 .... Pipe (n-1) 313 // + .... + 314 // | .... | 315 // +----+---------------+-----+ 316 // X X 317 // X +------+ Bank Addr Match 318 // +---------+----------+ 319 // | 320 // +--------+--------+ 321 // | Data Bank | 322 // +-----------------+ 323 val bank_addr_matchs = WireInit(VecInit(List.tabulate(LoadPipelineWidth)(i => { 324 bank_addrs(i) === bank_index.U && io.read(i).valid 325 }))) 326 val readline_match = Wire(Bool()) 327 if (ReduceReadlineConflict) { 328 readline_match := io.readline.valid && io.readline.bits.rmask(bank_index) 329 } else { 330 readline_match := io.readline.valid 331 } 332 val bank_way_en = Mux(readline_match, 333 io.readline.bits.way_en, 334 PriorityMux(Seq.tabulate(LoadPipelineWidth)(i => bank_addr_matchs(i) -> way_en(i))) 335 ) 336 val bank_set_addr = Mux(readline_match, 337 addr_to_dcache_set(io.readline.bits.addr), 338 PriorityMux(Seq.tabulate(LoadPipelineWidth)(i => bank_addr_matchs(i) -> set_addrs(i))) 339 ) 340 341 val read_enable = bank_addr_matchs.asUInt.orR || readline_match 342 343 // read raw data 344 val data_bank = data_banks(bank_index) 345 data_bank.io.r.en := read_enable 346 data_bank.io.r.way_en := bank_way_en 347 data_bank.io.r.addr := bank_set_addr 348 bank_result(bank_index).raw_data := data_bank.io.r.data 349 bank_result_dup_0(bank_index).raw_data := data_bank.io.r.data_dup_0 350 351 // read ECC 352 val ecc_bank = ecc_banks(bank_index) 353 ecc_bank.io.r.req.valid := read_enable 354 ecc_bank.io.r.req.bits.apply(setIdx = bank_set_addr) 355 bank_result(bank_index).ecc := Mux1H(RegNext(bank_way_en), ecc_bank.io.r.resp.data) 356 bank_result_dup_0(bank_index).ecc := Mux1H(RegNext(bank_way_en), ecc_bank.io.r.resp.data) 357 358 // use ECC to check error 359 val ecc_data = bank_result(bank_index).asECCData() 360 val ecc_data_delayed = RegEnable(ecc_data, RegNext(read_enable)) 361 bank_result(bank_index).error_delayed := dcacheParameters.dataCode.decode(ecc_data_delayed).error 362 bank_result_dup_0(bank_index).error_delayed := dcacheParameters.dataCode.decode(ecc_data_delayed).error 363 read_bank_error_delayed(bank_index) := bank_result(bank_index).error_delayed 364 } 365 366 // read result: expose banked read result 367 io.resp := bank_result 368 io.resp_dup_0 := bank_result_dup_0 369 370 // error detection 371 // normal read ports 372 (0 until LoadPipelineWidth).map(rport_index => { 373 io.read_error_delayed(rport_index) := RegNext(RegNext(io.read(rport_index).fire())) && 374 read_bank_error_delayed(RegNext(RegNext(bank_addrs(rport_index)))) && 375 !RegNext(io.bank_conflict_slow(rport_index)) 376 }) 377 // readline port 378 io.readline_error_delayed := RegNext(RegNext(io.readline.fire())) && 379 VecInit((0 until DCacheBanks).map(i => io.resp(i).error_delayed)).asUInt().orR 380 381 // write data_banks & ecc_banks 382 val sram_waddr = addr_to_dcache_set(io.write.bits.addr) 383 for (bank_index <- 0 until DCacheBanks) { 384 // data write 385 val data_bank = data_banks(bank_index) 386 data_bank.io.w.en := io.write.valid && io.write.bits.wmask(bank_index) 387 data_bank.io.w.way_en := io.write.bits.way_en 388 data_bank.io.w.addr := sram_waddr 389 data_bank.io.w.data := io.write.bits.data(bank_index) 390 391 // ecc write 392 val ecc_bank = ecc_banks(bank_index) 393 ecc_bank.io.w.req.valid := io.write.valid && io.write.bits.wmask(bank_index) 394 ecc_bank.io.w.req.bits.apply( 395 setIdx = sram_waddr, 396 data = getECCFromEncWord(cacheParams.dataCode.encode((io.write.bits.data(bank_index)))), 397 waymask = io.write.bits.way_en 398 ) 399 when(ecc_bank.io.w.req.valid) { 400 XSDebug("write in ecc sram: bank %x set %x data %x waymask %x\n", 401 bank_index.U, 402 sram_waddr, 403 getECCFromEncWord(cacheParams.dataCode.encode((io.write.bits.data(bank_index)))), 404 io.write.bits.way_en 405 ); 406 } 407 } 408 409 // deal with customized cache op 410 require(nWays <= 32) 411 io.cacheOp.resp.bits := DontCare 412 val cacheOpShouldResp = WireInit(false.B) 413 val eccReadResult = Wire(Vec(DCacheBanks, UInt(eccBits.W))) 414 when(io.cacheOp.req.valid){ 415 when (CacheInstrucion.isReadData(io.cacheOp.req.bits.opCode)) { 416 for (bank_index <- 0 until (DCacheBanks / 3)) { 417 val data_bank = data_banks(bank_index) 418 data_bank.io.r.en := true.B 419 data_bank.io.r.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 420 data_bank.io.r.addr := io.cacheOp.req.bits.index 421 } 422 cacheOpShouldResp := true.B 423 } 424 when (CacheInstrucion.isReadDataECC(io.cacheOp.req.bits.opCode)) { 425 for (bank_index <- 0 until (DCacheBanks / 3)) { 426 val ecc_bank = ecc_banks(bank_index) 427 ecc_bank.io.r.req.valid := true.B 428 ecc_bank.io.r.req.bits.setIdx := io.cacheOp.req.bits.index 429 } 430 cacheOpShouldResp := true.B 431 } 432 when(CacheInstrucion.isWriteData(io.cacheOp.req.bits.opCode)){ 433 for (bank_index <- 0 until (DCacheBanks / 3)) { 434 val data_bank = data_banks(bank_index) 435 data_bank.io.w.en := true.B 436 data_bank.io.w.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 437 data_bank.io.w.addr := io.cacheOp.req.bits.index 438 data_bank.io.w.data := io.cacheOp.req.bits.write_data_vec(bank_index) 439 } 440 cacheOpShouldResp := true.B 441 } 442 when(CacheInstrucion.isWriteDataECC(io.cacheOp.req.bits.opCode)){ 443 for (bank_index <- 0 until (DCacheBanks / 3)) { 444 val ecc_bank = ecc_banks(bank_index) 445 ecc_bank.io.w.req.valid := true.B 446 ecc_bank.io.w.req.bits.apply( 447 setIdx = io.cacheOp.req.bits.index, 448 data = io.cacheOp.req.bits.write_data_ecc, 449 waymask = UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 450 ) 451 } 452 cacheOpShouldResp := true.B 453 } 454 } 455 456 when (io.cacheOp_req_dups(0).valid && CacheInstrucion.isReadData(io.cacheOp_req_bits_opCode_dups(0))) { 457 for (bank_index <- (DCacheBanks / 3) until ((DCacheBanks / 3) * 2)) { 458 val data_bank = data_banks(bank_index) 459 data_bank.io.r.en := true.B 460 data_bank.io.r.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 461 data_bank.io.r.addr := io.cacheOp.req.bits.index 462 } 463 cacheOpShouldResp := true.B 464 } 465 when (io.cacheOp_req_dups(1).valid && CacheInstrucion.isReadDataECC(io.cacheOp_req_bits_opCode_dups(1))) { 466 for (bank_index <- (DCacheBanks / 3) until ((DCacheBanks / 3) * 2)) { 467 val ecc_bank = ecc_banks(bank_index) 468 ecc_bank.io.r.req.valid := true.B 469 ecc_bank.io.r.req.bits.setIdx := io.cacheOp.req.bits.index 470 } 471 cacheOpShouldResp := true.B 472 } 473 when(io.cacheOp_req_dups(2).valid && CacheInstrucion.isWriteData(io.cacheOp_req_bits_opCode_dups(2))){ 474 for (bank_index <- (DCacheBanks / 3) until ((DCacheBanks / 3) * 2)) { 475 val data_bank = data_banks(bank_index) 476 data_bank.io.w.en := true.B 477 data_bank.io.w.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 478 data_bank.io.w.addr := io.cacheOp.req.bits.index 479 data_bank.io.w.data := io.cacheOp.req.bits.write_data_vec(bank_index) 480 } 481 cacheOpShouldResp := true.B 482 } 483 when(io.cacheOp_req_dups(3).valid && CacheInstrucion.isWriteDataECC(io.cacheOp_req_bits_opCode_dups(3))){ 484 for (bank_index <- (DCacheBanks / 3) until ((DCacheBanks / 3) * 2)) { 485 val ecc_bank = ecc_banks(bank_index) 486 ecc_bank.io.w.req.valid := true.B 487 ecc_bank.io.w.req.bits.apply( 488 setIdx = io.cacheOp.req.bits.index, 489 data = io.cacheOp.req.bits.write_data_ecc, 490 waymask = UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 491 ) 492 } 493 cacheOpShouldResp := true.B 494 } 495 496 when (io.cacheOp_req_dups(4).valid && CacheInstrucion.isReadData(io.cacheOp_req_bits_opCode_dups(4))) { 497 for (bank_index <- ((DCacheBanks / 3) * 2) until DCacheBanks) { 498 val data_bank = data_banks(bank_index) 499 data_bank.io.r.en := true.B 500 data_bank.io.r.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 501 data_bank.io.r.addr := io.cacheOp.req.bits.index 502 } 503 cacheOpShouldResp := true.B 504 } 505 when (io.cacheOp_req_dups(5).valid && CacheInstrucion.isReadDataECC(io.cacheOp_req_bits_opCode_dups(5))) { 506 for (bank_index <- ((DCacheBanks / 3) * 2) until DCacheBanks) { 507 val ecc_bank = ecc_banks(bank_index) 508 ecc_bank.io.r.req.valid := true.B 509 ecc_bank.io.r.req.bits.setIdx := io.cacheOp.req.bits.index 510 } 511 cacheOpShouldResp := true.B 512 } 513 when(io.cacheOp_req_dups(6).valid && CacheInstrucion.isWriteData(io.cacheOp_req_bits_opCode_dups(6))){ 514 for (bank_index <- ((DCacheBanks / 3) * 2) until DCacheBanks) { 515 val data_bank = data_banks(bank_index) 516 data_bank.io.w.en := true.B 517 data_bank.io.w.way_en := UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 518 data_bank.io.w.addr := io.cacheOp.req.bits.index 519 data_bank.io.w.data := io.cacheOp.req.bits.write_data_vec(bank_index) 520 } 521 cacheOpShouldResp := true.B 522 } 523 when(io.cacheOp_req_dups(7).valid && CacheInstrucion.isWriteDataECC(io.cacheOp_req_bits_opCode_dups(7))){ 524 for (bank_index <- ((DCacheBanks / 3) * 2) until DCacheBanks) { 525 val ecc_bank = ecc_banks(bank_index) 526 ecc_bank.io.w.req.valid := true.B 527 ecc_bank.io.w.req.bits.apply( 528 setIdx = io.cacheOp.req.bits.index, 529 data = io.cacheOp.req.bits.write_data_ecc, 530 waymask = UIntToOH(io.cacheOp.req.bits.wayNum(4, 0)) 531 ) 532 } 533 cacheOpShouldResp := true.B 534 } 535 536 io.cacheOp.resp.valid := RegNext(io.cacheOp.req.valid && cacheOpShouldResp) 537 for (bank_index <- 0 until DCacheBanks) { 538 io.cacheOp.resp.bits.read_data_vec(bank_index) := bank_result(bank_index).raw_data 539 eccReadResult(bank_index) := ecc_banks(bank_index).io.r.resp.data(RegNext(io.cacheOp.req.bits.wayNum(4, 0))) 540 } 541 io.cacheOp.resp.bits.read_data_ecc := Mux(io.cacheOp.resp.valid, 542 eccReadResult(RegNext(io.cacheOp.req.bits.bank_num)), 543 0.U 544 ) 545} 546