17057673cSWilliam Wangpackage xiangshan.mem 27057673cSWilliam Wang 37057673cSWilliam Wangimport chisel3._ 47057673cSWilliam Wangimport chisel3.util._ 57057673cSWilliam Wangimport utils._ 67057673cSWilliam Wangimport xiangshan._ 77057673cSWilliam Wangimport xiangshan.cache._ 87057673cSWilliam Wangimport xiangshan.cache.{DCacheWordIO, DCacheLineIO, TlbRequestIO, MemoryOpConstants} 97057673cSWilliam Wangimport xiangshan.backend.LSUOpType 107057673cSWilliam Wangimport xiangshan.mem._ 117057673cSWilliam Wangimport xiangshan.backend.roq.RoqPtr 127057673cSWilliam Wang 137057673cSWilliam Wangclass LQDataEntry extends XSBundle { 147057673cSWilliam Wang // val vaddr = UInt(VAddrBits.W) 157057673cSWilliam Wang val paddr = UInt(PAddrBits.W) 167057673cSWilliam Wang val mask = UInt(8.W) 177057673cSWilliam Wang val data = UInt(XLEN.W) 187057673cSWilliam Wang val exception = UInt(16.W) // TODO: opt size 197057673cSWilliam Wang val fwdMask = Vec(8, Bool()) 207057673cSWilliam Wang} 217057673cSWilliam Wang 227057673cSWilliam Wang 237d91f790SWilliam Wangclass LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule with HasDCacheParameters with HasCircularQueuePtrHelper { 247057673cSWilliam Wang val io = IO(new Bundle() { 257d91f790SWilliam Wang val wb = new Bundle() { 267d91f790SWilliam Wang val wen = Vec(wbNumWrite, Input(Bool())) 277d91f790SWilliam Wang val waddr = Input(Vec(wbNumWrite, UInt(log2Up(size).W))) 287d91f790SWilliam Wang val wdata = Input(Vec(wbNumWrite, new LQDataEntry)) 297d91f790SWilliam Wang val raddr = Input(Vec(wbNumRead, UInt(log2Up(size).W))) 307d91f790SWilliam Wang val rdata = Output(Vec(wbNumRead, new LQDataEntry)) 317d91f790SWilliam Wang } 327057673cSWilliam Wang val uncache = new Bundle() { 337057673cSWilliam Wang val wen = Input(Bool()) 347d91f790SWilliam Wang val waddr = Input(UInt(log2Up(size).W)) 357d91f790SWilliam Wang val wdata = Input(UInt(XLEN.W)) // only write back uncache data 367d91f790SWilliam Wang val raddr = Input(UInt(log2Up(size).W)) 377d91f790SWilliam Wang val rdata = Output(new LQDataEntry) 387057673cSWilliam Wang } 397057673cSWilliam Wang val refill = new Bundle() { 407d91f790SWilliam Wang val valid = Input(Bool()) 417d91f790SWilliam Wang val paddr = Input(UInt(PAddrBits.W)) 427057673cSWilliam Wang val data = Input(UInt((cfg.blockBytes * 8).W)) 437d91f790SWilliam Wang val refillMask = Input(Vec(size, Bool())) 447d91f790SWilliam Wang val matchMask = Output(Vec(size, Bool())) 457057673cSWilliam Wang } 467d91f790SWilliam Wang val violation = Vec(StorePipelineWidth, new Bundle() { 477d91f790SWilliam Wang val paddr = Input(UInt(PAddrBits.W)) 487d91f790SWilliam Wang val mask = Input(UInt(8.W)) 497d91f790SWilliam Wang val violationMask = Output(Vec(size, Bool())) 507d91f790SWilliam Wang }) 517d91f790SWilliam Wang val debug = Output(Vec(size, new LQDataEntry)) 527057673cSWilliam Wang 537d91f790SWilliam Wang def wbWrite(channel: Int, waddr: UInt, wdata: LQDataEntry): Unit = { 547d91f790SWilliam Wang require(channel < wbNumWrite && wbNumWrite >= 0) 557057673cSWilliam Wang // need extra "this.wb(channel).wen := true.B" 567d91f790SWilliam Wang this.wb.waddr(channel) := waddr 577d91f790SWilliam Wang this.wb.wdata(channel) := wdata 587057673cSWilliam Wang } 597057673cSWilliam Wang 607d91f790SWilliam Wang def uncacheWrite(waddr: UInt, wdata: UInt): Unit = { 617057673cSWilliam Wang // need extra "this.uncache.wen := true.B" 627d91f790SWilliam Wang this.uncache.waddr := waddr 637057673cSWilliam Wang this.uncache.wdata := wdata 647057673cSWilliam Wang } 657057673cSWilliam Wang 667057673cSWilliam Wang // def refillWrite(ldIdx: Int): Unit = { 677057673cSWilliam Wang // } 687057673cSWilliam Wang // use "this.refill.wen(ldIdx) := true.B" instead 697057673cSWilliam Wang }) 707057673cSWilliam Wang 717057673cSWilliam Wang val data = Reg(Vec(size, new LQDataEntry)) 727057673cSWilliam Wang 73*a266fd76SWilliam Wang // read data 74*a266fd76SWilliam Wang (0 until wbNumRead).map(i => { 75*a266fd76SWilliam Wang io.wb.rdata(i) := data(io.wb.raddr(i)) 76*a266fd76SWilliam Wang }) 77*a266fd76SWilliam Wang 78*a266fd76SWilliam Wang io.uncache.rdata := data(io.uncache.raddr) 79*a266fd76SWilliam Wang 807057673cSWilliam Wang // writeback to lq/sq 817d91f790SWilliam Wang (0 until wbNumWrite).map(i => { 827d91f790SWilliam Wang when(io.wb.wen(i)){ 837d91f790SWilliam Wang data(io.wb.waddr(i)) := io.wb.wdata(i) 847057673cSWilliam Wang } 857057673cSWilliam Wang }) 867057673cSWilliam Wang 877057673cSWilliam Wang when(io.uncache.wen){ 887d91f790SWilliam Wang data(io.uncache.waddr).data := io.uncache.wdata 897057673cSWilliam Wang } 907057673cSWilliam Wang 917057673cSWilliam Wang // refill missed load 927057673cSWilliam Wang def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = { 937057673cSWilliam Wang val res = Wire(Vec(8, UInt(8.W))) 947057673cSWilliam Wang (0 until 8).foreach(i => { 957057673cSWilliam Wang res(i) := Mux(fwdMask(i), fwd(8 * (i + 1) - 1, 8 * i), refill(8 * (i + 1) - 1, 8 * i)) 967057673cSWilliam Wang }) 977057673cSWilliam Wang res.asUInt 987057673cSWilliam Wang } 997057673cSWilliam Wang 1007057673cSWilliam Wang // split dcache result into words 1017057673cSWilliam Wang val words = VecInit((0 until blockWords) map { i => io.refill.data(DataBits * (i + 1) - 1, DataBits * i)}) 1027057673cSWilliam Wang 1037d91f790SWilliam Wang // gen paddr match mask 1047057673cSWilliam Wang (0 until size).map(i => { 1057d91f790SWilliam Wang io.refill.matchMask(i) := get_block_addr(data(i).paddr) === get_block_addr(io.refill.paddr) 1067d91f790SWilliam Wang }) 1077d91f790SWilliam Wang 1087d91f790SWilliam Wang // refill data according to matchMask, refillMask and refill.valid 1097d91f790SWilliam Wang (0 until size).map(i => { 1107d91f790SWilliam Wang when(io.refill.valid && io.refill.matchMask(i) && io.refill.refillMask(i)){ 1117057673cSWilliam Wang val refillData = words(get_word(data(i).paddr)) 1127057673cSWilliam Wang data(i).data := mergeRefillData(refillData, data(i).data.asUInt, data(i).fwdMask.asUInt) 1137057673cSWilliam Wang XSDebug("miss resp: pos %d addr %x data %x + %x(%b)\n", i.U, data(i).paddr, refillData, data(i).data.asUInt, data(i).fwdMask.asUInt) 1147057673cSWilliam Wang } 1157057673cSWilliam Wang }) 1167057673cSWilliam Wang 1177d91f790SWilliam Wang // mem access violation check, gen violationMask 1187d91f790SWilliam Wang (0 until StorePipelineWidth).map(i => { 1197d91f790SWilliam Wang io.violation(i).violationMask := VecInit((0 until size).map(j => { 1207d91f790SWilliam Wang val addrMatch = io.violation(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3) 1217d91f790SWilliam Wang val violationVec = (0 until 8).map(k => data(j).mask(k) && io.violation(i).mask(k)) 1227d91f790SWilliam Wang Cat(violationVec).orR() && addrMatch 1237d91f790SWilliam Wang })) 1247d91f790SWilliam Wang }) 1257d91f790SWilliam Wang 1267d91f790SWilliam Wang // debug data read 1277d91f790SWilliam Wang io.debug := data 1287057673cSWilliam Wang} 129