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 23*7d91f790SWilliam Wangclass LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule with HasDCacheParameters with HasCircularQueuePtrHelper { 247057673cSWilliam Wang val io = IO(new Bundle() { 25*7d91f790SWilliam Wang val wb = new Bundle() { 26*7d91f790SWilliam Wang val wen = Vec(wbNumWrite, Input(Bool())) 27*7d91f790SWilliam Wang val waddr = Input(Vec(wbNumWrite, UInt(log2Up(size).W))) 28*7d91f790SWilliam Wang val wdata = Input(Vec(wbNumWrite, new LQDataEntry)) 29*7d91f790SWilliam Wang val raddr = Input(Vec(wbNumRead, UInt(log2Up(size).W))) 30*7d91f790SWilliam Wang val rdata = Output(Vec(wbNumRead, new LQDataEntry)) 31*7d91f790SWilliam Wang } 327057673cSWilliam Wang val uncache = new Bundle() { 337057673cSWilliam Wang val wen = Input(Bool()) 34*7d91f790SWilliam Wang val waddr = Input(UInt(log2Up(size).W)) 35*7d91f790SWilliam Wang val wdata = Input(UInt(XLEN.W)) // only write back uncache data 36*7d91f790SWilliam Wang val raddr = Input(UInt(log2Up(size).W)) 37*7d91f790SWilliam Wang val rdata = Output(new LQDataEntry) 387057673cSWilliam Wang } 397057673cSWilliam Wang val refill = new Bundle() { 40*7d91f790SWilliam Wang val valid = Input(Bool()) 41*7d91f790SWilliam Wang val paddr = Input(UInt(PAddrBits.W)) 427057673cSWilliam Wang val data = Input(UInt((cfg.blockBytes * 8).W)) 43*7d91f790SWilliam Wang val refillMask = Input(Vec(size, Bool())) 44*7d91f790SWilliam Wang val matchMask = Output(Vec(size, Bool())) 457057673cSWilliam Wang } 46*7d91f790SWilliam Wang val violation = Vec(StorePipelineWidth, new Bundle() { 47*7d91f790SWilliam Wang val paddr = Input(UInt(PAddrBits.W)) 48*7d91f790SWilliam Wang val mask = Input(UInt(8.W)) 49*7d91f790SWilliam Wang val violationMask = Output(Vec(size, Bool())) 50*7d91f790SWilliam Wang }) 51*7d91f790SWilliam Wang val debug = Output(Vec(size, new LQDataEntry)) 527057673cSWilliam Wang 53*7d91f790SWilliam Wang def wbWrite(channel: Int, waddr: UInt, wdata: LQDataEntry): Unit = { 54*7d91f790SWilliam Wang require(channel < wbNumWrite && wbNumWrite >= 0) 557057673cSWilliam Wang // need extra "this.wb(channel).wen := true.B" 56*7d91f790SWilliam Wang this.wb.waddr(channel) := waddr 57*7d91f790SWilliam Wang this.wb.wdata(channel) := wdata 587057673cSWilliam Wang } 597057673cSWilliam Wang 60*7d91f790SWilliam Wang def uncacheWrite(waddr: UInt, wdata: UInt): Unit = { 617057673cSWilliam Wang // need extra "this.uncache.wen := true.B" 62*7d91f790SWilliam 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 io := DontCare 727057673cSWilliam Wang 737057673cSWilliam Wang val data = Reg(Vec(size, new LQDataEntry)) 747057673cSWilliam Wang 757057673cSWilliam Wang // writeback to lq/sq 76*7d91f790SWilliam Wang (0 until wbNumWrite).map(i => { 77*7d91f790SWilliam Wang when(io.wb.wen(i)){ 78*7d91f790SWilliam Wang data(io.wb.waddr(i)) := io.wb.wdata(i) 797057673cSWilliam Wang } 807057673cSWilliam Wang }) 817057673cSWilliam Wang 827057673cSWilliam Wang when(io.uncache.wen){ 83*7d91f790SWilliam Wang data(io.uncache.waddr).data := io.uncache.wdata 847057673cSWilliam Wang } 857057673cSWilliam Wang 867057673cSWilliam Wang // refill missed load 877057673cSWilliam Wang def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = { 887057673cSWilliam Wang val res = Wire(Vec(8, UInt(8.W))) 897057673cSWilliam Wang (0 until 8).foreach(i => { 907057673cSWilliam Wang res(i) := Mux(fwdMask(i), fwd(8 * (i + 1) - 1, 8 * i), refill(8 * (i + 1) - 1, 8 * i)) 917057673cSWilliam Wang }) 927057673cSWilliam Wang res.asUInt 937057673cSWilliam Wang } 947057673cSWilliam Wang 957057673cSWilliam Wang // split dcache result into words 967057673cSWilliam Wang val words = VecInit((0 until blockWords) map { i => io.refill.data(DataBits * (i + 1) - 1, DataBits * i)}) 977057673cSWilliam Wang 98*7d91f790SWilliam Wang // gen paddr match mask 997057673cSWilliam Wang (0 until size).map(i => { 100*7d91f790SWilliam Wang io.refill.matchMask(i) := get_block_addr(data(i).paddr) === get_block_addr(io.refill.paddr) 101*7d91f790SWilliam Wang }) 102*7d91f790SWilliam Wang 103*7d91f790SWilliam Wang // refill data according to matchMask, refillMask and refill.valid 104*7d91f790SWilliam Wang (0 until size).map(i => { 105*7d91f790SWilliam Wang when(io.refill.valid && io.refill.matchMask(i) && io.refill.refillMask(i)){ 1067057673cSWilliam Wang val refillData = words(get_word(data(i).paddr)) 1077057673cSWilliam Wang data(i).data := mergeRefillData(refillData, data(i).data.asUInt, data(i).fwdMask.asUInt) 1087057673cSWilliam 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) 1097057673cSWilliam Wang } 1107057673cSWilliam Wang }) 1117057673cSWilliam Wang 112*7d91f790SWilliam Wang // mem access violation check, gen violationMask 113*7d91f790SWilliam Wang (0 until StorePipelineWidth).map(i => { 114*7d91f790SWilliam Wang io.violation(i).violationMask := VecInit((0 until size).map(j => { 115*7d91f790SWilliam Wang val addrMatch = io.violation(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3) 116*7d91f790SWilliam Wang val violationVec = (0 until 8).map(k => data(j).mask(k) && io.violation(i).mask(k)) 117*7d91f790SWilliam Wang Cat(violationVec).orR() && addrMatch 118*7d91f790SWilliam Wang })) 119*7d91f790SWilliam Wang }) 120*7d91f790SWilliam Wang 121*7d91f790SWilliam Wang // debug data read 122*7d91f790SWilliam Wang io.debug := data 1237057673cSWilliam Wang} 124