Skip to content

Commit 72881e2

Browse files
committed
feat(LoadQueueReplay): add support of fast wakeup for C_MA & C_FF
This Commit add support of fast wakeup from issueQueue of sta && std to LRQ. We will send sqIdx at og0 stage of issueQueue, latch 1 cycle. We will use scoreBoard to trace the wakeup and detect wakeup cancel. the source of wakeup cancel: og1Cancel, s0Cancel, s1Cancel.
1 parent be3c06a commit 72881e2

16 files changed

Lines changed: 246 additions & 43 deletions

src/main/scala/xiangshan/Parameters.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ case class XSCoreParameters
106106
LoadQueueRAWSize: Int = 56, // NOTE: make sure that LoadQueueRAWSize is power of 2.
107107
RollbackGroupSize: Int = 8,
108108
LoadQueueReplaySize: Int = 120,
109+
LoadDependenceScoreBoardWidth: Int = 3,
109110
LoadUncacheBufferSize: Int = 16,
110111
LoadQueueNWriteBanks: Int = 8, // NOTE: make sure that LoadQueueRARSize/LoadQueueRAWSize is divided by LoadQueueNWriteBanks
111112
StoreQueueSize: Int = 64,
@@ -706,6 +707,7 @@ trait HasXSParameter {
706707
val RAWlgSelectGroupSize = log2Ceil(RollbackGroupSize)
707708
val RAWTotalDelayCycles = scala.math.ceil(log2Ceil(LoadQueueRAWSize).toFloat / RAWlgSelectGroupSize).toInt + 1 - 2
708709
def LoadQueueReplaySize = coreParams.LoadQueueReplaySize
710+
def LoadDependenceScoreBoardWidth = coreParams.LoadDependenceScoreBoardWidth
709711
def LoadUncacheBufferSize = coreParams.LoadUncacheBufferSize
710712
def LoadQueueNWriteBanks = coreParams.LoadQueueNWriteBanks
711713
def StoreQueueSize = coreParams.StoreQueueSize

src/main/scala/xiangshan/XSCore.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
198198
memBlock.io.ooo_to_mem.backendToTopBypass := backend.io.toTop
199199
memBlock.io.ooo_to_mem.intIssue <> backend.io.mem.intIssue
200200
memBlock.io.ooo_to_mem.vecIssue <> backend.io.mem.vecIssue
201+
memBlock.io.ooo_to_mem.wakeupToLRQ <> backend.io.mem.wakeupToLRQ
202+
memBlock.io.ooo_to_mem.wakeupToLRQCancel := backend.io.mem.wakeupToLRQCancel
201203

202204
// By default, instructions do not have exceptions when they enter the function units.
203205
memBlock.io.ooo_to_mem.intIssue.flatten.foreach { case x => x.bits.flushPipe.foreach(_ := false.B) }

src/main/scala/xiangshan/backend/Backend.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame
315315
fpRegion.io.wakeupFromI2F. foreach(x => x := intRegion.io.cross.I2FWakeupOut.get)
316316
intRegion.io.F2IWakeupIn. foreach(x => x := fpRegion.io.cross.F2IWakeupOut.get)
317317
intRegion.io.wakeupFromLDU.foreach(x => x := io.mem.wakeup)
318+
intRegion.io.wakeupToLRQ.foreach(x => io.mem.wakeupToLRQ.zip(x.flatten).foreach { case (sink, source) => sink := source })
319+
intRegion.io.wakeupToLRQCancel.foreach(x => io.mem.wakeupToLRQCancel.zip(x.flatten).foreach { case (sink, source) => sink := source })
318320
intRegion.io.staFeedback. foreach(x => x := io.mem.staIqFeedback)
319321
vecRegion.io.vstuFeedback. foreach(x => x := io.mem.vstuIqFeedback)
320322
intRegion.io.ldCancel := io.mem.ldCancel
@@ -692,6 +694,8 @@ class BackendMemIO(implicit p: Parameters, params: BackendParams) extends XSBund
692694

693695
val intIssue = intSchdParams.genExuInputCopySrcBundleMemBlock
694696
val vecIssue = vecSchdParams.genExuInputCopySrcBundleMemBlock
697+
val wakeupToLRQ = Vec(params.StaCnt + params.StdCnt, ValidIO(new IssueQueueLRQWakeUpBundle))
698+
val wakeupToLRQCancel = Vec(params.StaCnt + params.StdCnt, new IssueQueueLRQWakeUpCancelBundle)
695699

696700
// store event difftest information
697701
val storeDebugInfo = Vec(EnsbufferWidth, new Bundle {

src/main/scala/xiangshan/backend/Bundles.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,14 @@ object Bundles {
810810
}
811811
}
812812

813+
class IssueQueueLRQWakeUpBundle(implicit p: Parameters) extends XSBundle {
814+
val sqIdx = new SqPtr
815+
}
816+
817+
class IssueQueueLRQWakeUpCancelBundle(implicit p: Parameters) extends XSBundle {
818+
val og1Cancel = Bool()
819+
}
820+
813821
class VPUCtrlSignals(implicit p: Parameters) extends XSBundle {
814822
// vtype
815823
val vill = Bool()
@@ -1378,7 +1386,7 @@ class ExuOutputVLoad(val params: ExeUnitParams)(implicit val p: Parameters) exte
13781386
val perfDebugInfo = Option.when(backendParams.debugEn)(new PerfDebugInfo())
13791387
val debug_seqNum = Option.when(backendParams.debugEn)(InstSeqNum())
13801388
}
1381-
1389+
13821390
class MemDebugBundle(implicit p: Parameters) extends XSBundle {
13831391
val isMMIO = Option.when(backendParams.basicDebugEn)(Bool())
13841392
val isNCIO = Option.when(backendParams.basicDebugEn)(Bool())

src/main/scala/xiangshan/backend/Region.scala

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ class Region(val params: SchdBlockParams)(implicit p: Parameters) extends XSModu
183183
imp.io.s2Resp.get.head.lqIdx.foreach(_ := feedBack.bits.lqIdx)
184184
imp.io.s2Resp.get.head.sqIdx.foreach(_ := feedBack.bits.sqIdx)
185185
}
186+
val stDataIQs = issueQueues.filter(iq => iq.param.StdCnt > 0)
187+
if (params.isIntSchd) {
188+
val lrqWakeupFromIQ = (stAddrIQs ++ stDataIQs).flatMap(_.io.wakeupToLRQ.get)
189+
io.wakeupToLRQ.get.flatten.zip(lrqWakeupFromIQ).foreach { case (sink, source) => sink := source }
190+
}
186191
val vecStuIQs = issueQueues.filter(iq => iq.param.VstuCnt > 0)
187192
vecStuIQs.zipWithIndex.foreach { case(imp, i) =>
188193
imp.io.memIO.get.lqDeqPtr.get := io.lqDeqPtr.get
@@ -258,7 +263,6 @@ class Region(val params: SchdBlockParams)(implicit p: Parameters) extends XSModu
258263
}
259264
}
260265
// std dispatch
261-
val stDataIQs = issueQueues.filter(iq => iq.param.StdCnt > 0)
262266
val staEnqs = stAddrIQs.map(_.io.enq).flatten
263267
val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
264268
val noStdExuParams = params.issueBlockParams.map(x => Seq.fill(x.numEnq)(x.exuBlockParams)).flatten.filter { x => x.map(!_.hasStdFu).reduce(_ && _) }
@@ -483,6 +487,20 @@ class Region(val params: SchdBlockParams)(implicit p: Parameters) extends XSModu
483487
io.toMemExu.get <> toMem
484488
val firstMemExu = bypassNetwork.io.toExus.int.indexWhere(x => x.map(xx => xx.bits.params.isMemExeUnit).reduce(_ || _))
485489
println(s"[Regin_int] firstMemExu = $firstMemExu")
490+
val firstStoreExu = bypassNetwork.io.toExus.int.indexWhere(x => x.map(xx => xx.bits.params.hasStoreFu).reduce(_ || _))
491+
println(s"[Regin_int] firstStoreExu = $firstStoreExu")
492+
493+
val storeWakeupCancel = Wire(io.wakeupToLRQCancel.get.cloneType)
494+
495+
storeWakeupCancel.zipWithIndex.foreach { case (toMemCancel, i) =>
496+
for (j <- toMemCancel.indices) {
497+
val toMemExuInput = bypassNetwork.io.toExus.int(firstStoreExu + i)(j)
498+
toMemCancel(j).og1Cancel := RegNext(LoadShouldCancel(toMemExuInput.bits.ctrl.loadDependency, io.ldCancel)) //regNext for timing
499+
}
500+
}
501+
502+
io.wakeupToLRQCancel.get.flatten.zip(storeWakeupCancel.flatten).foreach { case (sink, source) => sink := source }
503+
486504
for (i <- toMem.indices) {
487505
for (j <- toMem(i).indices) {
488506
val toMemExuInput = bypassNetwork.io.toExus.int(firstMemExu + i)(j)
@@ -860,6 +878,9 @@ class RegionIO(val params: SchdBlockParams)(implicit p: Parameters) extends XSBu
860878
val wakeupFromF2I = Option.when(params.isIntSchd)(Flipped(ValidIO(new IssueQueueIQWakeUpBundle(params.backendParam.getExuIdxF2I, params.backendParam))))
861879
val cross = new ExuCrossRegion(params)
862880
val toMemExu = Option.when(!params.isFpSchd)(params.genNewExuInputCopySrcBundleMemBlock)
881+
//to Mem, wake up LoadQueueReplay
882+
val wakeupToLRQ = Option.when(params.isIntSchd)(intSchdParam.genMemWakeupLRQBundle)
883+
val wakeupToLRQCancel = Option.when(params.isIntSchd)(intSchdParam.genMemWakeupCancelBundle)
863884
// fromMem
864885
val wakeupFromLDU = Option.when(params.isIntSchd)(Vec(params.LdExuCnt, Flipped(Valid(new MemWakeUpBundle))))
865886
val staFeedback = Option.when(params.isIntSchd)(Flipped(Vec(params.StaCnt, new MemRSFeedbackIO)))
@@ -945,4 +966,3 @@ class RegionIO(val params: SchdBlockParams)(implicit p: Parameters) extends XSBu
945966
val debugIQEnqHasIssuedVec = Option.when(backendParams.debugEn)(Vec(IQNum, Output(Bool())))
946967
val debugIQDeqRobIdxVec = Option.when(backendParams.debugEn)(Vec(iqDeqSum, ValidIO(new RobPtr())))
947968
}
948-

src/main/scala/xiangshan/backend/issue/IssueBlockParams.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ case class IssueBlockParams(
5959

6060
def isStdIQ: Boolean = StdCnt > 0
6161

62+
def isStoreIQ: Boolean = isStAddrIQ || isStdIQ
63+
6264
def isHyAddrIQ: Boolean = HyuCnt > 0
6365

6466
def isVecLduIQ: Boolean = (VlduCnt + VseglduCnt) > 0
@@ -406,6 +408,14 @@ case class IssueBlockParams(
406408
MixedVec(this.exuBlockParams.map(x => DecoupledIO(x.genNewExuInputCopySrcBundle)))
407409
}
408410

411+
def genMemWakeupLRQBundle(implicit p: Parameters): MixedVec[ValidIO[IssueQueueLRQWakeUpBundle]] = {
412+
MixedVec(this.exuBlockParams.filter(_.hasStoreFu).map(x => ValidIO(new IssueQueueLRQWakeUpBundle)))
413+
}
414+
415+
def genMemWakeupCancelBundle(implicit p: Parameters): MixedVec[IssueQueueLRQWakeUpCancelBundle] = {
416+
MixedVec(this.exuBlockParams.filter(x => x.hasStoreFu).map(x => new IssueQueueLRQWakeUpCancelBundle))
417+
}
418+
409419
def genExuOutputDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[ExuOutput]] = {
410420
MixedVec(this.exuParams.map(x => DecoupledIO(x.genExuOutputBundle)))
411421
}
@@ -487,6 +497,14 @@ case class IssueBlockParams(
487497
MixedVec(this.wakeUpInExuSources.map(x => ValidIO(new IssueQueueIQWakeUpBundle(backendParam.getExuIdx(x.name), backendParam))))
488498
}
489499

500+
def genIOWakeUpLRQValidBundle(implicit p: Parameters): MixedVec[ValidIO[IssueQueueLRQWakeUpBundle]] = {
501+
MixedVec(exuBlockParams.filter(_.hasStoreFu).map(x => ValidIO(new IssueQueueLRQWakeUpBundle)))
502+
}
503+
504+
def genIOWakeUpCancelBundle(implicit p: Parameters): MixedVec[IssueQueueLRQWakeUpCancelBundle] = {
505+
MixedVec(exuBlockParams.filter(_.hasStoreFu).map(x => Output(new IssueQueueLRQWakeUpCancelBundle)))
506+
}
507+
490508
def genOGRespBundle(implicit p: Parameters) = {
491509
implicit val issueBlockParams = this
492510
MixedVec(exuBlockParams.map(_ => new OGRespBundle))

src/main/scala/xiangshan/backend/issue/IssueQueue.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class IssueQueueIO()(implicit p: Parameters, params: IssueBlockParams) extends X
3434
val wakeupFromF2I: Option[ValidIO[IssueQueueIQWakeUpBundle]] = Option.when(params.needWakeupFromF2I)(Flipped(ValidIO(new IssueQueueIQWakeUpBundle(params.backendParam.getExuIdxF2I, params.backendParam))))
3535
val wakeupFromWBDelayed: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
3636
val wakeupFromIQDelayed: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
37+
//to Mem, wake up LoadQueueReplay
38+
val wakeupToLRQ = Option.when(params.isStAddrIQ || params.isStdIQ)(params.genIOWakeUpLRQValidBundle)
3739
val vlFromIntIsZero = Input(Bool())
3840
val vlFromIntIsVlmax = Input(Bool())
3941
val vlFromVfIsZero = Input(Bool())
@@ -948,6 +950,16 @@ class IssueQueueImp(implicit p: Parameters, params: IssueBlockParams) extends XS
948950
dontTouch(io.deqDelay)
949951
dontTouch(deqBeforeDly)
950952
}
953+
// sta wake up LRQ in og1
954+
io.wakeupToLRQ.foreach { case wakeupOption =>
955+
wakeupOption.zipWithIndex.foreach { case (wakeup, i) =>
956+
val wakeupCancel = LoadShouldCancel(io.deqDelay(i).bits.loadDependency, io.ldCancel)
957+
val wakeupValid = io.deqDelay(i).fire && !wakeupCancel
958+
wakeup.valid := RegNext(wakeupValid) // next cycle is og1
959+
wakeup.bits.sqIdx := RegNext(entries.io.deqOg1Payload(i).sqIdx.get)
960+
}
961+
}
962+
951963
io.wakeupToIQ.zipWithIndex.foreach { case (wakeup, i) =>
952964
if (wakeUpQueues(i).nonEmpty) {
953965
wakeup.valid := wakeUpQueues(i).get.io.deq.valid

src/main/scala/xiangshan/backend/issue/SchdBlockParams.scala

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ case class SchdBlockParams(
103103
def needSrcVxrm: Boolean = issueBlockParams.map(_.needSrcVxrm).reduce(_ || _)
104104

105105
def writeVConfig: Boolean = issueBlockParams.map(_.writeVConfig).reduce(_ || _)
106-
106+
107107
def writeVType: Boolean = issueBlockParams.map(_.writeVType).reduce(_ || _)
108108

109109
def numRedirect: Int = issueBlockParams.map(_.numRedirect).sum
@@ -152,6 +152,14 @@ case class SchdBlockParams(
152152
MixedVec(this.issueBlockParams.filter(_.isMemBlockIQ).map(_.genNewExuInputDecoupledCopySrcBundle))
153153
}
154154

155+
def genMemWakeupLRQBundle(implicit p: Parameters): MixedVec[MixedVec[ValidIO[IssueQueueLRQWakeUpBundle]]] = {
156+
MixedVec(this.issueBlockParams.filter(_.isStoreIQ).map(_.genMemWakeupLRQBundle))
157+
}
158+
159+
def genMemWakeupCancelBundle(implicit p: Parameters): MixedVec[MixedVec[IssueQueueLRQWakeUpCancelBundle]] = {
160+
MixedVec(this.issueBlockParams.filter(_.isStoreIQ).map(_.genMemWakeupCancelBundle))
161+
}
162+
155163
def genExuOutputDecoupledBundle(implicit p: Parameters): MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = {
156164
MixedVec(this.issueBlockParams.map(_.genExuOutputDecoupledBundle))
157165
}
@@ -187,7 +195,7 @@ case class SchdBlockParams(
187195
def genExuOutputDecoupledBundleNoMemBlock(implicit p: Parameters): MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = {
188196
MixedVec(this.issueBlockParams.filterNot(_.isMemBlockIQ).map(_.genExuOutputDecoupledBundle))
189197
}
190-
198+
191199
def genNewExuOutputDecoupledBundleNoMemBlock(implicit p: Parameters): MixedVec[MixedVec[DecoupledIO[NewExuOutput]]] = {
192200
MixedVec(this.issueBlockParams.filterNot(_.isMemBlockIQ).map(_.genNewExuOutputDecoupledBundle))
193201
}

src/main/scala/xiangshan/mem/MemBlock.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ class ooo_to_mem(implicit p: Parameters) extends MemBlockBundle {
194194

195195
val intIssue: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputCopySrcBundleMemBlock)
196196
val vecIssue: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vecSchdParams.genExuInputCopySrcBundleMemBlock)
197+
val wakeupToLRQ = Flipped(Vec(StaCnt + StdCnt, ValidIO(new IssueQueueLRQWakeUpBundle)))
198+
val wakeupToLRQCancel = Input(Vec(StaCnt + StdCnt, new IssueQueueLRQWakeUpCancelBundle))
197199
}
198200

199201
class mem_to_ooo(implicit p: Parameters) extends MemBlockBundle {
@@ -439,6 +441,7 @@ class MemBlockInlinedImp(outer: MemBlockInlined) extends LazyModuleImp(outer)
439441

440442
val intIssue: Seq[DecoupledIO[ExuInput]] = io.ooo_to_mem.intIssue.flatten
441443
val vecIssue: Seq[DecoupledIO[ExuInput]] = io.ooo_to_mem.vecIssue.flatten
444+
val wakeupToLRQCancel = Wire(Vec(StaCnt + StdCnt, new LRQWakeUpCancelBundle))
442445
val issueLda = intIssue.filter(_.bits.params.hasLoadFu)
443446
val issueSta = intIssue.filter(_.bits.params.hasStoreAddrFu)
444447
val issueStd = intIssue.filter(_.bits.params.hasStdFu)
@@ -492,6 +495,19 @@ class MemBlockInlinedImp(outer: MemBlockInlined) extends LazyModuleImp(outer)
492495
val newLoadUnits = Seq.tabulate(LduCnt)(i => Module(new NewLoadUnit(ldaParams(i))))
493496
val storeUnits = Seq.tabulate(StaCnt)(i => Module(new NewStoreUnit(staParams(i))))
494497
val stdExeUnits = Seq.tabulate(StdCnt)(i => Module(new StdExeUnit(stdParams(i))))
498+
499+
wakeupToLRQCancel.take(StaCnt).zip(storeUnits).zip(io.ooo_to_mem.wakeupToLRQCancel.take(StaCnt)).foreach {
500+
case ((sink, stu), source) =>
501+
sink.og1Cancel := source.og1Cancel //had latch in issueQueue
502+
sink.s0Cancel := RegNext(!stu.io.stin.ready)
503+
sink.s1Cancel := stu.io.feedBackSlow.valid && !stu.io.feedBackSlow.bits.hit // had latch in stu, so no need to latch again here
504+
}
505+
wakeupToLRQCancel.drop(StaCnt).take(StdCnt).zip(stdExeUnits).zip(io.ooo_to_mem.wakeupToLRQCancel.drop(StaCnt).take(StdCnt)).foreach {
506+
case ((sink, std), source) =>
507+
sink.og1Cancel := source.og1Cancel //had latch in issueQueue
508+
sink.s0Cancel := RegNext(!std.io.in.ready)
509+
sink.s1Cancel := false.B // TODO: used in the future
510+
}
495511
val atomicsUnit = Module(new AtomicsUnit(mouParam))
496512

497513
// The number of vector load/store units is decoupled with the number of load/store units
@@ -1028,6 +1044,8 @@ class MemBlockInlinedImp(outer: MemBlockInlined) extends LazyModuleImp(outer)
10281044

10291045
// lsq.io.rob <> io.lsqio.rob
10301046
lsq.io.enq <> io.ooo_to_mem.enqLsq
1047+
lsq.io.wakeupToLRQ <> io.ooo_to_mem.wakeupToLRQ
1048+
lsq.io.wakeupToLRQCancel := wakeupToLRQCancel
10311049
lsq.io.brqRedirect <> redirect
10321050

10331051
// violation rollback

src/main/scala/xiangshan/mem/lsqueue/LSQBundle.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ import xiangshan.cache.{CMOReq, CMOResp, DCacheWordReqWithVaddrAndPfFlag, Uncach
2828
import xiangshan.frontend.ftq.FtqPtr
2929
import xiangshan.mem.Bundles.{SQForward, StoreMaskBundle}
3030

31+
class LRQWakeUpCancelBundle(implicit p: Parameters) extends XSBundle {
32+
val og1Cancel = Bool()
33+
val s0Cancel = Bool()
34+
val s1Cancel = Bool()
35+
}
36+
3137
class StoreQueueEnqIO(implicit p: Parameters) extends MemBlockBundle {
3238
// Bundle define
3339

@@ -112,7 +118,7 @@ class StoreAddrIO(implicit p: Parameters) extends MemBlockBundle {
112118
* means this write request need to write whole cacheline.
113119
* */
114120
val wlineflag = Bool() // store write the whole cache line.
115-
121+
116122
// misalign
117123
val isUnalign = Bool()
118124
val cross16Byte = Bool()

0 commit comments

Comments
 (0)