1package xiangshan.cache 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import xiangshan.frontend.icache._ 7import utils._ 8import utility._ 9import chipsalliance.rocketchip.config.Parameters 10import xiangshan.backend.fu.util.HasCSRConst 11 12object CacheOpMap{ 13 def apply(opcode: String, optype: String, name: String ): Map[String, String] = { 14 Map( 15 "opcode" -> opcode, 16 "optype" -> optype, 17 "name" -> name, 18 ) 19 } 20} 21 22object CacheRegMap{ 23 def apply(offset: String, width: String, authority: String, name: String ): Pair[String, Map[String, String]] = { 24 name -> Map( 25 "offset" -> offset, 26 "width" -> width, 27 "authority" -> authority, 28 ) 29 } 30} 31 32trait CacheControlConst{ 33 def maxDataRowSupport = 8 34} 35 36abstract class CacheCtrlModule(implicit p: Parameters) extends XSModule with HasCSRConst with CacheControlConst 37 38object CacheInstrucion{ 39 def CacheOperation = List( 40 CacheOpMap("b00000", "CHECK", "READ_TAG_ECC"), 41 CacheOpMap("b00001", "CHECK", "READ_DATA_ECC"), 42 CacheOpMap("b00010", "LOAD", "READ_TAG"), 43 CacheOpMap("b00011", "LOAD", "READ_DATA"), 44 CacheOpMap("b00100", "STORE", "WRITE_TAG_ECC"), 45 CacheOpMap("b00101", "STORE", "WRITE_DATA_ECC"), 46 CacheOpMap("b00110", "STORE", "WRITE_TAG"), 47 CacheOpMap("b00111", "STORE", "WRITE_DATA"), 48 CacheOpMap("b01000", "FLUSH", "FLUSH_BLOCK") 49 ) 50 51 def CacheInsRegisterList = Map( 52 // offset width authority name 53 CacheRegMap("0", "64", "RW", "CACHE_OP"), 54 CacheRegMap("1", "64", "RW", "OP_FINISH"), 55 CacheRegMap("2", "64", "RW", "CACHE_LEVEL"), 56 CacheRegMap("3", "64", "RW", "CACHE_WAY"), 57 CacheRegMap("4", "64", "RW", "CACHE_IDX"), 58 CacheRegMap("5", "64", "RW", "CACHE_BANK_NUM"), 59 CacheRegMap("6", "64", "RW", "CACHE_TAG_ECC"), 60 CacheRegMap("7", "64", "RW", "CACHE_TAG_BITS"), // TODO 61 CacheRegMap("8", "64", "RW", "CACHE_TAG_LOW"), 62 CacheRegMap("9", "64", "RW", "CACHE_TAG_HIGH"), // not used in 64 bit arch 63 CacheRegMap("10", "64", "RW", "CACHE_ECC_WIDTH"), // TODO 64 CacheRegMap("11", "64", "RW", "CACHE_DATA_ECC"), 65 CacheRegMap("12", "64", "RW", "CACHE_DATA_0"), 66 CacheRegMap("13", "64", "RW", "CACHE_DATA_1"), 67 CacheRegMap("14", "64", "RW", "CACHE_DATA_2"), 68 CacheRegMap("15", "64", "RW", "CACHE_DATA_3"), 69 CacheRegMap("16", "64", "RW", "CACHE_DATA_4"), 70 CacheRegMap("17", "64", "RW", "CACHE_DATA_5"), 71 CacheRegMap("18", "64", "RW", "CACHE_DATA_6"), 72 CacheRegMap("19", "64", "RW", "CACHE_DATA_7"), 73 CacheRegMap("20", "64", "RW", "CACHE_ERROR"), 74 ) 75 76 // Usage: 77 // val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 78 // doSthWith(name, attribute("offset"), attribute("width")) 79 // }} 80 81 def COP_CHECK = 0.U 82 def COP_LOAD = 1.U 83 def COP_STORE = 2.U 84 def COP_FLUSH = 3.U 85 86 def COP_ID_ICACHE = 0 87 def COP_ID_DCACHE = 1 88 89 def COP_RESULT_CODE_IDLE = 0.U 90 def COP_RESULT_CODE_OK = 1.U 91 def COP_RESULT_CODE_ERROR = 2.U 92 93 def isReadTagECC(opcode: UInt) = opcode === "b00000".U 94 def isReadDataECC(opcode: UInt) = opcode === "b00001".U 95 def isReadTag(opcode: UInt) = opcode === "b00010".U 96 def isReadData(opcode: UInt) = opcode === "b00011".U 97 def isWriteTagECC(opcode: UInt) = opcode === "b00100".U 98 def isWriteDataECC(opcode: UInt) = opcode === "b00101".U 99 def isWriteTag(opcode: UInt) = opcode === "b00110".U 100 def isWriteData(opcode: UInt) = opcode === "b00111".U 101 def isFlush(opcode: UInt) = opcode === "b01000".U 102 103 def isReadOp(opcode: UInt) = isReadTagECC(opcode) || 104 isReadDataECC(opcode) || 105 isReadTag(opcode) || 106 isReadData(opcode) 107} 108 109class CacheCtrlReqInfo(implicit p: Parameters) extends XSBundle with CacheControlConst { 110 val level = UInt(XLEN.W) // op target id 111 val wayNum = UInt(XLEN.W) 112 val index = UInt(XLEN.W) 113 val opCode = UInt(XLEN.W) 114 val write_tag_high = UInt(XLEN.W) 115 val write_tag_low = UInt(XLEN.W) 116 val write_tag_ecc = UInt(XLEN.W) 117 val write_data_vec = Vec(maxDataRowSupport, UInt(XLEN.W)) 118 val write_data_ecc = UInt(XLEN.W) 119 val bank_num = UInt(XLEN.W) 120} 121 122class CacheCtrlRespInfo(implicit p: Parameters) extends XSBundle with HasICacheParameters with CacheControlConst{ 123 val read_tag_high = UInt(XLEN.W) 124 val read_tag_low = UInt(XLEN.W) 125 val read_tag_ecc = UInt(XLEN.W) 126 val read_data_vec = Vec(maxDataRowSupport, UInt(XLEN.W)) 127 val read_data_ecc = UInt(XLEN.W) 128 val bank_num = UInt(XLEN.W) 129} 130 131class L1CacheToCsrIO(implicit p: Parameters) extends DCacheBundle { 132 val distribute_csr = Flipped(new DistributedCSRIO) 133 val update = new DistributedCSRUpdateReq 134} 135 136class L1CacheInnerOpIO(implicit p: Parameters) extends DCacheBundle { 137 val req = Valid(new CacheCtrlReqInfo) 138 val resp = Flipped(Valid(new CacheCtrlRespInfo)) 139} 140 141class CSRCacheOpDecoder(decoder_name: String, id: Int)(implicit p: Parameters) extends CacheCtrlModule { 142 val io = IO(new Bundle { 143 val csr = new L1CacheToCsrIO 144 val cache = new L1CacheInnerOpIO 145 val cache_req_dup = Vec(11, Valid(new CacheCtrlReqInfo)) 146 val cacheOp_req_bits_opCode_dup = Output(Vec(11, UInt(XLEN.W))) 147 val error = Flipped(new L1CacheErrorInfo) 148 }) 149 150 // CSRCacheOpDecoder state 151 val wait_csr_op_req = RegInit(true.B) // waiting for csr "CACHE_OP" being write 152 val wait_cache_op_resp = RegInit(false.B) // waiting for dcache to finish dcache op 153 val schedule_csr_op_resp_data = RegInit(false.B) // ready to write data readed from cache back to csr 154 val schedule_csr_op_resp_finish = RegInit(false.B) // ready to write "OP_FINISH" csr 155 // val cache_op_resp_timer = RegInit(0.U(4.W)) 156 val data_transfer_finished = WireInit(false.B) 157 val data_transfer_cnt = RegInit(0.U(log2Up(maxDataRowSupport).W)) 158 159 // Translate CSR write to cache op 160 val translated_cache_req = Reg(new CacheCtrlReqInfo) 161 val translated_cache_req_opCode_dup = Reg(Vec(11, UInt(XLEN.W))) 162 println("Cache op decoder (" + decoder_name + "):") 163 println(" Id " + id) 164 // CacheInsRegisterList.map{case (name, attribute) => { 165 // println(" Register CSR mirror " + name) 166 // }} 167 168 def cacheop_csr_is_being_write(csr_name: String): Bool = { 169 io.csr.distribute_csr.w.bits.addr === (CacheInstrucion.CacheInsRegisterList(csr_name)("offset").toInt + Scachebase).U && 170 io.csr.distribute_csr.w.valid 171 } 172 173 def update_cache_req_when_write(csr_name: String, req_field: Data) = { 174 when( 175 cacheop_csr_is_being_write(csr_name) 176 ){ 177 req_field := io.csr.distribute_csr.w.bits.data 178 assert(wait_csr_op_req) 179 } 180 } 181 182 update_cache_req_when_write("CACHE_OP", translated_cache_req.opCode) 183 translated_cache_req_opCode_dup.map(dup => update_cache_req_when_write("CACHE_OP", dup)) 184 update_cache_req_when_write("CACHE_LEVEL", translated_cache_req.level) 185 update_cache_req_when_write("CACHE_WAY", translated_cache_req.wayNum) 186 update_cache_req_when_write("CACHE_IDX", translated_cache_req.index) 187 update_cache_req_when_write("CACHE_BANK_NUM", translated_cache_req.bank_num) 188 update_cache_req_when_write("CACHE_TAG_HIGH", translated_cache_req.write_tag_high) 189 update_cache_req_when_write("CACHE_TAG_LOW", translated_cache_req.write_tag_low) 190 update_cache_req_when_write("CACHE_TAG_ECC", translated_cache_req.write_tag_ecc) 191 update_cache_req_when_write("CACHE_DATA_0", translated_cache_req.write_data_vec(0)) 192 update_cache_req_when_write("CACHE_DATA_1", translated_cache_req.write_data_vec(1)) 193 update_cache_req_when_write("CACHE_DATA_2", translated_cache_req.write_data_vec(2)) 194 update_cache_req_when_write("CACHE_DATA_3", translated_cache_req.write_data_vec(3)) 195 update_cache_req_when_write("CACHE_DATA_4", translated_cache_req.write_data_vec(4)) 196 update_cache_req_when_write("CACHE_DATA_5", translated_cache_req.write_data_vec(5)) 197 update_cache_req_when_write("CACHE_DATA_6", translated_cache_req.write_data_vec(6)) 198 update_cache_req_when_write("CACHE_DATA_7", translated_cache_req.write_data_vec(7)) 199 update_cache_req_when_write("CACHE_DATA_ECC", translated_cache_req.write_data_ecc) 200 201 val cache_op_start = WireInit(cacheop_csr_is_being_write("CACHE_OP") && id.U === translated_cache_req.level) 202 when(cache_op_start) { 203 wait_csr_op_req := false.B 204 } 205 206 // Send cache op to cache 207 io.cache.req.valid := RegNext(cache_op_start) 208 io.cache_req_dup.map( dup => dup.valid := RegNext(cache_op_start) ) 209 io.cache.req.bits := translated_cache_req 210 io.cache_req_dup.map( dup => dup.bits := translated_cache_req ) 211 when(io.cache.req.fire()){ 212 wait_cache_op_resp := true.B 213 } 214 215 io.cacheOp_req_bits_opCode_dup.zipWithIndex.map{ case (dup, i) => dup := translated_cache_req_opCode_dup(i) } 216 217 // Receive cache op resp from cache 218 val raw_cache_resp = Reg(new CacheCtrlRespInfo) 219 when(io.cache.resp.fire()){ 220 wait_cache_op_resp := false.B 221 raw_cache_resp := io.cache.resp.bits 222 when(CacheInstrucion.isReadOp(translated_cache_req.opCode)){ 223 schedule_csr_op_resp_data := true.B 224 schedule_csr_op_resp_finish := false.B 225 assert(data_transfer_cnt === 0.U) 226 }.otherwise{ 227 schedule_csr_op_resp_data := false.B 228 schedule_csr_op_resp_finish := true.B 229 } 230 } 231 232 // Translate cache op resp to CSR write, send it back to CSR 233 when(io.csr.update.w.fire() && schedule_csr_op_resp_data && data_transfer_finished){ 234 schedule_csr_op_resp_data := false.B 235 schedule_csr_op_resp_finish := true.B 236 } 237 when(io.csr.update.w.fire() && schedule_csr_op_resp_finish){ 238 schedule_csr_op_resp_finish := false.B 239 wait_csr_op_req := true.B 240 } 241 242 io.csr.update.w.valid := schedule_csr_op_resp_data || schedule_csr_op_resp_finish 243 io.csr.update.w.bits := DontCare 244 245 val isReadTagECC = WireInit(CacheInstrucion.isReadTagECC(translated_cache_req_opCode_dup(0))) 246 val isReadDataECC = WireInit(CacheInstrucion.isReadDataECC(translated_cache_req_opCode_dup(0))) 247 val isReadTag = WireInit(CacheInstrucion.isReadTag(translated_cache_req.opCode)) 248 val isReadData = WireInit(CacheInstrucion.isReadData(translated_cache_req.opCode)) 249 250 when(schedule_csr_op_resp_data){ 251 io.csr.update.w.bits.addr := Mux1H(List( 252 isReadTagECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_TAG_ECC")("offset").toInt + Scachebase).U, 253 isReadDataECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_DATA_ECC")("offset").toInt + Scachebase).U, 254 isReadTag -> ((CacheInstrucion.CacheInsRegisterList("CACHE_TAG_LOW")("offset").toInt + Scachebase).U + data_transfer_cnt), 255 isReadData -> ((CacheInstrucion.CacheInsRegisterList("CACHE_DATA_0")("offset").toInt + Scachebase).U + data_transfer_cnt), 256 )) 257 io.csr.update.w.bits.data := Mux1H(List( 258 isReadTagECC -> raw_cache_resp.read_tag_ecc, 259 isReadDataECC -> raw_cache_resp.read_data_ecc, 260 isReadTag -> raw_cache_resp.read_tag_low, 261 isReadData -> raw_cache_resp.read_data_vec(data_transfer_cnt), 262 )) 263 data_transfer_finished := Mux(isReadData, 264 data_transfer_cnt === (maxDataRowSupport-1).U, 265 true.B 266 ) 267 data_transfer_cnt := data_transfer_cnt + 1.U 268 } 269 270 when(schedule_csr_op_resp_finish){ 271 io.csr.update.w.bits.addr := (CacheInstrucion.CacheInsRegisterList("OP_FINISH")("offset").toInt + Scachebase).U 272 io.csr.update.w.bits.data := CacheInstrucion.COP_RESULT_CODE_OK 273 data_transfer_cnt := 0.U 274 } 275 276 val error = DelayN(io.error, 1) 277 when(error.report_to_beu) { 278 io.csr.update.w.bits.addr := (CacheInstrucion.CacheInsRegisterList("CACHE_ERROR")("offset").toInt + Scachebase).U 279 io.csr.update.w.bits.data := error.asUInt 280 io.csr.update.w.valid := true.B 281 } 282} 283 284class CSRCacheErrorDecoder(implicit p: Parameters) extends CacheCtrlModule { 285 val io = IO(new Bundle{ 286 val encoded_cache_error = Input(UInt()) 287 }) 288 val encoded_cache_error = io.encoded_cache_error 289 def print_cache_error_flag(flag: Bool, desc: String) = { 290 when(flag){ 291 printf(" " + desc + "\n") 292 } 293 } 294 val decoded_cache_error = WireInit(encoded_cache_error.asTypeOf(new L1CacheErrorInfo)) 295 when(decoded_cache_error.valid && !RegNext(decoded_cache_error.valid)){ 296 printf("CACHE_ERROR CSR reported an error:\n") 297 printf(" paddr 0x%x\n", decoded_cache_error.paddr) 298 print_cache_error_flag(decoded_cache_error.report_to_beu, "report to bus error unit") 299 print_cache_error_flag(decoded_cache_error.source.tag, "tag") 300 print_cache_error_flag(decoded_cache_error.source.data, "data") 301 print_cache_error_flag(decoded_cache_error.source.l2, "l2") 302 print_cache_error_flag(decoded_cache_error.opType.fetch, "fetch") 303 print_cache_error_flag(decoded_cache_error.opType.load, "load") 304 print_cache_error_flag(decoded_cache_error.opType.store, "store") 305 print_cache_error_flag(decoded_cache_error.opType.probe, "probe") 306 print_cache_error_flag(decoded_cache_error.opType.release, "release") 307 print_cache_error_flag(decoded_cache_error.opType.atom, "atom") 308 printf("It should not happen in normal execution flow\n") 309 } 310} 311