xref: /XiangShan/src/main/scala/xiangshan/backend/issue/OthersEntry.scala (revision 28607074d64ccca05aab94e22fec1390305572ec)
1package xiangshan.backend.issue
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import utility.HasCircularQueuePtrHelper
7import utils.{MathUtils, OptionWrapper}
8import xiangshan._
9import xiangshan.backend.Bundles._
10import xiangshan.backend.fu.FuType
11import xiangshan.backend.datapath.DataSource
12import xiangshan.backend.rob.RobPtr
13import xiangshan.backend.issue.EntryBundles._
14import xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr}
15
16
17class OthersEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
18  //input
19  val commonIn        = new CommonInBundle
20  //output
21  val commonOut       = new CommonOutBundle
22
23  def wakeup          = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ
24}
25
26class OthersEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
27  val io = IO(new OthersEntryIO)
28
29  val validReg        = RegInit(false.B)
30  val entryReg        = Reg(new EntryBundle)
31
32  val common          = Wire(new CommonWireBundle)
33  val entryUpdate     = Wire(new EntryBundle)
34  val entryRegNext    = Wire(new EntryBundle)
35  val hasWakeupIQ     = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle))
36
37  //Reg
38  validReg := common.validRegNext
39  entryReg := entryRegNext
40
41  //Wire
42  CommonWireConnect(common, hasWakeupIQ, validReg, entryReg.status, io.commonIn, false)
43
44  if (params.hasIQWakeUp) {
45    ShiftLoadDependency(hasWakeupIQ.get)
46    CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, entryReg.status, io.commonIn, false)
47  }
48
49  when(io.commonIn.enq.valid) {
50    assert(common.enqReady, "Entry is not ready when enq is valid\n")
51  }
52
53  when(io.commonIn.enq.valid) {
54    entryRegNext := io.commonIn.enq.bits
55  }.otherwise {
56    entryRegNext := entryUpdate
57  }
58
59  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, entryReg.status, io.commonIn, false)
60
61  //output
62  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, entryReg.status, io.commonIn, false, isComp)
63}
64
65class OthersEntryMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry(isComp)
66  with HasCircularQueuePtrHelper {
67  EntryMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate, false)
68}
69
70class OthersEntryVecMemAddr(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends OthersEntryMem(isComp) {
71
72  require(params.isVecMemAddrIQ, "OthersEntryVecMemAddr can only be instance of VecMemAddr IQ")
73
74  val commonIn = io.commonIn
75  val enqValid = commonIn.enq.valid && commonIn.transSel
76  val fromMem = commonIn.fromMem.get
77  val memStatus = entryReg.status.mem.get
78  val memStatusNext = entryRegNext.status.mem.get
79  val shouldBlock = Mux(commonIn.enq.valid && commonIn.transSel, commonIn.enq.bits.status.blocked, entryReg.status.blocked)
80  // load cannot be issued before older store, unless meet some condition
81  val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr)
82
83  val vecMemStatus = entryReg.status.vecMem.get
84  val vecMemStatusNext = entryRegNext.status.vecMem.get
85  val vecMemStatusUpdate = entryUpdate.status.vecMem.get
86
87  val fromLsq = io.commonIn.fromLsq.get
88
89  when(enqValid) {
90    vecMemStatusNext := io.commonIn.enq.bits.status.vecMem.get
91  }.otherwise {
92    vecMemStatusNext := vecMemStatus
93  }
94
95  val isLsqHead = {
96    entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr &&
97    entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr
98  }
99  dontTouch(isLsqHead)
100
101  entryRegNext.status.blocked := !isLsqHead
102}
103
104class OthersEntryVecMemData(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry(isComp)
105  with HasCircularQueuePtrHelper {
106
107  require(params.isVecStDataIQ, "OthersEntryVecMemData can only be instance of VecMemData IQ")
108
109  val commonIn = io.commonIn
110  val enqValid = commonIn.enq.valid && commonIn.transSel
111  val vecMemStatus = entryReg.status.vecMem.get
112  val vecMemStatusNext = entryRegNext.status.vecMem.get
113  val fromLsq = io.commonIn.fromLsq.get
114
115  when(enqValid) {
116    vecMemStatusNext.sqIdx := commonIn.enq.bits.status.vecMem.get.sqIdx
117    vecMemStatusNext.lqIdx := commonIn.enq.bits.status.vecMem.get.lqIdx
118    vecMemStatusNext.uopIdx := commonIn.enq.bits.status.vecMem.get.uopIdx
119  }.otherwise {
120    vecMemStatusNext := vecMemStatus
121  }
122
123  val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value
124
125  entryRegNext.status.blocked := !isLsqHead
126}
127
128object OthersEntry {
129  def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): OthersEntry = {
130    iqParams.schdType match {
131      case IntScheduler() => new OthersEntry(isComp)
132      case MemScheduler() =>
133        if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new OthersEntryMem(isComp)
134        else if (iqParams.isVecMemAddrIQ) new OthersEntryVecMemAddr(isComp)
135        else if (iqParams.isVecStDataIQ) new OthersEntryVecMemData(isComp)
136        else new OthersEntry(isComp)
137      case VfScheduler() => new OthersEntry(isComp)
138      case _ => null
139    }
140  }
141}