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