1package xiangshan.mem 2 3import chisel3._ 4import chisel3.util._ 5import utils._ 6import xiangshan._ 7import xiangshan.cache.{TlbRequestIO, TlbCmd} 8 9class StoreUnit extends XSModule { 10 val io = IO(new Bundle() { 11 val stin = Flipped(Decoupled(new ExuInput)) 12 val redirect = Flipped(ValidIO(new Redirect)) 13 val tlbFeedback = ValidIO(new TlbFeedback) 14 val dtlb = new TlbRequestIO() 15 val lsq = ValidIO(new LsPipelineBundle) 16 }) 17 18 //------------------------------------------------------- 19 // Store Pipeline 20 //------------------------------------------------------- 21 val s2_out = Wire(Decoupled(new LsPipelineBundle)) 22 val s3_in = Wire(Decoupled(new LsPipelineBundle)) 23 24 25 private def printPipeLine(pipeline: LsPipelineBundle, cond: Bool, name: String): Unit = { 26 XSDebug(cond, 27 p"$name" + p" pc ${Hexadecimal(pipeline.uop.cf.pc)} " + 28 p"addr ${Hexadecimal(pipeline.vaddr)} -> ${Hexadecimal(pipeline.paddr)} " + 29 p"op ${Binary(pipeline.uop.ctrl.fuOpType)} " + 30 p"data ${Hexadecimal(pipeline.data)} " + 31 p"mask ${Hexadecimal(pipeline.mask)}\n" 32 ) 33 } 34 35 printPipeLine(s2_out.bits, s2_out.valid, "S2") 36 // TODO: is this nesscary ? 37 XSDebug(s2_out.fire(), "store req: pc 0x%x addr 0x%x -> 0x%x op %b data 0x%x\n", 38 s2_out.bits.uop.cf.pc, 39 s2_out.bits.vaddr, 40 s2_out.bits.paddr, 41 s2_out.bits.uop.ctrl.fuOpType, 42 s2_out.bits.data 43 ) 44 printPipeLine(s3_in.bits, s3_in.valid, "S3") 45 46 47 48 //------------------------------------------------------- 49 // ST Pipeline Stage 2 50 // Generate addr, use addr to query DTLB 51 //------------------------------------------------------- 52 53 // send req to dtlb 54 val saddr = io.stin.bits.src1 + io.stin.bits.uop.ctrl.imm 55 56 io.dtlb.req.bits.vaddr := saddr 57 io.dtlb.req.valid := io.stin.valid 58 io.dtlb.req.bits.cmd := TlbCmd.write 59 io.dtlb.req.bits.roqIdx := io.stin.bits.uop.roqIdx 60 io.dtlb.req.bits.debug.pc := io.stin.bits.uop.cf.pc 61 62 s2_out.bits := DontCare 63 s2_out.bits.vaddr := saddr 64 s2_out.bits.paddr := io.dtlb.resp.bits.paddr 65 s2_out.bits.data := genWdata(io.stin.bits.src2, io.stin.bits.uop.ctrl.fuOpType(1,0)) 66 s2_out.bits.uop := io.stin.bits.uop 67 s2_out.bits.miss := io.dtlb.resp.bits.miss 68 s2_out.bits.mask := genWmask(s2_out.bits.vaddr, io.stin.bits.uop.ctrl.fuOpType(1,0)) 69 s2_out.valid := io.stin.valid && !io.dtlb.resp.bits.miss && !s2_out.bits.uop.roqIdx.needFlush(io.redirect) 70 io.stin.ready := s2_out.ready 71 72 // exception check 73 val addrAligned = LookupTree(io.stin.bits.uop.ctrl.fuOpType(1,0), List( 74 "b00".U -> true.B, //b 75 "b01".U -> (s2_out.bits.vaddr(0) === 0.U), //h 76 "b10".U -> (s2_out.bits.vaddr(1,0) === 0.U), //w 77 "b11".U -> (s2_out.bits.vaddr(2,0) === 0.U) //d 78 )) 79 s2_out.bits.uop.cf.exceptionVec(storeAddrMisaligned) := !addrAligned 80 s2_out.bits.uop.cf.exceptionVec(storePageFault) := io.dtlb.resp.bits.excp.pf.st 81 82 PipelineConnect(s2_out, s3_in, true.B, false.B) 83 //------------------------------------------------------- 84 // ST Pipeline Stage 3 85 // Write paddr to LSQ 86 //------------------------------------------------------- 87 88 // Send TLB feedback to store issue queue 89 io.tlbFeedback.valid := RegNext(io.stin.valid && s2_out.ready) 90 io.tlbFeedback.bits.hit := RegNext(!s2_out.bits.miss) 91 io.tlbFeedback.bits.roqIdx := RegNext(s2_out.bits.uop.roqIdx) 92 XSDebug(io.tlbFeedback.valid, 93 "S3 Store: tlbHit: %d roqIdx: %d\n", 94 io.tlbFeedback.bits.hit, 95 io.tlbFeedback.bits.roqIdx.asUInt 96 ) 97 98 // get paddr from dtlb, check if rollback is needed 99 // writeback store inst to lsq 100 // writeback to LSQ 101 s3_in.ready := true.B 102 io.lsq.bits := s3_in.bits 103 io.lsq.bits.miss := false.B 104 io.lsq.bits.mmio := AddressSpace.isMMIO(s3_in.bits.paddr) 105 io.lsq.valid := s3_in.fire() 106 107 //------------------------------------------------------- 108 // ST Pipeline Stage 4 109 // Store writeback, send store request to store buffer 110 //------------------------------------------------------- 111 112 // Writeback to CDB 113 // (0 until LoadPipelineWidth).map(i => { 114 // io.ldout <> hitLoadOut 115 // }) 116 117 //------------------------------------------------------- 118 // ST Pipeline Async Stage 1 119 // Read paddr from store buffer, query DTAG in DCache 120 //------------------------------------------------------- 121 122 123 //------------------------------------------------------- 124 // ST Pipeline Async Stage 2 125 // DTAG compare, write data to DCache 126 //------------------------------------------------------- 127 128 // Done in DCache 129 130 //------------------------------------------------------- 131 // ST Pipeline Async Stage 2 132 // DCache miss / Shared cache wirte 133 //------------------------------------------------------- 134 135 // update store buffer according to store fill buffer 136 137} 138