1ad3ba452Szhanglinjuanpackage xiangshan.cache 2ad3ba452Szhanglinjuan 3ad3ba452Szhanglinjuanimport chisel3._ 4ad3ba452Szhanglinjuanimport chisel3.util._ 5ad3ba452Szhanglinjuanimport xiangshan._ 6ad3ba452Szhanglinjuanimport xiangshan.frontend._ 7ad3ba452Szhanglinjuanimport utils._ 8ad3ba452Szhanglinjuanimport chipsalliance.rocketchip.config.Parameters 9*e19f7967SWilliam 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 35*e19f7967SWilliam Wangabstract class CacheCtrlModule(implicit p: Parameters) extends XSModule with HasCSRConst with CacheControlConst 36*e19f7967SWilliam 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( 51*e19f7967SWilliam Wang // offset width authority name 52*e19f7967SWilliam Wang CacheRegMap("0", "64", "RW", "CACHE_OP"), 53*e19f7967SWilliam Wang CacheRegMap("1", "64", "RW", "OP_FINISH"), 54*e19f7967SWilliam Wang CacheRegMap("2", "64", "RW", "CACHE_LEVEL"), 55*e19f7967SWilliam Wang CacheRegMap("3", "64", "RW", "CACHE_WAY"), 56*e19f7967SWilliam Wang CacheRegMap("4", "64", "RW", "CACHE_IDX"), 57*e19f7967SWilliam Wang CacheRegMap("5", "64", "RW", "CACHE_BANK_NUM"), 58*e19f7967SWilliam Wang CacheRegMap("6", "64", "RW", "CACHE_TAG_ECC"), 59*e19f7967SWilliam Wang CacheRegMap("7", "64", "RW", "CACHE_TAG_BITS"), // TODO 60*e19f7967SWilliam Wang CacheRegMap("8", "64", "RW", "CACHE_TAG_LOW"), 61*e19f7967SWilliam Wang CacheRegMap("9", "64", "RW", "CACHE_TAG_HIGH"), // not used in 64 bit arch 62*e19f7967SWilliam Wang CacheRegMap("10", "64", "RW", "CACHE_ECC_WIDTH"), // TODO 63*e19f7967SWilliam Wang CacheRegMap("11", "64", "RW", "CACHE_DATA_ECC"), 64*e19f7967SWilliam Wang CacheRegMap("12", "64", "RW", "CACHE_DATA_0"), 65*e19f7967SWilliam Wang CacheRegMap("13", "64", "RW", "CACHE_DATA_1"), 66*e19f7967SWilliam Wang CacheRegMap("14", "64", "RW", "CACHE_DATA_2"), 67*e19f7967SWilliam Wang CacheRegMap("15", "64", "RW", "CACHE_DATA_3"), 68*e19f7967SWilliam Wang CacheRegMap("16", "64", "RW", "CACHE_DATA_4"), 69*e19f7967SWilliam Wang CacheRegMap("17", "64", "RW", "CACHE_DATA_5"), 70*e19f7967SWilliam Wang CacheRegMap("18", "64", "RW", "CACHE_DATA_6"), 71*e19f7967SWilliam Wang CacheRegMap("19", "64", "RW", "CACHE_DATA_7"), 72ad3ba452Szhanglinjuan ) 73ad3ba452Szhanglinjuan 74*e19f7967SWilliam Wang // Usage: 75*e19f7967SWilliam Wang // val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 76*e19f7967SWilliam Wang // doSthWith(name, attribute("offset"), attribute("width")) 77*e19f7967SWilliam Wang // }} 78*e19f7967SWilliam 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 84*e19f7967SWilliam Wang def COP_ID_ICACHE = 0 85*e19f7967SWilliam Wang def COP_ID_DCACHE = 1 86*e19f7967SWilliam Wang 87*e19f7967SWilliam Wang def COP_RESULT_CODE_IDLE = 0.U 88*e19f7967SWilliam Wang def COP_RESULT_CODE_OK = 1.U 89*e19f7967SWilliam Wang def COP_RESULT_CODE_ERROR = 2.U 90*e19f7967SWilliam 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 95*e19f7967SWilliam Wang def isWriteTagECC(opcode: UInt) = opcode === "b00100".U 96*e19f7967SWilliam 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 100*e19f7967SWilliam Wang 101*e19f7967SWilliam Wang def isReadOp(opcode: UInt) = isReadTagECC(opcode) || 102*e19f7967SWilliam Wang isReadDataECC(opcode) || 103*e19f7967SWilliam Wang isReadTag(opcode) || 104*e19f7967SWilliam Wang isReadData(opcode) 105ad3ba452Szhanglinjuan} 106ad3ba452Szhanglinjuan 107ad3ba452Szhanglinjuanclass CacheCtrlReqInfo(implicit p: Parameters) extends XSBundle with CacheControlConst { 108*e19f7967SWilliam 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) 117*e19f7967SWilliam 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) 126*e19f7967SWilliam Wang val bank_num = UInt(XLEN.W) 127ad3ba452Szhanglinjuan} 128ad3ba452Szhanglinjuan 129*e19f7967SWilliam Wangclass L1CacheToCsrIO(implicit p: Parameters) extends DCacheBundle { 130*e19f7967SWilliam Wang val distribute_csr = Flipped(new DistributedCSRIO) 131*e19f7967SWilliam Wang val update = new DistributedCSRUpdateReq 132*e19f7967SWilliam Wang} 133ad3ba452Szhanglinjuan 134*e19f7967SWilliam Wangclass DCacheInnerOpIO(implicit p: Parameters) extends DCacheBundle { 135*e19f7967SWilliam Wang val req = Valid(new CacheCtrlReqInfo) 136*e19f7967SWilliam Wang val resp = Flipped(Valid(new CacheCtrlRespInfo)) 137*e19f7967SWilliam Wang} 138*e19f7967SWilliam Wang 139*e19f7967SWilliam Wangclass CSRCacheOpDecoder(decoder_name: String, id: Int)(implicit p: Parameters) extends CacheCtrlModule { 140*e19f7967SWilliam Wang val io = IO(new Bundle { 141*e19f7967SWilliam Wang val csr = new L1CacheToCsrIO 142*e19f7967SWilliam Wang val cache = new DCacheInnerOpIO 143*e19f7967SWilliam Wang }) 144*e19f7967SWilliam Wang 145*e19f7967SWilliam Wang // CSRCacheOpDecoder state 146*e19f7967SWilliam Wang val w_csr_op_req = RegInit(true.B) // waiting for csr "CACHE_OP" being write 147*e19f7967SWilliam Wang val w_cache_op_resp = RegInit(false.B) // waiting for dcache to finish dcache op 148*e19f7967SWilliam Wang val s_csr_op_resp_data = RegInit(false.B) // ready to write data readed from cache back to csr 149*e19f7967SWilliam Wang val s_csr_op_resp_finish = RegInit(false.B) // ready to write "OP_FINISH" csr 150*e19f7967SWilliam Wang // val cache_op_resp_timer = RegInit(0.U(4.W)) 151*e19f7967SWilliam Wang val data_transfer_finished = WireInit(false.B) 152*e19f7967SWilliam Wang val data_transfer_cnt = RegInit(0.U(log2Up(maxDataRowSupport).W)) 153*e19f7967SWilliam Wang 154*e19f7967SWilliam Wang // Translate CSR write to cache op 155*e19f7967SWilliam Wang val translated_cache_req = Reg(new CacheCtrlReqInfo) 156*e19f7967SWilliam Wang println("Cache op decoder (" + decoder_name + "):") 157*e19f7967SWilliam Wang println(" Id " + id) 158*e19f7967SWilliam Wang // CacheInsRegisterList.map{case (name, attribute) => { 159*e19f7967SWilliam Wang // println(" Register CSR mirror " + name) 160*e19f7967SWilliam Wang // }} 161*e19f7967SWilliam Wang 162*e19f7967SWilliam Wang def cacheop_csr_is_being_write(csr_name: String): Bool = { 163*e19f7967SWilliam Wang io.csr.distribute_csr.w.bits.addr === (CacheInstrucion.CacheInsRegisterList(csr_name)("offset").toInt + Scachebase).U && 164*e19f7967SWilliam Wang io.csr.distribute_csr.w.valid 165*e19f7967SWilliam Wang } 166*e19f7967SWilliam Wang 167*e19f7967SWilliam Wang def update_cache_req_when_write(csr_name: String, req_field: Data) = { 168*e19f7967SWilliam Wang when( 169*e19f7967SWilliam Wang cacheop_csr_is_being_write(csr_name) 170*e19f7967SWilliam Wang ){ 171*e19f7967SWilliam Wang req_field := io.csr.distribute_csr.w.bits.data 172*e19f7967SWilliam Wang assert(w_csr_op_req) 173*e19f7967SWilliam Wang } 174*e19f7967SWilliam Wang } 175*e19f7967SWilliam Wang 176*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_OP", translated_cache_req.opCode) 177*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_LEVEL", translated_cache_req.level) 178*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_WAY", translated_cache_req.wayNum) 179*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_IDX", translated_cache_req.index) 180*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_BANK_NUM", translated_cache_req.bank_num) 181*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_TAG_HIGH", translated_cache_req.write_tag_high) 182*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_TAG_LOW", translated_cache_req.write_tag_low) 183*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_ECC", translated_cache_req.write_tag_ecc) 184*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_0", translated_cache_req.write_data_vec(0)) 185*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_1", translated_cache_req.write_data_vec(1)) 186*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_2", translated_cache_req.write_data_vec(2)) 187*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_3", translated_cache_req.write_data_vec(3)) 188*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_4", translated_cache_req.write_data_vec(4)) 189*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_5", translated_cache_req.write_data_vec(5)) 190*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_6", translated_cache_req.write_data_vec(6)) 191*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_7", translated_cache_req.write_data_vec(7)) 192*e19f7967SWilliam Wang update_cache_req_when_write("CACHE_DATA_ECC", translated_cache_req.write_data_ecc) 193*e19f7967SWilliam Wang 194*e19f7967SWilliam Wang val cache_op_start = WireInit(cacheop_csr_is_being_write("CACHE_OP") && id.U === translated_cache_req.level) 195*e19f7967SWilliam Wang when(cache_op_start) { 196*e19f7967SWilliam Wang w_csr_op_req := false.B 197*e19f7967SWilliam Wang } 198*e19f7967SWilliam Wang 199*e19f7967SWilliam Wang // Send cache op to cache 200*e19f7967SWilliam Wang io.cache.req.valid := RegNext(cache_op_start) 201*e19f7967SWilliam Wang io.cache.req.bits := translated_cache_req 202*e19f7967SWilliam Wang when(io.cache.req.fire()){ 203*e19f7967SWilliam Wang w_cache_op_resp := true.B 204*e19f7967SWilliam Wang } 205*e19f7967SWilliam Wang 206*e19f7967SWilliam Wang // Receive cache op resp from cache 207*e19f7967SWilliam Wang val raw_cache_resp = Reg(new CacheCtrlRespInfo) 208*e19f7967SWilliam Wang when(io.cache.resp.fire()){ 209*e19f7967SWilliam Wang w_cache_op_resp := false.B 210*e19f7967SWilliam Wang raw_cache_resp := io.cache.resp.bits 211*e19f7967SWilliam Wang when(CacheInstrucion.isReadOp(translated_cache_req.opCode)){ 212*e19f7967SWilliam Wang s_csr_op_resp_data := true.B 213*e19f7967SWilliam Wang s_csr_op_resp_finish := false.B 214*e19f7967SWilliam Wang assert(data_transfer_cnt === 0.U) 215*e19f7967SWilliam Wang }.otherwise{ 216*e19f7967SWilliam Wang s_csr_op_resp_data := false.B 217*e19f7967SWilliam Wang s_csr_op_resp_finish := true.B 218*e19f7967SWilliam Wang } 219*e19f7967SWilliam Wang } 220*e19f7967SWilliam Wang 221*e19f7967SWilliam Wang // Translate cache op resp to CSR write, send it back to CSR 222*e19f7967SWilliam Wang when(io.csr.update.w.fire() && s_csr_op_resp_data && data_transfer_finished){ 223*e19f7967SWilliam Wang s_csr_op_resp_data := false.B 224*e19f7967SWilliam Wang s_csr_op_resp_finish := true.B 225*e19f7967SWilliam Wang } 226*e19f7967SWilliam Wang when(io.csr.update.w.fire() && s_csr_op_resp_finish){ 227*e19f7967SWilliam Wang s_csr_op_resp_finish := false.B 228*e19f7967SWilliam Wang w_csr_op_req := true.B 229*e19f7967SWilliam Wang } 230*e19f7967SWilliam Wang 231*e19f7967SWilliam Wang io.csr.update.w.valid := s_csr_op_resp_data || s_csr_op_resp_finish 232*e19f7967SWilliam Wang io.csr.update.w.bits := DontCare 233*e19f7967SWilliam Wang 234*e19f7967SWilliam Wang val isReadTagECC = WireInit(CacheInstrucion.isReadTagECC(translated_cache_req.opCode)) 235*e19f7967SWilliam Wang val isReadDataECC = WireInit(CacheInstrucion.isReadDataECC(translated_cache_req.opCode)) 236*e19f7967SWilliam Wang val isReadTag = WireInit(CacheInstrucion.isReadTag(translated_cache_req.opCode)) 237*e19f7967SWilliam Wang val isReadData = WireInit(CacheInstrucion.isReadData(translated_cache_req.opCode)) 238*e19f7967SWilliam Wang 239*e19f7967SWilliam Wang when(s_csr_op_resp_data){ 240*e19f7967SWilliam Wang io.csr.update.w.bits.addr := Mux1H(List( 241*e19f7967SWilliam Wang isReadTagECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_TAG_ECC")("offset").toInt + Scachebase).U, 242*e19f7967SWilliam Wang isReadDataECC -> (CacheInstrucion.CacheInsRegisterList("CACHE_BANK_NUM")("offset").toInt + Scachebase).U, 243*e19f7967SWilliam Wang isReadTag -> ((CacheInstrucion.CacheInsRegisterList("CACHE_TAG_LOW")("offset").toInt + Scachebase).U + data_transfer_cnt), 244*e19f7967SWilliam Wang isReadData -> ((CacheInstrucion.CacheInsRegisterList("CACHE_DATA_0")("offset").toInt + Scachebase).U + data_transfer_cnt), 245*e19f7967SWilliam Wang )) 246*e19f7967SWilliam Wang io.csr.update.w.bits.data := Mux1H(List( 247*e19f7967SWilliam Wang isReadTagECC -> raw_cache_resp.read_tag_ecc, 248*e19f7967SWilliam Wang isReadDataECC -> raw_cache_resp.read_tag_ecc, 249*e19f7967SWilliam Wang isReadTag -> raw_cache_resp.read_tag_low, 250*e19f7967SWilliam Wang isReadData -> raw_cache_resp.read_data_vec(data_transfer_cnt), 251*e19f7967SWilliam Wang )) 252*e19f7967SWilliam Wang data_transfer_finished := Mux(isReadData(translated_cache_req.opCode), 253*e19f7967SWilliam Wang data_transfer_cnt === (maxDataRowSupport-1).U, 254*e19f7967SWilliam Wang true.B 255*e19f7967SWilliam Wang ) 256*e19f7967SWilliam Wang data_transfer_cnt := data_transfer_cnt + 1.U 257*e19f7967SWilliam Wang } 258*e19f7967SWilliam Wang 259*e19f7967SWilliam Wang when(s_csr_op_resp_finish){ 260*e19f7967SWilliam Wang io.csr.update.w.bits.addr := (CacheInstrucion.CacheInsRegisterList("OP_FINISH")("offset").toInt + Scachebase).U 261*e19f7967SWilliam Wang io.csr.update.w.bits.data := CacheInstrucion.COP_RESULT_CODE_OK 262*e19f7967SWilliam Wang data_transfer_cnt := 0.U 263*e19f7967SWilliam Wang } 264*e19f7967SWilliam Wang} 265