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