xref: /XiangShan/src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala (revision 4d8915fda0e6d6f5e1468fbbcaadb531c95e25c4)
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 lsroq = 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  io.dtlb.req.bits.debug.lsroqIdx := io.stin.bits.uop.lsroqIdx // FIXME: need update
62
63  s2_out.bits := DontCare
64  s2_out.bits.vaddr := saddr
65  s2_out.bits.paddr := io.dtlb.resp.bits.paddr
66  s2_out.bits.data := genWdata(io.stin.bits.src2, io.stin.bits.uop.ctrl.fuOpType(1,0))
67  s2_out.bits.uop := io.stin.bits.uop
68  s2_out.bits.miss := io.dtlb.resp.bits.miss
69  s2_out.bits.mask := genWmask(s2_out.bits.vaddr, io.stin.bits.uop.ctrl.fuOpType(1,0))
70  s2_out.valid := io.stin.valid && !io.dtlb.resp.bits.miss && !s2_out.bits.uop.roqIdx.needFlush(io.redirect)
71  io.stin.ready := s2_out.ready
72
73  // exception check
74  val addrAligned = LookupTree(io.stin.bits.uop.ctrl.fuOpType(1,0), List(
75    "b00".U   -> true.B,              //b
76    "b01".U   -> (s2_out.bits.vaddr(0) === 0.U),   //h
77    "b10".U   -> (s2_out.bits.vaddr(1,0) === 0.U), //w
78    "b11".U   -> (s2_out.bits.vaddr(2,0) === 0.U)  //d
79  ))
80  s2_out.bits.uop.cf.exceptionVec(storeAddrMisaligned) := !addrAligned
81  s2_out.bits.uop.cf.exceptionVec(storePageFault) := io.dtlb.resp.bits.excp.pf.st
82
83  PipelineConnect(s2_out, s3_in, true.B, false.B)
84  //-------------------------------------------------------
85  // ST Pipeline Stage 3
86  // Write paddr to LSROQ
87  //-------------------------------------------------------
88
89  // Send TLB feedback to store issue queue
90  io.tlbFeedback.valid := RegNext(io.stin.valid && s2_out.ready)
91  io.tlbFeedback.bits.hit := RegNext(!s2_out.bits.miss)
92  io.tlbFeedback.bits.roqIdx := RegNext(s2_out.bits.uop.roqIdx)
93  XSDebug(io.tlbFeedback.valid,
94    "S3 Store: tlbHit: %d roqIdx: %d\n",
95    io.tlbFeedback.bits.hit,
96    io.tlbFeedback.bits.roqIdx.asUInt
97  )
98
99  // get paddr from dtlb, check if rollback is needed
100  // writeback store inst to lsroq
101  // writeback to LSROQ
102  s3_in.ready := true.B
103  io.lsroq.bits := s3_in.bits
104  io.lsroq.bits.miss := false.B
105  io.lsroq.bits.mmio := AddressSpace.isMMIO(s3_in.bits.paddr)
106  io.lsroq.valid := s3_in.fire()
107
108  //-------------------------------------------------------
109  // ST Pipeline Stage 4
110  // Store writeback, send store request to store buffer
111  //-------------------------------------------------------
112
113  // Writeback to CDB
114  // (0 until LoadPipelineWidth).map(i => {
115  //   io.ldout <> hitLoadOut
116  // })
117
118  //-------------------------------------------------------
119  // ST Pipeline Async Stage 1
120  // Read paddr from store buffer, query DTAG in DCache
121  //-------------------------------------------------------
122
123
124  //-------------------------------------------------------
125  // ST Pipeline Async Stage 2
126  // DTAG compare, write data to DCache
127  //-------------------------------------------------------
128
129  // Done in DCache
130
131  //-------------------------------------------------------
132  // ST Pipeline Async Stage 2
133  // DCache miss / Shared cache wirte
134  //-------------------------------------------------------
135
136  // update store buffer according to store fill buffer
137
138}
139