xref: /XiangShan/src/main/scala/xiangshan/backend/issue/OthersEntry.scala (revision 397c0f330295d110f9451000814959f075ccb37a)
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(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 && io.commonIn.transSel) {
50    entryRegNext := io.commonIn.enq.bits
51  }.otherwise {
52    entryRegNext := entryUpdate
53  }
54
55  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, entryReg.status, io.commonIn, false)
56
57  //output
58  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, entryReg.status, io.commonIn, false)
59}
60
61class OthersEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry
62  with HasCircularQueuePtrHelper {
63  EntryMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate, false)
64}
65
66class OthersEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntryMem {
67
68  require(params.isVecMemAddrIQ, "OthersEntryVecMemAddr can only be instance of VecMemAddr IQ")
69
70  val commonIn = io.commonIn
71  val enqValid = commonIn.enq.valid && commonIn.transSel
72  val fromMem = commonIn.fromMem.get
73  val memStatus = entryReg.status.mem.get
74  val memStatusNext = entryRegNext.status.mem.get
75  val shouldBlock = Mux(commonIn.enq.valid && commonIn.transSel, commonIn.enq.bits.status.blocked, entryReg.status.blocked)
76  // load cannot be issued before older store, unless meet some condition
77  val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr)
78
79  val vecMemStatus = entryReg.status.vecMem.get
80  val vecMemStatusNext = entryRegNext.status.vecMem.get
81  val vecMemStatusUpdate = entryUpdate.status.vecMem.get
82
83  val fromLsq = io.commonIn.fromLsq.get
84
85  when(enqValid) {
86    vecMemStatusNext := io.commonIn.enq.bits.status.vecMem.get
87  }.otherwise {
88    vecMemStatusNext := vecMemStatus
89  }
90
91  val isLsqHead = {
92    entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr &&
93    entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr
94  }
95  dontTouch(isLsqHead)
96
97  entryRegNext.status.blocked := !isLsqHead
98}
99
100class OthersEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry
101  with HasCircularQueuePtrHelper {
102
103  require(params.isVecStDataIQ, "OthersEntryVecMemData can only be instance of VecMemData IQ")
104
105  val commonIn = io.commonIn
106  val enqValid = commonIn.enq.valid && commonIn.transSel
107  val vecMemStatus = entryReg.status.vecMem.get
108  val vecMemStatusNext = entryRegNext.status.vecMem.get
109  val fromLsq = io.commonIn.fromLsq.get
110
111  when(enqValid) {
112    vecMemStatusNext.sqIdx := commonIn.enq.bits.status.vecMem.get.sqIdx
113    vecMemStatusNext.lqIdx := commonIn.enq.bits.status.vecMem.get.lqIdx
114    vecMemStatusNext.uopIdx := commonIn.enq.bits.status.vecMem.get.uopIdx
115  }.otherwise {
116    vecMemStatusNext := vecMemStatus
117  }
118
119  val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value
120
121  entryRegNext.status.blocked := !isLsqHead
122}
123
124object OthersEntry {
125  def apply(implicit p: Parameters, iqParams: IssueBlockParams): OthersEntry = {
126    iqParams.schdType match {
127      case IntScheduler() => new OthersEntry()
128      case MemScheduler() =>
129        if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new OthersEntryMem()
130        else if (iqParams.isVecMemAddrIQ) new OthersEntryVecMemAddr()
131        else if (iqParams.isVecStDataIQ) new OthersEntryVecMemData()
132        else new OthersEntry()
133      case VfScheduler() => new OthersEntry()
134      case _ => null
135    }
136  }
137}