From 462254359b333e1545dabcae1994b87a4a0e890a Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Tue, 8 Aug 2023 23:40:41 +0800 Subject: [PATCH 01/16] feat:ghr specUpdate and fix --- src/src/frontend/bpu/BPU.scala | 15 +++--- src/src/frontend/bpu/TagePredictor.scala | 63 +++++++++++++++++++++++- src/src/spec/Param.scala | 27 ++++++++-- 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/src/frontend/bpu/BPU.scala b/src/src/frontend/bpu/BPU.scala index 076ea2ce..7b3567be 100644 --- a/src/src/frontend/bpu/BPU.scala +++ b/src/src/frontend/bpu/BPU.scala @@ -220,12 +220,15 @@ class BPU( // connect tage Predictor module val tagePredictorModule = Module(new TagePredictor) - tagePredictorModule.io.pc := io.pc - tageQueryMeta := tagePredictorModule.io.tageQueryMeta - predictTaken := tagePredictorModule.io.predictBranchTaken - predictValid := tagePredictorModule.io.predictValid - tagePredictorModule.io.updatePc := io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.startPc - tagePredictorModule.io.updateInfoPort := tageUpdateInfo + tagePredictorModule.io.pc := io.pc + tageQueryMeta := tagePredictorModule.io.tageQueryMeta + predictTaken := tagePredictorModule.io.predictBranchTaken + predictValid := tagePredictorModule.io.predictValid + tagePredictorModule.io.updatePc := io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.startPc + tagePredictorModule.io.updateInfoPort := tageUpdateInfo + tagePredictorModule.io.bpuSpecTaken := false.B + tagePredictorModule.io.bpuSpecValid := false.B + tagePredictorModule.io.ghrUpdateNdBundle := GhrUpdateNdBundle.default // tagePredictorModule.io.perfTagHitCounters <> DontCare } diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 27224c1b..c67e7e9f 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -6,8 +6,18 @@ import chisel3.util.random.LFSR import frontend.bpu.bundles.{BpuFtqMetaNdPort, TagePredictorUpdateInfoPort} import frontend.bpu.components.Bundles.TageMetaPort import frontend.bpu.components._ +import spec.Param.BPU.GhrFixType import spec._ - +class GhrUpdateNdBundle extends Bundle { + val bpuSpecValid = Bool() // speculative update + val bpuSpecTaken = Bool() + val isFixGhrValid = Bool() + val ghrFixType = UInt(Param.BPU.GhrFixType.width.W) + val isFixBranchTaken = Bool() +} +object GhrUpdateNdBundle { + def default = 0.U.asTypeOf(new GhrUpdateNdBundle) +} // TAGE predictor // This is the main predictor class TagePredictor( @@ -35,6 +45,11 @@ class TagePredictor( val updatePc = Input(UInt(Width.Reg.data)) val updateInfoPort = Input(new TagePredictorUpdateInfoPort) + // BPU predict info + val ghrUpdateNdBundle = Input(new GhrUpdateNdBundle) + val bpuSpecValid = Input(Bool()) // speculative update + val bpuSpecTaken = Input(Bool()) + // TODO PMU // val perfTagHitCounters = Output(Vec(32, UInt((tagComponentNum + 1).W))) @@ -115,12 +130,56 @@ class TagePredictor( // END of Defines //////////////////////////////////////////////////////////////////////////////////////////// + val specPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) + val commitPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) + val checkPtr = WireDefault(0.U(Param.BPU.ftqPtrWidth.W)) + val checkDepth = Wire(UInt(Param.BPU.ftqPtrWidth.W)) + checkDepth := checkPtr - commitPtr + // Global History Register val ghr = RegInit(0.U(ghrDepth.W)) + + isGlobalHistoryUpdateReg := isUpdateValid + + // speculative Global history update + // 1. when ftb hit and predict ,update ghr with predictBranchTaken, specPtr + 1 + // 2. when inst commit, commitPtr + 1 + // fix error global history + // 1. when check a direction error, Cat the correct old history and actually taken as fixed history,specPtr keep as checkPtr + // 2. when check a branch inst actually is taken without prediction, update the history with checkPoint,specPtr = 1 + checkPtr + // 3. when detect a non branch inst predict taken or an exception that discards a predicted inst,recover the history, specPtr = checkPtr - 1 + // ghr update priority: + // 1.commitStage : recover + // 2.exeStage : fix or update + // 3.preDecoderStage :recover or update + // 4.spec update + +// def updateGhr(location: UInt, isTaken: Bool, originGhr: UInt) = { +// ghr := Cat(ghr(ghrDepth - 2, location), isTaken) +// } + + when(isUpdateValid) { + commitPtr := commitPtr + 1.U + } + when(io.ghrUpdateNdBundle.isFixGhrValid) { + switch(io.ghrUpdateNdBundle.ghrFixType) { + is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { + ghr := ghr >> checkDepth + } + is(GhrFixType.exeFixDirection) { + ghr := Cat(ghr >> (checkDepth - 1.U), io.ghrUpdateNdBundle.isFixBranchTaken) + } + is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { + ghr := Cat(ghr >> (checkDepth - 1.U), true.B) + } + } + }.elsewhen(io.bpuSpecValid) { + ghr := Cat(ghr(ghrDepth - 2, 0), io.bpuSpecTaken) + } + when(isUpdateValid) { ghr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) } - isGlobalHistoryUpdateReg := isUpdateValid //////////////////////////////////////////////////////////////////////////////////////////// // Query Logic diff --git a/src/src/spec/Param.scala b/src/src/spec/Param.scala index 52f9f871..7a555b16 100644 --- a/src/src/spec/Param.scala +++ b/src/src/spec/Param.scala @@ -184,15 +184,15 @@ object Param { object TagePredictor { // ComponentTableDepth // predictor num = tagComponentNum + 1 (BasePredictor) - val ghrLength = 140 val tagComponentTagWidth = 12 val tagComponentNum = 4 - val componentHistoryLength = Seq(0, 11, 23, 53, 131, 230, 479, 1012) // ipc 0.6452 + val componentHistoryLength = Seq(0, 11, 23, 53, 131) val componentTableDepth = Seq(8192, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024) - val componentCtrWidth = Seq(2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) - val componentUsefulWidth = Seq(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1) // tage paper suggest 2, but in order to save source, we use 1 bit(won't decrease ipc) + val componentCtrWidth = Seq(2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) + val componentUsefulWidth = Seq(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) + // tage paper suggest 2-bits useful, but in order to save source, we use 1 bit(won't decrease ipc) + val ghrLength = componentHistoryLength(tagComponentNum) + ftqSize } object FTB { @@ -217,6 +217,23 @@ object Param { def width = log2Ceil(count + 1) } + + object GhrFixType { + var count = 0 + + private def next = { + count += 1 + count.U + } + + val commitBrExcp = 0.U + val exeFixDirection = next + val exeUpdateJump = next + val decodeUpdateJump = next + val decodeBrExcp = next + + def width = log2Ceil(count + 1) + } } object SimpleFetchStageState extends ChiselEnum { From 3a36e9335c8b7bf900d479b3e06d0a6aad05060d Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Wed, 9 Aug 2023 16:57:54 +0800 Subject: [PATCH 02/16] fix:ghrHash error delay --- src/src/frontend/bpu/TagePredictor.scala | 43 ++++++++++++------- .../bpu/components/Bundles/TageMetaPort.scala | 6 +-- .../bpu/components/TaggedPreditor.scala | 2 + 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index c67e7e9f..3c20d18c 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -129,15 +129,24 @@ class TagePredictor( //////////////////////////////////////////////////////////////////////////////////////////// // END of Defines //////////////////////////////////////////////////////////////////////////////////////////// + // Global History Register speculative update logic + //////////////////////////////////////////////////////////////////////////////////////////// - val specPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) - val commitPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) - val checkPtr = WireDefault(0.U(Param.BPU.ftqPtrWidth.W)) - val checkDepth = Wire(UInt(Param.BPU.ftqPtrWidth.W)) - checkDepth := checkPtr - commitPtr + val specPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) + val nextSpecPtr = Wire(UInt(Param.BPU.ftqPtrWidth.W)) + val commitPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) + val checkPtr = WireDefault(0.U(Param.BPU.ftqPtrWidth.W)) + val checkDepth = Wire(UInt(Param.BPU.ftqPtrWidth.W)) + checkDepth := checkPtr - commitPtr // calculate the location of the correct old history // Global History Register - val ghr = RegInit(0.U(ghrDepth.W)) + val ghr = RegInit(0.U(ghrDepth.W)) + val nextGhr = Wire(UInt(ghrDepth.W)) + // default nextGhr keep; ghr = RegNext(nextGhr) + nextGhr := ghr + ghr := nextGhr + nextSpecPtr := specPtr + specPtr := nextSpecPtr isGlobalHistoryUpdateReg := isUpdateValid @@ -154,32 +163,34 @@ class TagePredictor( // 3.preDecoderStage :recover or update // 4.spec update -// def updateGhr(location: UInt, isTaken: Bool, originGhr: UInt) = { -// ghr := Cat(ghr(ghrDepth - 2, location), isTaken) -// } - when(isUpdateValid) { commitPtr := commitPtr + 1.U } when(io.ghrUpdateNdBundle.isFixGhrValid) { switch(io.ghrUpdateNdBundle.ghrFixType) { is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { - ghr := ghr >> checkDepth + nextGhr := ghr >> checkDepth // recover to the old history + nextSpecPtr := checkPtr - 1.U } is(GhrFixType.exeFixDirection) { - ghr := Cat(ghr >> (checkDepth - 1.U), io.ghrUpdateNdBundle.isFixBranchTaken) + nextGhr := Cat(ghr >> checkDepth, io.ghrUpdateNdBundle.isFixBranchTaken) // fix error predict + nextSpecPtr := checkPtr } is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { - ghr := Cat(ghr >> (checkDepth - 1.U), true.B) + nextGhr := Cat(ghr >> checkDepth, true.B) // update the branch that has not been predicted + nextSpecPtr := checkPtr + 1.U } } }.elsewhen(io.bpuSpecValid) { - ghr := Cat(ghr(ghrDepth - 2, 0), io.bpuSpecTaken) + nextGhr := Cat(ghr(ghrDepth - 2, 0), io.bpuSpecTaken) + nextSpecPtr := specPtr + 1.U } when(isUpdateValid) { - ghr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) + nextGhr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) } + // output + io.tageQueryMeta.checkPtr := nextSpecPtr //////////////////////////////////////////////////////////////////////////////////////////// // Query Logic @@ -208,7 +219,7 @@ class TagePredictor( ) // Query taggedPreditor.io.isGlobalHistoryUpdate := isUpdateValid - taggedPreditor.io.globalHistory := ghr(historyLengths(providerId + 1) - 1, 0) + taggedPreditor.io.globalHistory := nextGhr(historyLengths(providerId + 1) - 1, 0) taggedPreditor.io.pc := io.pc tagUsefulbits(providerId) := taggedPreditor.io.usefulBits tagCtrbits(providerId) := taggedPreditor.io.ctrBits diff --git a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala index a8033587..7793a9c1 100644 --- a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala +++ b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala @@ -16,10 +16,10 @@ class TageMetaPort( val tagPredictorOriginTags = Vec(tagComponentNum, UInt(tagComponentTagWidth.W)) val tagPredictorHitIndexs = Vec(tagComponentNum, UInt(10.W)) val tagPredictorUsefulBits = Vec(tagComponentNum, UInt(3.W)) + // global history info + val checkPtr = UInt(Param.BPU.ftqPtrWidth.W) } object TageMetaPort { - val tagComponentNum = Param.BPU.TagePredictor.tagComponentNum - val tagComponentTagWidth = Param.BPU.TagePredictor.tagComponentTagWidth - def default = 0.U.asTypeOf(new TageMetaPort) + def default = 0.U.asTypeOf(new TageMetaPort) } diff --git a/src/src/frontend/bpu/components/TaggedPreditor.scala b/src/src/frontend/bpu/components/TaggedPreditor.scala index 72864619..377bd7ed 100644 --- a/src/src/frontend/bpu/components/TaggedPreditor.scala +++ b/src/src/frontend/bpu/components/TaggedPreditor.scala @@ -62,6 +62,8 @@ class TaggedPreditor( val reallocEntry = Input(Bool()) val updateTag = Input(UInt(phtTagWidth.W)) val updateIndex = Input(UInt(log2Ceil(phtDepth).W)) + + // speculative }) def toPhtLine(line: UInt) = { From 4da4270175fd79ba3c77c81ae987189848fdf101 Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Wed, 9 Aug 2023 23:06:11 +0800 Subject: [PATCH 03/16] feat:implement speculative ghrHash fix --- src/src/frontend/FetchTargetQueue.scala | 2 +- src/src/frontend/bpu/TagePredictor.scala | 77 ++++++++++++------- .../bpu/components/Bundles/TageMetaPort.scala | 8 +- .../bpu/components/TaggedPreditor.scala | 55 +++++++++---- src/src/frontend/bpu/utils/CsrHash.scala | 50 ++++++++++-- 5 files changed, 138 insertions(+), 54 deletions(-) diff --git a/src/src/frontend/FetchTargetQueue.scala b/src/src/frontend/FetchTargetQueue.scala index 815ead19..0b840ef1 100644 --- a/src/src/frontend/FetchTargetQueue.scala +++ b/src/src/frontend/FetchTargetQueue.scala @@ -204,7 +204,7 @@ class FetchTargetQueue( io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.startPc := ftqVecReg(commitFtqId).startPc io.bpuFtqPort.ftqBpuTrainMeta.isCrossCacheline := ftqVecReg(commitFtqId).isCrossCacheline - io.bpuFtqPort.ftqBpuTrainMeta.tageOriginMeta := ftqBpuMetaRegs(commitFtqId).tageQueryMeta + io.bpuFtqPort.ftqBpuTrainMeta.tageOriginMeta := ftqBpuMetaRegs(commitFtqId).tageQueryMeta io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.jumpTargetAddr := ftqBranchMetaRegs(commitFtqId).jumpTargetAddr io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.fallThroughAddr := ftqBranchMetaRegs(commitFtqId).fallThroughAddr diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 3c20d18c..025d9434 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -34,6 +34,7 @@ class TagePredictor( val addrWidth = log2Ceil(addr) val pointerWidth = log2Ceil(entryNum) val tagComPtrWidth = log2Ceil(tagComponentNum + 1) + val phtAddrWidth = log2Ceil(phtDepths(1)) val io = IO(new Bundle { // Query signal val pc = Input(UInt(Width.Reg.data)) @@ -131,7 +132,7 @@ class TagePredictor( //////////////////////////////////////////////////////////////////////////////////////////// // Global History Register speculative update logic //////////////////////////////////////////////////////////////////////////////////////////// - + // predict queue val specPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) val nextSpecPtr = Wire(UInt(Param.BPU.ftqPtrWidth.W)) val commitPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) @@ -142,12 +143,18 @@ class TagePredictor( // Global History Register val ghr = RegInit(0.U(ghrDepth.W)) val nextGhr = Wire(UInt(ghrDepth.W)) - // default nextGhr keep; ghr = RegNext(nextGhr) + // default nextGhr keep value; ghr = RegNext(nextGhr) (assign in the next clock) nextGhr := ghr ghr := nextGhr nextSpecPtr := specPtr specPtr := nextSpecPtr + // signal that indicates how to fix globalHistory Hash value + val isFixUpdateCsr = WireDefault(false.B) + val isFixDirectionCsr = WireDefault(false.B) + val isRecoverCsr = WireDefault(false.B) +// val originHash = Input(UInt(outputLength.W)) + isGlobalHistoryUpdateReg := isUpdateValid // speculative Global history update @@ -169,16 +176,19 @@ class TagePredictor( when(io.ghrUpdateNdBundle.isFixGhrValid) { switch(io.ghrUpdateNdBundle.ghrFixType) { is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { - nextGhr := ghr >> checkDepth // recover to the old history - nextSpecPtr := checkPtr - 1.U + nextGhr := ghr >> checkDepth // recover to the old history + nextSpecPtr := checkPtr - 1.U + isRecoverCsr := true.B } is(GhrFixType.exeFixDirection) { - nextGhr := Cat(ghr >> checkDepth, io.ghrUpdateNdBundle.isFixBranchTaken) // fix error predict - nextSpecPtr := checkPtr + nextGhr := Cat(ghr >> checkDepth, io.ghrUpdateNdBundle.isFixBranchTaken) // fix error predict + nextSpecPtr := checkPtr + isFixDirectionCsr := true.B } is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { - nextGhr := Cat(ghr >> checkDepth, true.B) // update the branch that has not been predicted - nextSpecPtr := checkPtr + 1.U + nextGhr := Cat(ghr >> checkDepth, true.B) // update the branch that has not been predicted + nextSpecPtr := checkPtr + 1.U + isFixUpdateCsr := true.B } } }.elsewhen(io.bpuSpecValid) { @@ -218,29 +228,38 @@ class TagePredictor( ) ) // Query - taggedPreditor.io.isGlobalHistoryUpdate := isUpdateValid - taggedPreditor.io.globalHistory := nextGhr(historyLengths(providerId + 1) - 1, 0) - taggedPreditor.io.pc := io.pc - tagUsefulbits(providerId) := taggedPreditor.io.usefulBits - tagCtrbits(providerId) := taggedPreditor.io.ctrBits - tagQueryTags(providerId) := taggedPreditor.io.queryTag - tagOriginTags(providerId) := taggedPreditor.io.originTag - tagHitIndexs(providerId) := taggedPreditor.io.hitIndex - tagIsTakens(providerId) := taggedPreditor.io.taken - tagIsHits(providerId) := taggedPreditor.io.tagHit + taggedPreditor.io.isGlobalHistoryUpdate := isUpdateValid + taggedPreditor.io.globalHistory := nextGhr(historyLengths(providerId + 1) - 1, 0) + taggedPreditor.io.pc := io.pc + tagUsefulbits(providerId) := taggedPreditor.io.usefulBits + tagCtrbits(providerId) := taggedPreditor.io.ctrBits + tagQueryTags(providerId) := taggedPreditor.io.queryTag + tagOriginTags(providerId) := taggedPreditor.io.originTag + tagHitIndexs(providerId) := taggedPreditor.io.hitIndex + tagIsTakens(providerId) := taggedPreditor.io.taken + tagIsHits(providerId) := taggedPreditor.io.tagHit + io.tageQueryMeta.tagGhtHashs(providerId) := taggedPreditor.io.queryGhtHash + io.tageQueryMeta.tagTagHashCsr1s(providerId) := taggedPreditor.io.queryTagHashCsr1 + io.tageQueryMeta.tagTagHaxhCsr2s(providerId) := taggedPreditor.io.queryTagHashCsr2 // update - taggedPreditor.io.updatePc := io.updatePc - taggedPreditor.io.updateValid := isUpdateValid && updateIsConditional - taggedPreditor.io.incUseful := tagUpdateIsIncUsefuls(providerId) - taggedPreditor.io.updateUseful := tagIsUpdateUsefuls(providerId) - taggedPreditor.io.updateUsefulBits := updateMetaBundle.tagPredictorUsefulBits(providerId) - taggedPreditor.io.updateCtr := tagIsUpdateCtrs.asBools(providerId) - taggedPreditor.io.incCtr := updateBranchTaken - taggedPreditor.io.updateCtrBits := updateMetaBundle.providerCtrBits(providerId + 1) - taggedPreditor.io.reallocEntry := tagUpdateisReallocEntrys(providerId) - taggedPreditor.io.updateTag := tagUpdateNewTags(providerId) - taggedPreditor.io.updateIndex := updateMetaBundle.tagPredictorHitIndexs(providerId) + taggedPreditor.io.updatePc := io.updatePc + taggedPreditor.io.updateValid := isUpdateValid && updateIsConditional + taggedPreditor.io.incUseful := tagUpdateIsIncUsefuls(providerId) + taggedPreditor.io.updateUseful := tagIsUpdateUsefuls(providerId) + taggedPreditor.io.updateUsefulBits := updateMetaBundle.tagPredictorUsefulBits(providerId) + taggedPreditor.io.updateCtr := tagIsUpdateCtrs.asBools(providerId) + taggedPreditor.io.incCtr := updateBranchTaken + taggedPreditor.io.updateCtrBits := updateMetaBundle.providerCtrBits(providerId + 1) + taggedPreditor.io.reallocEntry := tagUpdateisReallocEntrys(providerId) + taggedPreditor.io.updateTag := tagUpdateNewTags(providerId) + taggedPreditor.io.updateIndex := updateMetaBundle.tagPredictorHitIndexs(providerId) + taggedPreditor.io.isRecoverCsr := isRecoverCsr + taggedPreditor.io.isFixUpdateCsr := isFixUpdateCsr + taggedPreditor.io.isFixDirectionCsr := isFixDirectionCsr + taggedPreditor.io.originGhtHash := io.updateInfoPort.tageOriginMeta.tagGhtHashs(providerId) + taggedPreditor.io.originTagHashCsr1 := io.updateInfoPort.tageOriginMeta.tagTagHashCsr1s(providerId) + taggedPreditor.io.originTagHashCsr2 := io.updateInfoPort.tageOriginMeta.tagTagHaxhCsr2s(providerId) taggedPreditor } diff --git a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala index 7793a9c1..4fad7830 100644 --- a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala +++ b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala @@ -6,7 +6,8 @@ import spec._ class TageMetaPort( tagComponentNum: Int = Param.BPU.TagePredictor.tagComponentNum, - tagComponentTagWidth: Int = Param.BPU.TagePredictor.tagComponentTagWidth) + tagComponentTagWidth: Int = Param.BPU.TagePredictor.tagComponentTagWidth, + phtAddrWidth: Int = log2Ceil(Param.BPU.TagePredictor.componentTableDepth(1))) extends Bundle { val providerId = UInt(log2Ceil(tagComponentNum + 1).W) val altProviderId = UInt(log2Ceil(tagComponentNum + 1).W) @@ -17,7 +18,10 @@ class TageMetaPort( val tagPredictorHitIndexs = Vec(tagComponentNum, UInt(10.W)) val tagPredictorUsefulBits = Vec(tagComponentNum, UInt(3.W)) // global history info - val checkPtr = UInt(Param.BPU.ftqPtrWidth.W) + val checkPtr = UInt(Param.BPU.ftqPtrWidth.W) + val tagGhtHashs = Vec(tagComponentNum, UInt(phtAddrWidth.W)) + val tagTagHashCsr1s = Vec(tagComponentNum, UInt(tagComponentTagWidth.W)) + val tagTagHaxhCsr2s = Vec(tagComponentNum, UInt((tagComponentTagWidth - 1).W)) } object TageMetaPort { diff --git a/src/src/frontend/bpu/components/TaggedPreditor.scala b/src/src/frontend/bpu/components/TaggedPreditor.scala index 377bd7ed..1bd912e1 100644 --- a/src/src/frontend/bpu/components/TaggedPreditor.scala +++ b/src/src/frontend/bpu/components/TaggedPreditor.scala @@ -40,11 +40,14 @@ class TaggedPreditor( val pc = Input(UInt(spec.Width.Mem.addr)) // Meta - val usefulBits = Output(UInt(phtUsefulWidth.W)) - val ctrBits = Output(UInt(phtCtrWidth.W)) - val queryTag = Output(UInt(phtTagWidth.W)) - val originTag = Output(UInt(phtTagWidth.W)) - val hitIndex = Output(UInt(log2Ceil(phtDepth).W)) + val usefulBits = Output(UInt(phtUsefulWidth.W)) + val ctrBits = Output(UInt(phtCtrWidth.W)) + val queryTag = Output(UInt(phtTagWidth.W)) + val originTag = Output(UInt(phtTagWidth.W)) + val hitIndex = Output(UInt(log2Ceil(phtDepth).W)) + val queryGhtHash = Output(UInt(phtAddrWidth.W)) + val queryTagHashCsr1 = Output(UInt(phtTagWidth.W)) + val queryTagHashCsr2 = Output(UInt((phtTagWidth - 1).W)) // Query result val taken = Output(Bool()) @@ -63,7 +66,13 @@ class TaggedPreditor( val updateTag = Input(UInt(phtTagWidth.W)) val updateIndex = Input(UInt(log2Ceil(phtDepth).W)) - // speculative + // speculative update hash value + val isFixUpdateCsr = Input(Bool()) + val isFixDirectionCsr = Input(Bool()) + val isRecoverCsr = Input(Bool()) + val originGhtHash = Input(UInt(phtAddrWidth.W)) + val originTagHashCsr1 = Input(UInt(phtTagWidth.W)) + val originTagHashCsr2 = Input(UInt((phtTagWidth - 1).W)) }) def toPhtLine(line: UInt) = { @@ -168,25 +177,39 @@ class TaggedPreditor( // to do connect CSR hash val ghtHashCsrHash = Module(new CsrHash(ghrLength, phtAddrWidth)) - ghtHashCsrHash.io.data := io.globalHistory - ghtHashCsrHash.io.dataUpdate := io.isGlobalHistoryUpdate - hashedGhtInput := ghtHashCsrHash.io.hash + ghtHashCsrHash.io.data := io.globalHistory + ghtHashCsrHash.io.dataUpdate := io.isGlobalHistoryUpdate + hashedGhtInput := ghtHashCsrHash.io.hash + ghtHashCsrHash.io.originHash := io.originGhtHash + ghtHashCsrHash.io.isRecoverCsr := io.isRecoverCsr + ghtHashCsrHash.io.isFixUpdateCsr := io.isFixUpdateCsr + ghtHashCsrHash.io.isFixDirectionCsr := io.isFixDirectionCsr + io.queryGhtHash := ghtHashCsrHash.io.hash val pcHashCsrHash1 = Module(new CsrHash(ghrLength, phtTagWidth)) - pcHashCsrHash1.io.data := io.globalHistory - pcHashCsrHash1.io.dataUpdate := io.isGlobalHistoryUpdate - tagHashCsr1 := pcHashCsrHash1.io.hash + pcHashCsrHash1.io.data := io.globalHistory + pcHashCsrHash1.io.dataUpdate := io.isGlobalHistoryUpdate + tagHashCsr1 := pcHashCsrHash1.io.hash + pcHashCsrHash1.io.originHash := io.originTagHashCsr1 + pcHashCsrHash1.io.isRecoverCsr := io.isRecoverCsr + pcHashCsrHash1.io.isFixUpdateCsr := io.isFixUpdateCsr + pcHashCsrHash1.io.isFixDirectionCsr := io.isFixDirectionCsr + io.queryTagHashCsr1 := pcHashCsrHash1.io.hash val pcHashCsrHash2 = Module(new CsrHash(ghrLength, phtTagWidth - 1)) - pcHashCsrHash2.io.data := io.globalHistory - pcHashCsrHash2.io.dataUpdate := io.isGlobalHistoryUpdate - tagHashCsr2 := pcHashCsrHash2.io.hash + pcHashCsrHash2.io.data := io.globalHistory + pcHashCsrHash2.io.dataUpdate := io.isGlobalHistoryUpdate + tagHashCsr2 := pcHashCsrHash2.io.hash + pcHashCsrHash2.io.originHash := io.originTagHashCsr2 + pcHashCsrHash2.io.isRecoverCsr := io.isRecoverCsr + pcHashCsrHash2.io.isFixUpdateCsr := io.isFixUpdateCsr + pcHashCsrHash2.io.isFixDirectionCsr := io.isFixDirectionCsr + io.queryTagHashCsr2 := pcHashCsrHash2.io.hash val phtRam = Module( new VSimpleDualBRam( phtDepth, // size PhtEntey.width // dataWidth - ) ) phtRam.io.readAddr := queryIndex diff --git a/src/src/frontend/bpu/utils/CsrHash.scala b/src/src/frontend/bpu/utils/CsrHash.scala index 9fe806c4..af25a246 100644 --- a/src/src/frontend/bpu/utils/CsrHash.scala +++ b/src/src/frontend/bpu/utils/CsrHash.scala @@ -8,9 +8,13 @@ class CsrHash( outputLength: Int = 10) extends Module { val io = IO(new Bundle { - val dataUpdate = Input(Bool()) - val data = Input(UInt(inputLength.W)) - val hash = Output(UInt(outputLength.W)) + val dataUpdate = Input(Bool()) + val data = Input(UInt(inputLength.W)) + val hash = Output(UInt(outputLength.W)) + val isFixUpdateCsr = Input(Bool()) + val isFixDirectionCsr = Input(Bool()) + val isRecoverCsr = Input(Bool()) + val originHash = Input(UInt(outputLength.W)) }) val csr = RegInit(0.U(outputLength.W)) @@ -19,10 +23,44 @@ class CsrHash( val residual = (inputLength - 1) % outputLength // nextCSR := Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) // nextCSR(residual) := nextCSR(residual, residual) ^ io.data(inputLength - 1) + val updateCSR = WireDefault(0.U(outputLength.W)) + updateCSR := Mux( + io.isFixUpdateCsr || io.isFixDirectionCsr, + Cat(io.originHash(outputLength - 2, 0), io.originHash(outputLength - 1) ^ io.data(0)) ^ (io.data( + inputLength - 1 + ) << residual).asUInt, + Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( + inputLength - 1 + ) << residual).asUInt + ) + val keepCSR = WireDefault(0.U(outputLength.W)) + keepCSR := Mux(io.isRecoverCsr, io.originHash, csr) - nextCSR := Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( - inputLength - 1 - ) << residual).asUInt + nextCSR := Mux( + io.isRecoverCsr, + io.originHash, + Mux( + io.isFixUpdateCsr || io.isFixDirectionCsr, + Cat(io.originHash(outputLength - 2, 0), io.originHash(outputLength - 1) ^ io.data(0)) ^ (io.data( + inputLength - 1 + ) << residual).asUInt, + Mux( + io.dataUpdate, + Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( + inputLength - 1 + ) << residual).asUInt, + csr + ) + ) + ) + // commit update +// nextCSR := Mux( +// io.dataUpdate, +// Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( +// inputLength - 1 +// ) << residual).asUInt, +// csr +// ) when(io.dataUpdate) { csr := nextCSR From feccd766d4a4210a72d647c9d6d9b2847bf1cb55 Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Thu, 10 Aug 2023 00:46:58 +0800 Subject: [PATCH 04/16] feat:ghr Update info --- src/src/ComplexCoreCpuTop.scala | 2 + src/src/SimpleCoreCpuTop.scala | 2 + src/src/frontend/FetchTargetQueue.scala | 31 ++++++--- src/src/frontend/Frontend.scala | 13 ++-- src/src/frontend/bpu/BPU.scala | 43 ++++++++---- src/src/frontend/bpu/TagePredictor.scala | 66 ++++++++++--------- .../bundles/TagePredictorUpdateInfoPort.scala | 2 +- .../bpu/components/Bundles/TageMetaPort.scala | 18 +++-- src/src/frontend/bpu/utils/Bram.scala | 54 --------------- src/src/frontend/bpu/utils/Lsfr.scala | 66 ------------------- src/src/frontend/bundles/ExeFtqPort.scala | 1 + src/src/frontend/bundles/FtqBpuMetaPort.scala | 18 ++++- .../frontend/fetch/InstPreDecodeStage.scala | 2 + 13 files changed, 135 insertions(+), 183 deletions(-) delete mode 100644 src/src/frontend/bpu/utils/Bram.scala delete mode 100644 src/src/frontend/bpu/utils/Lsfr.scala diff --git a/src/src/ComplexCoreCpuTop.scala b/src/src/ComplexCoreCpuTop.scala index 77a7039c..85ed758f 100644 --- a/src/src/ComplexCoreCpuTop.scala +++ b/src/src/ComplexCoreCpuTop.scala @@ -179,6 +179,8 @@ class ComplexCoreCpuTop extends Module { case (dst, src) => dst := src } + frontend.io.commitFixBranch := false.B + frontend.io.commitFixId := 0.U // Instruction queue instQueue.io.enqueuePort <> frontend.io.instDequeuePort diff --git a/src/src/SimpleCoreCpuTop.scala b/src/src/SimpleCoreCpuTop.scala index a1d92a52..7b7b10ac 100644 --- a/src/src/SimpleCoreCpuTop.scala +++ b/src/src/SimpleCoreCpuTop.scala @@ -191,6 +191,8 @@ class SimpleCoreCpuTop extends Module { frontend.io.exeFtqPort.queryPcBundle <> issueQueue.io.queryPcPort frontend.io.exeFtqPort.commitBundle := mainExeStage.io.peer.get.feedbackFtq frontend.io.commitFtqTrainPort := addrTransStage.io.peer.get.commitFtqPort + frontend.io.commitFixBranch := false.B + frontend.io.commitFixId := 0.U connectVec(frontend.io.commitBitMask, cu.io.commitBitMask) // Instruction queue diff --git a/src/src/frontend/FetchTargetQueue.scala b/src/src/frontend/FetchTargetQueue.scala index 0b840ef1..a2b3ceea 100644 --- a/src/src/frontend/FetchTargetQueue.scala +++ b/src/src/frontend/FetchTargetQueue.scala @@ -17,10 +17,11 @@ class FetchTargetQueue( val io = IO(new Bundle { // <-> Frontend flush control - val backendFlush = Input(Bool()) - val backendFlushFtqId = Input(UInt(ptrWidth.W)) - val instFetchFlush = Input(Bool()) - val instFetchFtqId = Input(UInt(ptrWidth.W)) + val backendFlush = Input(Bool()) + val backendFlushFtqId = Input(UInt(ptrWidth.W)) + val preDecoderFlush = Input(Bool()) + val preDecoderFtqId = Input(UInt(ptrWidth.W)) + val preDecoderBranchTaken = Input(Bool()) // <-> BPU val bpuFtqPort = new BpuFtqPort @@ -29,6 +30,8 @@ class FetchTargetQueue( // <-> Cu commit val commitFtqTrainPort = Input(new CommitFtqTrainNdPort) val commitBitMask = Input(Vec(Param.commitNum, Bool())) + val commitFixBranch = Input(Bool()) + val commitFixId = Input(UInt(ptrWidth.W)) // <-> Ex query port val exeFtqPort = new ExeFtqPort @@ -116,9 +119,9 @@ class FetchTargetQueue( } // if IF predecoder found a redirect - when(io.instFetchFlush) { - nextIfPtr := io.instFetchFtqId + 1.U - bpuPtr := io.instFetchFtqId + 1.U + when(io.preDecoderFlush) { + nextIfPtr := io.preDecoderFtqId + 1.U + bpuPtr := io.preDecoderFtqId + 1.U } // if backend redirect triggered,back to the next block of the redirect block // backend may continue to commit older block (flush before exeStage inst;commit after exeStage inst) @@ -187,7 +190,19 @@ class FetchTargetQueue( io.bpuFtqPort.ftqFull := queueFull // training meta to BPU - io.bpuFtqPort.ftqBpuTrainMeta := FtqBpuMetaPort.default + io.bpuFtqPort.ftqBpuTrainMeta := FtqBpuMetaPort.default + io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.exeFixBundle := io.exeFtqPort.fixGhrBundle + io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.isPredecoderFixGhr := io.preDecoderFlush + io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.isPredecoderBranchTaken := io.preDecoderBranchTaken + io.bpuFtqPort.ftqBpuTrainMeta.tageGhrInfo := Mux( + io.commitFixBranch, + ftqBpuMetaRegs(io.commitFixId).tageQueryMeta.tageGhrInfo, + Mux( + io.exeFtqPort.fixGhrBundle.isExeFixErrorGhr, + ftqBpuMetaRegs(io.backendFlushFtqId).tageQueryMeta.tageGhrInfo, + ftqBpuMetaRegs(io.preDecoderFtqId).tageQueryMeta.tageGhrInfo + ) + ) // when( // io.cuCommitFtqPort.blockBitmask(0) & io.cuCommitFtqPort.meta.isBranch // ) { diff --git a/src/src/frontend/Frontend.scala b/src/src/frontend/Frontend.scala index d28b5bfb..3f0044d4 100644 --- a/src/src/frontend/Frontend.scala +++ b/src/src/frontend/Frontend.scala @@ -23,6 +23,8 @@ class Frontend extends Module { // ftq <-> cu val commitFtqTrainPort = Input(new CommitFtqTrainNdPort) val commitBitMask = Input(Vec(Param.commitNum, Bool())) + val commitFixBranch = Input(Bool()) + val commitFixId = Input(UInt(Param.BPU.ftqPtrWidth.W)) // instFetch <-> ICache val accessPort = Flipped(new ICacheAccessPort) @@ -66,10 +68,13 @@ class Frontend extends Module { // fetch Target Pc queue; // stage 1 // act as a fetch buffer - ftq.io.backendFlush := io.isFlush - ftq.io.backendFlushFtqId := io.ftqFlushId - ftq.io.instFetchFlush := instFetch.io.preDecodeRedirectPort.predecodeRedirect // TODO add predecoder stage - ftq.io.instFetchFtqId := instFetch.io.preDecodeRedirectPort.redirectFtqId + ftq.io.backendFlush := io.isFlush + ftq.io.backendFlushFtqId := io.ftqFlushId + ftq.io.preDecoderFlush := instFetch.io.preDecodeRedirectPort.predecodeRedirect // TODO add predecoder stage + ftq.io.preDecoderFtqId := instFetch.io.preDecodeRedirectPort.redirectFtqId + ftq.io.preDecoderBranchTaken := instFetch.io.preDecodeRedirectPort.predecoderBranch + ftq.io.commitFixId := io.commitFixId + ftq.io.commitFixBranch := io.commitFixBranch instFetch.io.preDecodeRedirectPort.commitRasPort := ftq.io.ftqRasPort ftq.io.commitFtqTrainPort := io.commitFtqTrainPort ftq.io.exeFtqPort <> io.exeFtqPort diff --git a/src/src/frontend/bpu/BPU.scala b/src/src/frontend/bpu/BPU.scala index 7b3567be..f5e081ac 100644 --- a/src/src/frontend/bpu/BPU.scala +++ b/src/src/frontend/bpu/BPU.scala @@ -5,8 +5,8 @@ import chisel3.util._ import frontend.bpu.bundles._ import frontend.bpu.components.Bundles.{FtbEntryNdPort, TageMetaPort} import frontend.bpu.components.FTB -import frontend.bundles.{BpuFtqPort, FtqBlockBundle} -import spec.Param.BPU.BranchType +import frontend.bundles.{BpuFtqPort, FtqBlockBundle, GhrUpdateSignalBundle} +import spec.Param.BPU.{BranchType, GhrFixType} import spec._ // BPU is the Branch Predicting Unit @@ -144,7 +144,8 @@ class BPU( io.bpuRedirectPc.bits := ftbEntry.jumpTargetAddr } is(Param.BPU.BranchType.ret) { - // return inst is predict in pre decode Stage + // return inst is predict in preDecode Stage; + // when preDecode predict error,use ftb to predict } } @@ -200,6 +201,23 @@ class BPU( ftbUpdateEntry.jumpTargetAddr := io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.jumpTargetAddr ftbUpdateEntry.fallThroughAddr := io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.fallThroughAddr + // global branch history update logic + val ghrFixBundle = Wire(new GhrFixNdBundle) + val ghrUpdateSignalBundle = WireDefault( + io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle + ) + ghrFixBundle.isFixGhrValid := ghrUpdateSignalBundle.isPredecoderFixGhr || ghrUpdateSignalBundle.isCommitFixGhr || ghrUpdateSignalBundle.exeFixBundle.isExeFixErrorGhr + ghrFixBundle.isFixBranchTaken := ghrUpdateSignalBundle.exeFixBundle.exeFixIsTaken + ghrFixBundle.ghrFixType := Mux( + ghrUpdateSignalBundle.isCommitFixGhr, + GhrFixType.commitBrExcp, + Mux( + ghrUpdateSignalBundle.exeFixBundle.isExeFixErrorGhr, + Mux(ghrUpdateSignalBundle.exeFixBundle.isExeUpdateGhr, GhrFixType.exeUpdateJump, GhrFixType.exeFixDirection), + Mux(ghrUpdateSignalBundle.isPredecoderBranchTaken, GhrFixType.decodeUpdateJump, GhrFixType.decodeBrExcp) + ) + ) + // connect fetch target buffer module // assign ftbHit = 0 val ftbModule = Module(new FTB) @@ -220,15 +238,16 @@ class BPU( // connect tage Predictor module val tagePredictorModule = Module(new TagePredictor) - tagePredictorModule.io.pc := io.pc - tageQueryMeta := tagePredictorModule.io.tageQueryMeta - predictTaken := tagePredictorModule.io.predictBranchTaken - predictValid := tagePredictorModule.io.predictValid - tagePredictorModule.io.updatePc := io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.startPc - tagePredictorModule.io.updateInfoPort := tageUpdateInfo - tagePredictorModule.io.bpuSpecTaken := false.B - tagePredictorModule.io.bpuSpecValid := false.B - tagePredictorModule.io.ghrUpdateNdBundle := GhrUpdateNdBundle.default + tagePredictorModule.io.pc := io.pc + tageQueryMeta := tagePredictorModule.io.tageQueryMeta + predictTaken := tagePredictorModule.io.predictBranchTaken + predictValid := tagePredictorModule.io.predictValid + tagePredictorModule.io.updatePc := io.bpuFtqPort.ftqBpuTrainMeta.branchAddrBundle.startPc + tagePredictorModule.io.updateInfoPort := tageUpdateInfo + tagePredictorModule.io.ghrUpdateNdBundle.bpuSpecTaken := io.bpuFtqPort.ftqP1.predictTaken // bpu predict info + tagePredictorModule.io.ghrUpdateNdBundle.bpuSpecValid := mainRedirectValid + tagePredictorModule.io.ghrUpdateNdBundle.fixBundle := ghrFixBundle + tagePredictorModule.io.ghrUpdateNdBundle.tageGhrInfo := io.bpuFtqPort.ftqBpuTrainMeta.tageGhrInfo // tagePredictorModule.io.perfTagHitCounters <> DontCare } diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 025d9434..09ba56e1 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -4,13 +4,17 @@ import chisel3._ import chisel3.util._ import chisel3.util.random.LFSR import frontend.bpu.bundles.{BpuFtqMetaNdPort, TagePredictorUpdateInfoPort} -import frontend.bpu.components.Bundles.TageMetaPort +import frontend.bpu.components.Bundles.{TageGhrInfo, TageMetaPort} import frontend.bpu.components._ import spec.Param.BPU.GhrFixType import spec._ class GhrUpdateNdBundle extends Bundle { - val bpuSpecValid = Bool() // speculative update - val bpuSpecTaken = Bool() + val bpuSpecValid = Bool() // speculative update + val bpuSpecTaken = Bool() + val fixBundle = new GhrFixNdBundle + val tageGhrInfo = new TageGhrInfo() +} +class GhrFixNdBundle extends Bundle { val isFixGhrValid = Bool() val ghrFixType = UInt(Param.BPU.GhrFixType.width.W) val isFixBranchTaken = Bool() @@ -46,10 +50,8 @@ class TagePredictor( val updatePc = Input(UInt(Width.Reg.data)) val updateInfoPort = Input(new TagePredictorUpdateInfoPort) - // BPU predict info + // globalHistory update info val ghrUpdateNdBundle = Input(new GhrUpdateNdBundle) - val bpuSpecValid = Input(Bool()) // speculative update - val bpuSpecTaken = Input(Bool()) // TODO PMU // val perfTagHitCounters = Output(Vec(32, UInt((tagComponentNum + 1).W))) @@ -173,16 +175,16 @@ class TagePredictor( when(isUpdateValid) { commitPtr := commitPtr + 1.U } - when(io.ghrUpdateNdBundle.isFixGhrValid) { - switch(io.ghrUpdateNdBundle.ghrFixType) { + when(io.ghrUpdateNdBundle.fixBundle.isFixGhrValid) { + switch(io.ghrUpdateNdBundle.fixBundle.ghrFixType) { is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { nextGhr := ghr >> checkDepth // recover to the old history nextSpecPtr := checkPtr - 1.U isRecoverCsr := true.B } is(GhrFixType.exeFixDirection) { - nextGhr := Cat(ghr >> checkDepth, io.ghrUpdateNdBundle.isFixBranchTaken) // fix error predict - nextSpecPtr := checkPtr + nextGhr := Cat(ghr >> checkDepth, io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken) // fix error predict + nextSpecPtr := checkPtr isFixDirectionCsr := true.B } is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { @@ -191,16 +193,16 @@ class TagePredictor( isFixUpdateCsr := true.B } } - }.elsewhen(io.bpuSpecValid) { - nextGhr := Cat(ghr(ghrDepth - 2, 0), io.bpuSpecTaken) + }.elsewhen(io.ghrUpdateNdBundle.bpuSpecValid) { + nextGhr := Cat(ghr(ghrDepth - 2, 0), io.ghrUpdateNdBundle.bpuSpecTaken) nextSpecPtr := specPtr + 1.U } - when(isUpdateValid) { - nextGhr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) - } +// when(isUpdateValid) { +// nextGhr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) +// } // output - io.tageQueryMeta.checkPtr := nextSpecPtr + io.tageQueryMeta.tageGhrInfo.checkPtr := nextSpecPtr //////////////////////////////////////////////////////////////////////////////////////////// // Query Logic @@ -228,19 +230,19 @@ class TagePredictor( ) ) // Query - taggedPreditor.io.isGlobalHistoryUpdate := isUpdateValid - taggedPreditor.io.globalHistory := nextGhr(historyLengths(providerId + 1) - 1, 0) - taggedPreditor.io.pc := io.pc - tagUsefulbits(providerId) := taggedPreditor.io.usefulBits - tagCtrbits(providerId) := taggedPreditor.io.ctrBits - tagQueryTags(providerId) := taggedPreditor.io.queryTag - tagOriginTags(providerId) := taggedPreditor.io.originTag - tagHitIndexs(providerId) := taggedPreditor.io.hitIndex - tagIsTakens(providerId) := taggedPreditor.io.taken - tagIsHits(providerId) := taggedPreditor.io.tagHit - io.tageQueryMeta.tagGhtHashs(providerId) := taggedPreditor.io.queryGhtHash - io.tageQueryMeta.tagTagHashCsr1s(providerId) := taggedPreditor.io.queryTagHashCsr1 - io.tageQueryMeta.tagTagHaxhCsr2s(providerId) := taggedPreditor.io.queryTagHashCsr2 + taggedPreditor.io.isGlobalHistoryUpdate := io.ghrUpdateNdBundle.bpuSpecValid + taggedPreditor.io.globalHistory := nextGhr(historyLengths(providerId + 1) - 1, 0) + taggedPreditor.io.pc := io.pc + tagUsefulbits(providerId) := taggedPreditor.io.usefulBits + tagCtrbits(providerId) := taggedPreditor.io.ctrBits + tagQueryTags(providerId) := taggedPreditor.io.queryTag + tagOriginTags(providerId) := taggedPreditor.io.originTag + tagHitIndexs(providerId) := taggedPreditor.io.hitIndex + tagIsTakens(providerId) := taggedPreditor.io.taken + tagIsHits(providerId) := taggedPreditor.io.tagHit + io.tageQueryMeta.tageGhrInfo.tagGhtHashs(providerId) := taggedPreditor.io.queryGhtHash + io.tageQueryMeta.tageGhrInfo.tagTagHashCsr1s(providerId) := taggedPreditor.io.queryTagHashCsr1 + io.tageQueryMeta.tageGhrInfo.tagTagHashCsr2s(providerId) := taggedPreditor.io.queryTagHashCsr2 // update taggedPreditor.io.updatePc := io.updatePc @@ -257,9 +259,9 @@ class TagePredictor( taggedPreditor.io.isRecoverCsr := isRecoverCsr taggedPreditor.io.isFixUpdateCsr := isFixUpdateCsr taggedPreditor.io.isFixDirectionCsr := isFixDirectionCsr - taggedPreditor.io.originGhtHash := io.updateInfoPort.tageOriginMeta.tagGhtHashs(providerId) - taggedPreditor.io.originTagHashCsr1 := io.updateInfoPort.tageOriginMeta.tagTagHashCsr1s(providerId) - taggedPreditor.io.originTagHashCsr2 := io.updateInfoPort.tageOriginMeta.tagTagHaxhCsr2s(providerId) + taggedPreditor.io.originGhtHash := io.updateInfoPort.tageOriginMeta.tageGhrInfo.tagGhtHashs(providerId) + taggedPreditor.io.originTagHashCsr1 := io.updateInfoPort.tageOriginMeta.tageGhrInfo.tagTagHashCsr1s(providerId) + taggedPreditor.io.originTagHashCsr2 := io.updateInfoPort.tageOriginMeta.tageGhrInfo.tagTagHashCsr2s(providerId) taggedPreditor } diff --git a/src/src/frontend/bpu/bundles/TagePredictorUpdateInfoPort.scala b/src/src/frontend/bpu/bundles/TagePredictorUpdateInfoPort.scala index 521ebae2..6b739ba8 100644 --- a/src/src/frontend/bpu/bundles/TagePredictorUpdateInfoPort.scala +++ b/src/src/frontend/bpu/bundles/TagePredictorUpdateInfoPort.scala @@ -1,6 +1,6 @@ package frontend.bpu.bundles import chisel3._ -import frontend.bpu.components.Bundles.TageMetaPort +import frontend.bpu.components.Bundles.{TageGhrInfo, TageMetaPort} class TagePredictorUpdateInfoPort extends Bundle { val valid = Bool() diff --git a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala index 4fad7830..fc17a326 100644 --- a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala +++ b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala @@ -4,6 +4,17 @@ import chisel3._ import chisel3.util._ import spec._ +class TageGhrInfo( + tagComponentNum: Int = Param.BPU.TagePredictor.tagComponentNum, + tagComponentTagWidth: Int = Param.BPU.TagePredictor.tagComponentTagWidth, + phtAddrWidth: Int = log2Ceil(Param.BPU.TagePredictor.componentTableDepth(1))) + extends Bundle { + val checkPtr = UInt(Param.BPU.ftqPtrWidth.W) + val tagGhtHashs = Vec(tagComponentNum, UInt(phtAddrWidth.W)) + val tagTagHashCsr1s = Vec(tagComponentNum, UInt(tagComponentTagWidth.W)) + val tagTagHashCsr2s = Vec(tagComponentNum, UInt((tagComponentTagWidth - 1).W)) +} + class TageMetaPort( tagComponentNum: Int = Param.BPU.TagePredictor.tagComponentNum, tagComponentTagWidth: Int = Param.BPU.TagePredictor.tagComponentTagWidth, @@ -17,11 +28,8 @@ class TageMetaPort( val tagPredictorOriginTags = Vec(tagComponentNum, UInt(tagComponentTagWidth.W)) val tagPredictorHitIndexs = Vec(tagComponentNum, UInt(10.W)) val tagPredictorUsefulBits = Vec(tagComponentNum, UInt(3.W)) - // global history info - val checkPtr = UInt(Param.BPU.ftqPtrWidth.W) - val tagGhtHashs = Vec(tagComponentNum, UInt(phtAddrWidth.W)) - val tagTagHashCsr1s = Vec(tagComponentNum, UInt(tagComponentTagWidth.W)) - val tagTagHaxhCsr2s = Vec(tagComponentNum, UInt((tagComponentTagWidth - 1).W)) + // global history Hash info + val tageGhrInfo = new TageGhrInfo() } object TageMetaPort { diff --git a/src/src/frontend/bpu/utils/Bram.scala b/src/src/frontend/bpu/utils/Bram.scala deleted file mode 100644 index ff4c4f83..00000000 --- a/src/src/frontend/bpu/utils/Bram.scala +++ /dev/null @@ -1,54 +0,0 @@ -package frontend.bpu.utils -import chisel3._ -// simulate BRAM IP in simulation without Vivado -// data read latency is 1 cycle -class Bram( - dataWidth: Int = 128, - dataDepthExp2: Int = 8) - extends Module { - // parameter - val addrWidth = dataDepthExp2 - val dataDepth = 1 << dataDepthExp2 - val io = IO(new Bundle { - val ena = Input(Bool()) // Chip enable A - val enb = Input(Bool()) // Chip enable B - val wea = Input(Bool()) // Write enable A - val web = Input(Bool()) // Write enable B - - val dina = Input(UInt(dataWidth.W)) - val addra = Input(UInt(addrWidth.W)) - val douta = Output(UInt(dataWidth.W)) - - val dinb = Input(UInt(dataWidth.W)) - val addrb = Input(UInt(addrWidth.W)) - val doutb = Output(UInt(dataWidth.W)) - - }) - val datas = RegInit(VecInit(Seq.fill(dataWidth)(0.U(dataDepth.W)))) - - // Read logic - when(io.ena & io.wea) { - io.douta := RegNext(io.dina, 0.U) - }.elsewhen(io.ena) { - io.douta := RegNext(datas(io.addra), 0.U) - }.otherwise { - io.douta := RegNext(0.U(dataDepth.W), 0.U) - } - - when(io.enb & io.web) { - io.doutb := RegNext(io.dinb, 0.U) - }.elsewhen(io.enb) { - io.doutb := RegNext(datas(io.addrb), 0.U) - }.otherwise { - io.doutb := RegNext(0.U(dataDepth.W), 0.U) - } - - // Write logic - when(io.enb & io.web) { - datas(io.addrb) := RegNext(io.dinb, 0.U) - } - - when(io.ena & io.wea) { - datas(io.addra) := RegNext(io.dinb, 0.U) - } -} diff --git a/src/src/frontend/bpu/utils/Lsfr.scala b/src/src/frontend/bpu/utils/Lsfr.scala deleted file mode 100644 index a551bfc9..00000000 --- a/src/src/frontend/bpu/utils/Lsfr.scala +++ /dev/null @@ -1,66 +0,0 @@ -package frontend.bpu.utils - -import chisel3._ -import chisel3.util._ - -//translate lfsr system verilog code from https://github.com/openhwgroup/cva5/blob/master/core/lfsr.sv -//3-16 bit LFSRs with additional feedback to support full 2^N range -// Linear-feedback shift register -//lfsr is used to generate random number -class Lfsr( - width: Int = 3, - NeedsReset: Int = 1) - extends Module { - // XNOR taps for LFSR from 3-16 bits wide (source: Xilinx xapp052) - val tapNums = Seq(1, 1, 1, // Dummy entries for widths 0-2 - 2, 2, 2, 2, 2, // Number of taps and indicies[3:0] for LFSRs width 3 to 16 - 4, 2, 2, 2, // 8 - 4, 4, 4, 2, 4) - val tapIndiciess = Seq( - Seq(0, 0, 0, 0), - Seq(0, 0, 0, 0), - Seq(0, 0, 0, 0), - Seq(0, 0, 1, 2), - Seq(0, 0, 2, 3), - Seq(0, 0, 2, 4), - Seq(0, 0, 4, 5), - Seq(0, 0, 5, 6), - Seq(3, 4, 5, 7), - Seq(0, 0, 4, 8), - Seq(0, 0, 8, 10), - Seq(0, 3, 5, 11), - Seq(0, 2, 3, 12), - Seq(0, 2, 4, 13), - Seq(0, 0, 13, 14), - Seq(3, 12, 14, 15) - ) - - val io = IO(new Bundle { - val en = Input(Bool()) - val value = Output(UInt(width.W)) - }) - - val num = tapNums(width) - val indicies = tapIndiciess(width) - - val feedbackInput = WireDefault(0.U(num.W)) - val feedback = WireDefault(false.B) - val value = RegInit(0.U(width.W)) - //////////////////////////////////////////////////// - // Implementation - if (width == 2) { - feedback := ~value(width - 1) - } else { - for (i <- 0 to num) { - feedbackInput(i) := value(indicies(i)) - } - // XNOR of taps and range extension to include all ones - feedback := (!(feedbackInput.xorR)) ^ (value(width - 2, 0).orR) - } - - when(io.en) { - value := RegNext(Cat(value(width - 2, 0), feedback), 0.U) - } - io.value := value - -} diff --git a/src/src/frontend/bundles/ExeFtqPort.scala b/src/src/frontend/bundles/ExeFtqPort.scala index 616c2acd..98b14862 100644 --- a/src/src/frontend/bundles/ExeFtqPort.scala +++ b/src/src/frontend/bundles/ExeFtqPort.scala @@ -4,6 +4,7 @@ import spec.Param class ExeFtqPort extends Bundle { val queryPcBundle = new QueryPcBundle val commitBundle = Input(new ExeCommitFtqNdPort) + val fixGhrBundle = Input(new ExeFtqFixGhrBundle) } class QueryPcBundle extends Bundle { diff --git a/src/src/frontend/bundles/FtqBpuMetaPort.scala b/src/src/frontend/bundles/FtqBpuMetaPort.scala index 849a7d75..d057de60 100644 --- a/src/src/frontend/bundles/FtqBpuMetaPort.scala +++ b/src/src/frontend/bundles/FtqBpuMetaPort.scala @@ -1,7 +1,7 @@ package frontend.bundles import chisel3._ import chisel3.util._ -import frontend.bpu.components.Bundles.TageMetaPort +import frontend.bpu.components.Bundles.{TageGhrInfo, TageMetaPort} import spec._ class BranchAddrBundle extends Bundle { @@ -9,6 +9,18 @@ class BranchAddrBundle extends Bundle { val jumpTargetAddr = UInt(spec.Width.Mem.addr) val fallThroughAddr = UInt(spec.Width.Mem.addr) } + +class ExeFtqFixGhrBundle extends Bundle { + val isExeFixErrorGhr = Bool() + val isExeUpdateGhr = Bool() + val exeFixIsTaken = Bool() +} +class GhrUpdateSignalBundle extends Bundle { + val isCommitFixGhr = Bool() + val exeFixBundle = new ExeFtqFixGhrBundle + val isPredecoderFixGhr = Bool() + val isPredecoderBranchTaken = Bool() +} class FtqBpuMetaPort( ftbNway: Int = Param.BPU.FTB.nway, addr: Int = wordLength) @@ -26,6 +38,10 @@ class FtqBpuMetaPort( // FTB train meta val branchAddrBundle = new BranchAddrBundle + + // train meta + val ghrUpdateSignalBundle = new GhrUpdateSignalBundle // global history register + val tageGhrInfo = new TageGhrInfo() } object FtqBpuMetaPort { diff --git a/src/src/frontend/fetch/InstPreDecodeStage.scala b/src/src/frontend/fetch/InstPreDecodeStage.scala index c09c1490..f4c79212 100644 --- a/src/src/frontend/fetch/InstPreDecodeStage.scala +++ b/src/src/frontend/fetch/InstPreDecodeStage.scala @@ -31,6 +31,7 @@ class ftqPreDecodeFixRasNdPort extends Bundle { } class InstPreDecodePeerPort extends Bundle { val predecodeRedirect = Output(Bool()) + val predecoderBranch = Output(Bool()) val redirectFtqId = Output(UInt(Param.BPU.ftqPtrWidth.W)) val redirectPc = Output(UInt(spec.Width.Mem.addr)) val commitRasPort = Input(Valid(new ftqPreDecodeFixRasNdPort)) @@ -108,6 +109,7 @@ class InstPreDecodeStage val isPredecoderRedirect = WireDefault(false.B) isPredecoderRedirect := isDataValid && ((isJump && canJump) || isErrorPredict) val isPredecoderRedirectReg = RegNext(isPredecoderRedirect, false.B) + peer.predecoderBranch := RegNext(isDataValid && (isJump && canJump), false.B) // connect return address stack module val rasModule = Module(new RAS) From de4fd67dc5139fdf306d3c01c893585ab456cf8d Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Thu, 10 Aug 2023 03:22:50 +0800 Subject: [PATCH 05/16] feat:implement speculative Global history update --- src/src/SimpleCoreCpuTop.scala | 2 +- src/src/frontend/FetchTargetQueue.scala | 15 +++++----- src/src/frontend/bpu/BPU.scala | 6 ++-- src/src/frontend/bpu/TagePredictor.scala | 1 + src/src/frontend/bundles/ExeFtqPort.scala | 7 +++-- src/src/frontend/bundles/FtqBpuMetaPort.scala | 6 ++-- .../frontend/fetch/InstPreDecodeStage.scala | 12 ++++++-- src/src/frontend/fetch/InstResStage.scala | 10 ++++--- .../common/bundles/FtqInfoBundle.scala | 3 +- .../complex/execution/ExePassWbStage.scala | 27 +++++++++-------- src/src/pipeline/simple/MainExeStage.scala | 29 ++++++++++--------- 11 files changed, 69 insertions(+), 49 deletions(-) diff --git a/src/src/SimpleCoreCpuTop.scala b/src/src/SimpleCoreCpuTop.scala index 7b7b10ac..742922d5 100644 --- a/src/src/SimpleCoreCpuTop.scala +++ b/src/src/SimpleCoreCpuTop.scala @@ -189,7 +189,7 @@ class SimpleCoreCpuTop extends Module { // TODO: Connect frontend frontend.io.exeFtqPort.queryPcBundle <> issueQueue.io.queryPcPort - frontend.io.exeFtqPort.commitBundle := mainExeStage.io.peer.get.feedbackFtq + frontend.io.exeFtqPort.feedBack := mainExeStage.io.peer.get.feedbackFtq frontend.io.commitFtqTrainPort := addrTransStage.io.peer.get.commitFtqPort frontend.io.commitFixBranch := false.B frontend.io.commitFixId := 0.U diff --git a/src/src/frontend/FetchTargetQueue.scala b/src/src/frontend/FetchTargetQueue.scala index a2b3ceea..7bd886a5 100644 --- a/src/src/frontend/FetchTargetQueue.scala +++ b/src/src/frontend/FetchTargetQueue.scala @@ -191,14 +191,14 @@ class FetchTargetQueue( // training meta to BPU io.bpuFtqPort.ftqBpuTrainMeta := FtqBpuMetaPort.default - io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.exeFixBundle := io.exeFtqPort.fixGhrBundle + io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.exeFixBundle := io.exeFtqPort.feedBack.fixGhrBundle io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.isPredecoderFixGhr := io.preDecoderFlush io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.isPredecoderBranchTaken := io.preDecoderBranchTaken io.bpuFtqPort.ftqBpuTrainMeta.tageGhrInfo := Mux( io.commitFixBranch, ftqBpuMetaRegs(io.commitFixId).tageQueryMeta.tageGhrInfo, Mux( - io.exeFtqPort.fixGhrBundle.isExeFixErrorGhr, + io.exeFtqPort.feedBack.fixGhrBundle.isExeFixValid, ftqBpuMetaRegs(io.backendFlushFtqId).tageQueryMeta.tageGhrInfo, ftqBpuMetaRegs(io.preDecoderFtqId).tageQueryMeta.tageGhrInfo ) @@ -246,6 +246,7 @@ class FetchTargetQueue( io.bpuFtqPort.bpuQueryMeta, BpuFtqMetaNdPort.default ) + bpuMetaWriteEntry.tageQueryMeta.tageGhrInfo := io.bpuFtqPort.bpuQueryMeta.tageQueryMeta.tageGhrInfo // when(io.bpuFtqPort.ftqP1.isValid & ~mainBpuRedirectDelay) { // bpuMetaWriteValid := true.B // bpuMetaWritePtr := bpuPtr - 1.U @@ -275,15 +276,15 @@ class FetchTargetQueue( ftqBpuMetaRegs(bpuMetaWritePtr) := bpuMetaWriteEntry } // update pc from backend - when(io.exeFtqPort.commitBundle.ftqMetaUpdateValid) { - val ftqUpdateMetaId = WireDefault(io.exeFtqPort.commitBundle.ftqUpdateMetaId) + when(io.exeFtqPort.feedBack.commitBundle.ftqMetaUpdateValid) { + val ftqUpdateMetaId = WireDefault(io.exeFtqPort.feedBack.commitBundle.ftqUpdateMetaId) ftqBranchMetaRegs( ftqUpdateMetaId - ).jumpTargetAddr := io.exeFtqPort.commitBundle.ftqMetaUpdateJumpTarget + ).jumpTargetAddr := io.exeFtqPort.feedBack.commitBundle.ftqMetaUpdateJumpTarget ftqBranchMetaRegs( ftqUpdateMetaId - ).fallThroughAddr := io.exeFtqPort.commitBundle.ftqMetaUpdateFallThrough - ftqBranchMetaRegs(ftqUpdateMetaId).ftbDirty := io.exeFtqPort.commitBundle.ftqMetaUpdateFtbDirty + ).fallThroughAddr := io.exeFtqPort.feedBack.commitBundle.ftqMetaUpdateFallThrough + ftqBranchMetaRegs(ftqUpdateMetaId).ftbDirty := io.exeFtqPort.feedBack.commitBundle.ftqMetaUpdateFtbDirty } } diff --git a/src/src/frontend/bpu/BPU.scala b/src/src/frontend/bpu/BPU.scala index f5e081ac..247fe748 100644 --- a/src/src/frontend/bpu/BPU.scala +++ b/src/src/frontend/bpu/BPU.scala @@ -206,14 +206,14 @@ class BPU( val ghrUpdateSignalBundle = WireDefault( io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle ) - ghrFixBundle.isFixGhrValid := ghrUpdateSignalBundle.isPredecoderFixGhr || ghrUpdateSignalBundle.isCommitFixGhr || ghrUpdateSignalBundle.exeFixBundle.isExeFixErrorGhr + ghrFixBundle.isFixGhrValid := ghrUpdateSignalBundle.isPredecoderFixGhr || ghrUpdateSignalBundle.isCommitFixGhr || ghrUpdateSignalBundle.exeFixBundle.isExeFixValid ghrFixBundle.isFixBranchTaken := ghrUpdateSignalBundle.exeFixBundle.exeFixIsTaken ghrFixBundle.ghrFixType := Mux( ghrUpdateSignalBundle.isCommitFixGhr, GhrFixType.commitBrExcp, Mux( - ghrUpdateSignalBundle.exeFixBundle.isExeFixErrorGhr, - Mux(ghrUpdateSignalBundle.exeFixBundle.isExeUpdateGhr, GhrFixType.exeUpdateJump, GhrFixType.exeFixDirection), + ghrUpdateSignalBundle.exeFixBundle.isExeFixValid, + Mux(ghrUpdateSignalBundle.exeFixBundle.exeFixFirstBrTaken, GhrFixType.exeUpdateJump, GhrFixType.exeFixDirection), Mux(ghrUpdateSignalBundle.isPredecoderBranchTaken, GhrFixType.decodeUpdateJump, GhrFixType.decodeBrExcp) ) ) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 09ba56e1..4106dc2d 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -140,6 +140,7 @@ class TagePredictor( val commitPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) val checkPtr = WireDefault(0.U(Param.BPU.ftqPtrWidth.W)) val checkDepth = Wire(UInt(Param.BPU.ftqPtrWidth.W)) + checkPtr := io.ghrUpdateNdBundle.tageGhrInfo.checkPtr checkDepth := checkPtr - commitPtr // calculate the location of the correct old history // Global History Register diff --git a/src/src/frontend/bundles/ExeFtqPort.scala b/src/src/frontend/bundles/ExeFtqPort.scala index 98b14862..e52d0e85 100644 --- a/src/src/frontend/bundles/ExeFtqPort.scala +++ b/src/src/frontend/bundles/ExeFtqPort.scala @@ -3,8 +3,7 @@ import chisel3._ import spec.Param class ExeFtqPort extends Bundle { val queryPcBundle = new QueryPcBundle - val commitBundle = Input(new ExeCommitFtqNdPort) - val fixGhrBundle = Input(new ExeFtqFixGhrBundle) + val feedBack = Input(new ExeFtqFeedBackNdPort) } class QueryPcBundle extends Bundle { @@ -19,3 +18,7 @@ class ExeCommitFtqNdPort extends Bundle { val ftqMetaUpdateFallThrough = UInt(spec.Width.Mem.addr) val ftqUpdateMetaId = UInt(Param.BPU.Width.id) } +class ExeFtqFeedBackNdPort extends Bundle { + val commitBundle = new ExeCommitFtqNdPort + val fixGhrBundle = new ExeFtqFixGhrBundle +} diff --git a/src/src/frontend/bundles/FtqBpuMetaPort.scala b/src/src/frontend/bundles/FtqBpuMetaPort.scala index d057de60..9ad3ccaa 100644 --- a/src/src/frontend/bundles/FtqBpuMetaPort.scala +++ b/src/src/frontend/bundles/FtqBpuMetaPort.scala @@ -11,9 +11,9 @@ class BranchAddrBundle extends Bundle { } class ExeFtqFixGhrBundle extends Bundle { - val isExeFixErrorGhr = Bool() - val isExeUpdateGhr = Bool() - val exeFixIsTaken = Bool() + val isExeFixValid = Bool() + val exeFixFirstBrTaken = Bool() + val exeFixIsTaken = Bool() } class GhrUpdateSignalBundle extends Bundle { val isCommitFixGhr = Bool() diff --git a/src/src/frontend/fetch/InstPreDecodeStage.scala b/src/src/frontend/fetch/InstPreDecodeStage.scala index f4c79212..7d5ed4eb 100644 --- a/src/src/frontend/fetch/InstPreDecodeStage.scala +++ b/src/src/frontend/fetch/InstPreDecodeStage.scala @@ -168,14 +168,20 @@ class InstPreDecodeStage } when((index + 1).U === selectBlockLength) { infoBundle.bits.ftqInfo.predictBranch := selectedIn - .enqInfos(selectBlockLength - 1.U) + .enqInfos(index) .bits .ftqInfo .predictBranch || isPredecoderRedirect + infoBundle.bits.ftqInfo.isPredictValid := selectedIn + .enqInfos(index) + .bits + .ftqInfo + .isPredictValid || isPredecoderRedirect infoBundle.bits.ftqInfo.isLastInBlock := true.B }.otherwise { - infoBundle.bits.ftqInfo.predictBranch := false.B - infoBundle.bits.ftqInfo.isLastInBlock := false.B + infoBundle.bits.ftqInfo.isPredictValid := false.B + infoBundle.bits.ftqInfo.predictBranch := false.B + infoBundle.bits.ftqInfo.isLastInBlock := false.B } } diff --git a/src/src/frontend/fetch/InstResStage.scala b/src/src/frontend/fetch/InstResStage.scala index aa0bc159..8481918f 100644 --- a/src/src/frontend/fetch/InstResStage.scala +++ b/src/src/frontend/fetch/InstResStage.scala @@ -54,11 +54,13 @@ class InstResStage infoBundle.bits.exception := selectedIn.exception.bits infoBundle.bits.ftqInfo.ftqId := selectedIn.ftqId when((index + 1).U === selectedIn.ftqBlock.length) { - infoBundle.bits.ftqInfo.predictBranch := selectedIn.ftqBlock.predictTaken - infoBundle.bits.ftqInfo.isLastInBlock := true.B + infoBundle.bits.ftqInfo.predictBranch := selectedIn.ftqBlock.predictTaken + infoBundle.bits.ftqInfo.isPredictValid := selectedIn.ftqBlock.predictValid + infoBundle.bits.ftqInfo.isLastInBlock := true.B }.otherwise { - infoBundle.bits.ftqInfo.predictBranch := false.B - infoBundle.bits.ftqInfo.isLastInBlock := false.B + infoBundle.bits.ftqInfo.predictBranch := false.B + infoBundle.bits.ftqInfo.isPredictValid := false.B + infoBundle.bits.ftqInfo.isLastInBlock := false.B } } diff --git a/src/src/pipeline/common/bundles/FtqInfoBundle.scala b/src/src/pipeline/common/bundles/FtqInfoBundle.scala index 292f20be..0e93b661 100644 --- a/src/src/pipeline/common/bundles/FtqInfoBundle.scala +++ b/src/src/pipeline/common/bundles/FtqInfoBundle.scala @@ -7,7 +7,8 @@ class FtqInfoBundle extends Bundle { val isLastInBlock = Bool() val ftqId = UInt(Param.BPU.Width.id) // val idxInBlock = UInt(log2Ceil(Param.fetchInstMaxNum).W) - val predictBranch = Bool() + val predictBranch = Bool() + val isPredictValid = Bool() } object FtqInfoBundle extends Bundle { diff --git a/src/src/pipeline/complex/execution/ExePassWbStage.scala b/src/src/pipeline/complex/execution/ExePassWbStage.scala index b5024ef1..cb70dc09 100644 --- a/src/src/pipeline/complex/execution/ExePassWbStage.scala +++ b/src/src/pipeline/complex/execution/ExePassWbStage.scala @@ -233,8 +233,11 @@ class ExePassWbStage(supportBranchCsr: Boolean = true) resultOutReg.bits.instInfo.ftqCommitInfo.targetMispredict.get := branchTargetMispredict && branchEnableFlag && isBranchInst } - branchSetPort.en := isRedirect - branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId + branchSetPort.en := isRedirect + branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId + feedbackFtq.feedBack.fixGhrBundle.isExeFixValid := branchDirectionMispredict && branchEnableFlag && isBranchInst + feedbackFtq.feedBack.fixGhrBundle.exeFixFirstBrTaken := jumpBranchInfo.en && !inFtqInfo.isPredictValid && branchEnableFlag && isBranchInst // TODO predictValid + feedbackFtq.feedBack.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en branchSetPort.pcAddr := Mux( jumpBranchInfo.en, @@ -244,25 +247,25 @@ class ExePassWbStage(supportBranchCsr: Boolean = true) if (Param.exeFeedBackFtqDelay) { - feedbackFtq.commitBundle.ftqMetaUpdateValid := (RegNext(isBranchInst, false.B) || + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateValid := (RegNext(isBranchInst, false.B) || (RegNext(!isBranchInst, false.B) && RegNext(inFtqInfo.predictBranch, false.B))) && RegNext( branchEnableFlag, false.B ) - feedbackFtq.commitBundle.ftqMetaUpdateFtbDirty := RegNext(branchTargetMispredict, false.B) || + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateFtbDirty := RegNext(branchTargetMispredict, false.B) || (RegNext(jumpBranchInfo.en, false.B) && !RegNext(inFtqInfo.isLastInBlock, false.B)) || (RegNext(!isBranchInst, false.B) && RegNext(inFtqInfo.predictBranch, false.B)) - feedbackFtq.commitBundle.ftqUpdateMetaId := RegNext(inFtqInfo.ftqId, 0.U) - feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpBranchInfo.pcAddr, 0.U) - feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) + feedbackFtq.feedBack.commitBundle.ftqUpdateMetaId := RegNext(inFtqInfo.ftqId, 0.U) + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpBranchInfo.pcAddr, 0.U) + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) } else { - feedbackFtq.commitBundle.ftqMetaUpdateValid := (isBranchInst || (!isBranchInst && inFtqInfo.predictBranch)) && branchEnableFlag - feedbackFtq.commitBundle.ftqMetaUpdateFtbDirty := branchTargetMispredict || + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateValid := (isBranchInst || (!isBranchInst && inFtqInfo.predictBranch)) && branchEnableFlag + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateFtbDirty := branchTargetMispredict || (jumpBranchInfo.en && !inFtqInfo.isLastInBlock) || (!isBranchInst && inFtqInfo.predictBranch) - feedbackFtq.commitBundle.ftqUpdateMetaId := inFtqInfo.ftqId - feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := jumpBranchInfo.pcAddr - feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := fallThroughPc + feedbackFtq.feedBack.commitBundle.ftqUpdateMetaId := inFtqInfo.ftqId + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateJumpTarget := jumpBranchInfo.pcAddr + feedbackFtq.feedBack.commitBundle.ftqMetaUpdateFallThrough := fallThroughPc } resultOutReg.bits.instInfo.ftqCommitInfo.isBranchSuccess := jumpBranchInfo.en diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 1476d6e8..70513b9f 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -72,7 +72,7 @@ class ExePeerPort extends Bundle { val stableCounterReadPort = Flipped(new StableCounterReadPort) val csrReadPort = Flipped(new CsrReadPort) - val feedbackFtq = Output(new ExeCommitFtqNdPort) + val feedbackFtq = Output(new ExeFtqFeedBackNdPort) // val robQueryPcPort = Flipped(new RobQueryPcPort) @@ -448,8 +448,11 @@ class MainExeStage out.wb.instInfo.ftqCommitInfo.targetMispredict.get := branchTargetMispredict && isBranchInst } - branchSetPort.en := isRedirect && !branchBlockingReg && !isDbarBlockingReg - branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId + branchSetPort.en := isRedirect && !branchBlockingReg && !isDbarBlockingReg + branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId + feedbackFtq.fixGhrBundle.isExeFixValid := branchDirectionMispredict && !branchBlockingReg && isBranchInst + feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := jumpBranchInfo.en && !inFtqInfo.isPredictValid && !branchBlockingReg && isBranchInst // TODO predictValid + feedbackFtq.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en branchSetPort.pcAddr := Mux( jumpBranchInfo.en, @@ -459,25 +462,25 @@ class MainExeStage if (Param.exeFeedBackFtqDelay) { - feedbackFtq.ftqMetaUpdateValid := (RegNext(isBranchInst, false.B) || + feedbackFtq.commitBundle.ftqMetaUpdateValid := (RegNext(isBranchInst, false.B) || (RegNext(!isBranchInst, false.B) && RegNext(inFtqInfo.predictBranch, false.B))) && RegNext( !branchBlockingReg, false.B ) - feedbackFtq.ftqMetaUpdateFtbDirty := RegNext(branchTargetMispredict, false.B) || + feedbackFtq.commitBundle.ftqMetaUpdateFtbDirty := RegNext(branchTargetMispredict, false.B) || (RegNext(jumpBranchInfo.en, false.B) && !RegNext(inFtqInfo.isLastInBlock, false.B)) || (RegNext(!isBranchInst, false.B) && RegNext(inFtqInfo.predictBranch, false.B)) - feedbackFtq.ftqUpdateMetaId := RegNext(inFtqInfo.ftqId, 0.U) - feedbackFtq.ftqMetaUpdateJumpTarget := RegNext(jumpBranchInfo.pcAddr, 0.U) - feedbackFtq.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) + feedbackFtq.commitBundle.ftqUpdateMetaId := RegNext(inFtqInfo.ftqId, 0.U) + feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpBranchInfo.pcAddr, 0.U) + feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) } else { - feedbackFtq.ftqMetaUpdateValid := (isBranchInst || (!isBranchInst && inFtqInfo.predictBranch)) && !branchBlockingReg - feedbackFtq.ftqMetaUpdateFtbDirty := branchTargetMispredict || + feedbackFtq.commitBundle.ftqMetaUpdateValid := (isBranchInst || (!isBranchInst && inFtqInfo.predictBranch)) && !branchBlockingReg + feedbackFtq.commitBundle.ftqMetaUpdateFtbDirty := branchTargetMispredict || (jumpBranchInfo.en && !inFtqInfo.isLastInBlock) || (!isBranchInst && inFtqInfo.predictBranch) - feedbackFtq.ftqUpdateMetaId := inFtqInfo.ftqId - feedbackFtq.ftqMetaUpdateJumpTarget := jumpBranchInfo.pcAddr - feedbackFtq.ftqMetaUpdateFallThrough := fallThroughPc + feedbackFtq.commitBundle.ftqUpdateMetaId := inFtqInfo.ftqId + feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := jumpBranchInfo.pcAddr + feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := fallThroughPc } // out.wb.instInfo.ftqCommitInfo.isBranchSuccess := jumpBranchInfo.en From 77fe311c03874e9da1f0339f70823af2fa9a143e Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Thu, 10 Aug 2023 18:41:52 +0800 Subject: [PATCH 06/16] fix:ghrUpdate connection error --- src/src/frontend/bpu/TagePredictor.scala | 83 +++++++++++++--------- src/src/pipeline/simple/MainExeStage.scala | 16 +++-- 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 4106dc2d..3c211a94 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -87,11 +87,14 @@ class TagePredictor( val queryNewEntryFlag = WireDefault(false.B) // Indicates the provider is new // Meta - val tagCtrbits = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(3.W)))) - val tagUsefulbits = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(componentUsefulWidth(1).W)))) - val tagQueryTags = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(tagComponentTagWidth.W)))) - val tagOriginTags = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(tagComponentTagWidth.W)))) - val tagHitIndexs = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(10.W)))) + val tagCtrbits = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(3.W)))) + val tagUsefulbits = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(componentUsefulWidth(1).W)))) + val tagQueryTags = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(tagComponentTagWidth.W)))) + val tagOriginTags = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(tagComponentTagWidth.W)))) + val tagHitIndexs = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(10.W)))) + val tagGhtHashs = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(phtAddrWidth.W)))) + val tagTagHashCsr1s = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U(tagComponentTagWidth.W)))) + val tagTagHashCsr2s = WireDefault(VecInit(Seq.fill(tagComponentNum)(0.U((tagComponentTagWidth - 1).W)))) // update val updatePc = WireDefault(0.U(Width.Reg.data)) @@ -144,13 +147,13 @@ class TagePredictor( checkDepth := checkPtr - commitPtr // calculate the location of the correct old history // Global History Register - val ghr = RegInit(0.U(ghrDepth.W)) - val nextGhr = Wire(UInt(ghrDepth.W)) + val globalHistoryReg = RegInit(0.U(ghrDepth.W)) + val nextGlobalHistory = Wire(UInt(ghrDepth.W)) // default nextGhr keep value; ghr = RegNext(nextGhr) (assign in the next clock) - nextGhr := ghr - ghr := nextGhr - nextSpecPtr := specPtr - specPtr := nextSpecPtr + nextGlobalHistory := globalHistoryReg + globalHistoryReg := nextGlobalHistory + nextSpecPtr := specPtr + specPtr := nextSpecPtr // signal that indicates how to fix globalHistory Hash value val isFixUpdateCsr = WireDefault(false.B) @@ -179,24 +182,30 @@ class TagePredictor( when(io.ghrUpdateNdBundle.fixBundle.isFixGhrValid) { switch(io.ghrUpdateNdBundle.fixBundle.ghrFixType) { is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { - nextGhr := ghr >> checkDepth // recover to the old history - nextSpecPtr := checkPtr - 1.U - isRecoverCsr := true.B + nextGlobalHistory := globalHistoryReg >> checkDepth // recover to the old history + nextSpecPtr := checkPtr - 1.U + isRecoverCsr := true.B } is(GhrFixType.exeFixDirection) { - nextGhr := Cat(ghr >> checkDepth, io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken) // fix error predict - nextSpecPtr := checkPtr + nextGlobalHistory := Cat( + globalHistoryReg >> checkDepth, + io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken + ) // fix error predict + nextSpecPtr := checkPtr isFixDirectionCsr := true.B } is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { - nextGhr := Cat(ghr >> checkDepth, true.B) // update the branch that has not been predicted + nextGlobalHistory := Cat( + globalHistoryReg >> checkDepth, + true.B + ) // update the branch that has not been predicted nextSpecPtr := checkPtr + 1.U isFixUpdateCsr := true.B } } }.elsewhen(io.ghrUpdateNdBundle.bpuSpecValid) { - nextGhr := Cat(ghr(ghrDepth - 2, 0), io.ghrUpdateNdBundle.bpuSpecTaken) - nextSpecPtr := specPtr + 1.U + nextGlobalHistory := Cat(globalHistoryReg(ghrDepth - 2, 0), io.ghrUpdateNdBundle.bpuSpecTaken) + nextSpecPtr := specPtr + 1.U } // when(isUpdateValid) { @@ -231,19 +240,19 @@ class TagePredictor( ) ) // Query - taggedPreditor.io.isGlobalHistoryUpdate := io.ghrUpdateNdBundle.bpuSpecValid - taggedPreditor.io.globalHistory := nextGhr(historyLengths(providerId + 1) - 1, 0) - taggedPreditor.io.pc := io.pc - tagUsefulbits(providerId) := taggedPreditor.io.usefulBits - tagCtrbits(providerId) := taggedPreditor.io.ctrBits - tagQueryTags(providerId) := taggedPreditor.io.queryTag - tagOriginTags(providerId) := taggedPreditor.io.originTag - tagHitIndexs(providerId) := taggedPreditor.io.hitIndex - tagIsTakens(providerId) := taggedPreditor.io.taken - tagIsHits(providerId) := taggedPreditor.io.tagHit - io.tageQueryMeta.tageGhrInfo.tagGhtHashs(providerId) := taggedPreditor.io.queryGhtHash - io.tageQueryMeta.tageGhrInfo.tagTagHashCsr1s(providerId) := taggedPreditor.io.queryTagHashCsr1 - io.tageQueryMeta.tageGhrInfo.tagTagHashCsr2s(providerId) := taggedPreditor.io.queryTagHashCsr2 + taggedPreditor.io.isGlobalHistoryUpdate := io.ghrUpdateNdBundle.bpuSpecValid + taggedPreditor.io.globalHistory := nextGlobalHistory(historyLengths(providerId + 1) - 1, 0) + taggedPreditor.io.pc := io.pc + tagUsefulbits(providerId) := taggedPreditor.io.usefulBits + tagCtrbits(providerId) := taggedPreditor.io.ctrBits + tagQueryTags(providerId) := taggedPreditor.io.queryTag + tagOriginTags(providerId) := taggedPreditor.io.originTag + tagHitIndexs(providerId) := taggedPreditor.io.hitIndex + tagIsTakens(providerId) := taggedPreditor.io.taken + tagIsHits(providerId) := taggedPreditor.io.tagHit + tagGhtHashs(providerId) := taggedPreditor.io.queryGhtHash + tagTagHashCsr1s(providerId) := taggedPreditor.io.queryTagHashCsr1 + tagTagHashCsr2s(providerId) := taggedPreditor.io.queryTagHashCsr2 // update taggedPreditor.io.updatePc := io.updatePc @@ -260,9 +269,9 @@ class TagePredictor( taggedPreditor.io.isRecoverCsr := isRecoverCsr taggedPreditor.io.isFixUpdateCsr := isFixUpdateCsr taggedPreditor.io.isFixDirectionCsr := isFixDirectionCsr - taggedPreditor.io.originGhtHash := io.updateInfoPort.tageOriginMeta.tageGhrInfo.tagGhtHashs(providerId) - taggedPreditor.io.originTagHashCsr1 := io.updateInfoPort.tageOriginMeta.tageGhrInfo.tagTagHashCsr1s(providerId) - taggedPreditor.io.originTagHashCsr2 := io.updateInfoPort.tageOriginMeta.tageGhrInfo.tagTagHashCsr2s(providerId) + taggedPreditor.io.originGhtHash := updateMetaBundle.tageGhrInfo.tagGhtHashs(providerId) + taggedPreditor.io.originTagHashCsr1 := updateMetaBundle.tageGhrInfo.tagTagHashCsr1s(providerId) + taggedPreditor.io.originTagHashCsr2 := updateMetaBundle.tageGhrInfo.tagTagHashCsr2s(providerId) taggedPreditor } @@ -316,6 +325,10 @@ class TagePredictor( vecAssign(queryMetaBundle.tagPredictorHitIndexs, tagHitIndexs) vecAssign(queryMetaBundle.tagPredictorQueryTags, tagQueryTags) vecAssign(queryMetaBundle.tagPredictorOriginTags, tagOriginTags) + vecAssign(queryMetaBundle.tageGhrInfo.tagGhtHashs, tagGhtHashs) + vecAssign(queryMetaBundle.tageGhrInfo.tagTagHashCsr1s, tagTagHashCsr1s) + vecAssign(queryMetaBundle.tageGhrInfo.tagTagHashCsr2s, tagTagHashCsr2s) + queryMetaBundle.tageGhrInfo.checkPtr := nextSpecPtr queryMetaBundle.isUseful := takens(predPredictionId) =/= takens( altPredPredctionId ) // Indicates whether the pred component is useful diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 70513b9f..a21a94d9 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -448,11 +448,17 @@ class MainExeStage out.wb.instInfo.ftqCommitInfo.targetMispredict.get := branchTargetMispredict && isBranchInst } - branchSetPort.en := isRedirect && !branchBlockingReg && !isDbarBlockingReg - branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId - feedbackFtq.fixGhrBundle.isExeFixValid := branchDirectionMispredict && !branchBlockingReg && isBranchInst - feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := jumpBranchInfo.en && !inFtqInfo.isPredictValid && !branchBlockingReg && isBranchInst // TODO predictValid - feedbackFtq.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en + branchSetPort.en := isRedirect && !branchBlockingReg && !isDbarBlockingReg + branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId + feedbackFtq.fixGhrBundle.isExeFixValid := RegNext( + branchDirectionMispredict && !branchBlockingReg && isBranchInst, + false.B + ) + feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := RegNext( + jumpBranchInfo.en && !inFtqInfo.isPredictValid && !branchBlockingReg && isBranchInst, + false.B + ) // TODO predictValid + feedbackFtq.fixGhrBundle.exeFixIsTaken := RegNext(jumpBranchInfo.en, false.B) branchSetPort.pcAddr := Mux( jumpBranchInfo.en, From 1ab8d773e5dc32ab0d08c4b80e325247664bc662 Mon Sep 17 00:00:00 2001 From: Chrisqcwx <3075401625@qq.com> Date: Thu, 10 Aug 2023 21:31:10 +0800 Subject: [PATCH 07/16] refactor: simplify some logic --- src/src/execution/Alu.scala | 32 +++++++------------ src/src/pipeline/simple/MainExeStage.scala | 37 ++++++++++++++-------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/src/execution/Alu.scala b/src/src/execution/Alu.scala index 179040ed..8bdb54c7 100644 --- a/src/src/execution/Alu.scala +++ b/src/src/execution/Alu.scala @@ -19,7 +19,7 @@ class Alu extends Module { }) io.outputValid := true.B - io.result := AluResultNdPort.default + io.result := DontCare def lop = io.aluInst.leftOperand @@ -28,20 +28,14 @@ class Alu extends Module { /** Result definition */ - val logic = WireDefault(zeroWord) + val logic = io.result.logic - val shift = WireDefault(zeroWord) + val shift = io.result.shift - val jumpBranchInfo = WireDefault(JumpBranchInfoNdPort.default) + val jumpBranchInfo = io.result.jumpBranchInfo // computed with one cycle - val arithmetic = WireDefault(zeroWord) - - // Fallback - io.result.arithmetic := arithmetic - io.result.logic := logic - io.result.jumpBranchInfo := jumpBranchInfo - io.result.shift := shift + val arithmetic = io.result.arithmetic // Logic computation @@ -117,14 +111,13 @@ class Alu extends Module { val mulStage = Module(new Mul) - val useSignedMul = WireDefault( + val useSignedMul = VecInit( ExeInst.Op.mul, ExeInst.Op.mulh ).contains(io.aluInst.op) - ) - val useUnsignedMul = WireDefault(io.aluInst.op === ExeInst.Op.mulhu) + val useUnsignedMul = io.aluInst.op === ExeInst.Op.mulhu val useMul = WireDefault(useSignedMul || useUnsignedMul) @@ -136,7 +129,7 @@ class Alu extends Module { mulStage.io.mulInst.bits.leftOperand := lop mulStage.io.mulInst.bits.rightOperand := rop - val mulResult = WireDefault(mulStage.io.mulResult.bits) + val mulResult = mulStage.io.mulResult.bits // Div @@ -151,9 +144,9 @@ class Alu extends Module { val divStage = Module(new Div) - val divisorValid = WireDefault(rop =/= 0.U) + val divisorValid = rop =/= 0.U - val divStart = WireDefault(useDiv && divisorValid) + val divStart = useDiv && divisorValid divStage.io.isFlush := io.isFlush divStage.io.divInst.valid := divStart @@ -164,8 +157,8 @@ class Alu extends Module { divStage.io.divInst.bits.leftOperand := lop divStage.io.divInst.bits.rightOperand := rop - val quotient = WireDefault(divStage.io.divResult.bits.quotient) - val remainder = WireDefault(divStage.io.divResult.bits.remainder) + val quotient = divStage.io.divResult.bits.quotient + val remainder = divStage.io.divResult.bits.remainder io.outputValid := !(mulStart && !mulStage.io.mulResult.valid) && ( @@ -201,6 +194,5 @@ class Alu extends Module { when(io.isFlush) { io.outputValid := false.B - mulResult := 0.U } } diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index a21a94d9..13720faa 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -413,11 +413,12 @@ class MainExeStage val branchSetPort = io.peer.get.branchSetPort // branch set - branchSetPort := BackendRedirectPcNdPort.default + branchSetPort := DontCare + branchSetPort.en := false.B val feedbackFtq = io.peer.get.feedbackFtq - val jumpBranchInfo = WireDefault(alu.io.result.jumpBranchInfo) - val inFtqInfo = WireDefault(selectedIn.instInfo.ftqInfo) + val jumpBranchInfo = alu.io.result.jumpBranchInfo + val inFtqInfo = selectedIn.instInfo.ftqInfo val ftqQueryPc = selectedIn.branchInfo.predictJumpAddr @@ -448,17 +449,10 @@ class MainExeStage out.wb.instInfo.ftqCommitInfo.targetMispredict.get := branchTargetMispredict && isBranchInst } - branchSetPort.en := isRedirect && !branchBlockingReg && !isDbarBlockingReg + val isBlocking = branchBlockingReg || isDbarBlockingReg + + branchSetPort.en := isRedirect && !isBlocking branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId - feedbackFtq.fixGhrBundle.isExeFixValid := RegNext( - branchDirectionMispredict && !branchBlockingReg && isBranchInst, - false.B - ) - feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := RegNext( - jumpBranchInfo.en && !inFtqInfo.isPredictValid && !branchBlockingReg && isBranchInst, - false.B - ) // TODO predictValid - feedbackFtq.fixGhrBundle.exeFixIsTaken := RegNext(jumpBranchInfo.en, false.B) branchSetPort.pcAddr := Mux( jumpBranchInfo.en, @@ -470,7 +464,7 @@ class MainExeStage feedbackFtq.commitBundle.ftqMetaUpdateValid := (RegNext(isBranchInst, false.B) || (RegNext(!isBranchInst, false.B) && RegNext(inFtqInfo.predictBranch, false.B))) && RegNext( - !branchBlockingReg, + !isBlocking, false.B ) feedbackFtq.commitBundle.ftqMetaUpdateFtbDirty := RegNext(branchTargetMispredict, false.B) || @@ -479,6 +473,16 @@ class MainExeStage feedbackFtq.commitBundle.ftqUpdateMetaId := RegNext(inFtqInfo.ftqId, 0.U) feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpBranchInfo.pcAddr, 0.U) feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) + + feedbackFtq.fixGhrBundle.isExeFixValid := RegNext( + branchDirectionMispredict && !isBlocking && isBranchInst, + false.B + ) + feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := RegNext( + jumpBranchInfo.en && !inFtqInfo.isPredictValid && !isBlocking && isBranchInst, + false.B + ) // TODO predictValid + feedbackFtq.fixGhrBundle.exeFixIsTaken := RegNext(jumpBranchInfo.en, false.B) } else { feedbackFtq.commitBundle.ftqMetaUpdateValid := (isBranchInst || (!isBranchInst && inFtqInfo.predictBranch)) && !branchBlockingReg @@ -487,6 +491,11 @@ class MainExeStage feedbackFtq.commitBundle.ftqUpdateMetaId := inFtqInfo.ftqId feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := jumpBranchInfo.pcAddr feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := fallThroughPc + + feedbackFtq.fixGhrBundle.isExeFixValid := branchDirectionMispredict && !isBlocking && isBranchInst + feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := + jumpBranchInfo.en && !inFtqInfo.isPredictValid && !isBlocking && isBranchInst + feedbackFtq.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en } // out.wb.instInfo.ftqCommitInfo.isBranchSuccess := jumpBranchInfo.en From 143fd53f51d954597e0a830141658246f705b962 Mon Sep 17 00:00:00 2001 From: Chrisqcwx <3075401625@qq.com> Date: Thu, 10 Aug 2023 22:13:10 +0800 Subject: [PATCH 08/16] refactor: some logic for branch in exe calc early --- src/src/SimpleCoreCpuTop.scala | 1 - .../complex}/execution/Alu.scala | 4 +- .../complex/execution/ExePassWbStage.scala | 2 +- src/src/pipeline/simple/Alu.scala | 200 ++++++++++ src/src/pipeline/simple/MainExeStage.scala | 9 +- src/src/pipeline/simple/SimpleExeStage.scala | 2 +- .../bundles/MainExeBranchInfoBundle.scala | 11 +- src/src/pipeline/simple/id/IssueQueue.scala | 15 +- src/src/pipeline/simple/id/IssueStage.scala | 352 ------------------ 9 files changed, 229 insertions(+), 367 deletions(-) rename src/src/{ => pipeline/complex}/execution/Alu.scala (98%) create mode 100644 src/src/pipeline/simple/Alu.scala delete mode 100644 src/src/pipeline/simple/id/IssueStage.scala diff --git a/src/src/SimpleCoreCpuTop.scala b/src/src/SimpleCoreCpuTop.scala index 742922d5..ed57d014 100644 --- a/src/src/SimpleCoreCpuTop.scala +++ b/src/src/SimpleCoreCpuTop.scala @@ -1,5 +1,4 @@ import pipeline.simple.MainExeStage -import pipeline.simple.id.IssueStage import axi.Axi3x1Crossbar import axi.bundles.AxiMasterInterface import chisel3._ diff --git a/src/src/execution/Alu.scala b/src/src/pipeline/complex/execution/Alu.scala similarity index 98% rename from src/src/execution/Alu.scala rename to src/src/pipeline/complex/execution/Alu.scala index 8bdb54c7..1a6235be 100644 --- a/src/src/execution/Alu.scala +++ b/src/src/pipeline/complex/execution/Alu.scala @@ -1,4 +1,4 @@ -package execution +package pipeline.complex.execution import chisel3._ import chisel3.util._ @@ -6,6 +6,8 @@ import execution.bundles.{AluInstNdPort, AluResultNdPort} import pipeline.complex.execution.bundles.JumpBranchInfoNdPort import spec.ExeInst.Op import spec._ +import execution.Mul +import execution.Div class Alu extends Module { val io = IO(new Bundle { diff --git a/src/src/pipeline/complex/execution/ExePassWbStage.scala b/src/src/pipeline/complex/execution/ExePassWbStage.scala index cb70dc09..e2fddbc8 100644 --- a/src/src/pipeline/complex/execution/ExePassWbStage.scala +++ b/src/src/pipeline/complex/execution/ExePassWbStage.scala @@ -7,7 +7,7 @@ import common.bundles._ import control.bundles.{CsrReadPort, CsrWriteNdPort, StableCounterReadPort} import control.csrBundles.{EraBundle, LlbctlBundle} import control.enums.ExceptionPos -import execution.Alu +import pipeline.complex.execution.Alu import frontend.bundles.ExeFtqPort import pipeline.common.bundles.RobQueryPcPort import pipeline.complex.bundles.InstInfoNdPort diff --git a/src/src/pipeline/simple/Alu.scala b/src/src/pipeline/simple/Alu.scala new file mode 100644 index 00000000..cb647bc5 --- /dev/null +++ b/src/src/pipeline/simple/Alu.scala @@ -0,0 +1,200 @@ +package pipeline.simple.execution + +import chisel3._ +import chisel3.util._ +import execution.bundles.{AluInstNdPort, AluResultNdPort} +import pipeline.complex.execution.bundles.JumpBranchInfoNdPort +import spec.ExeInst.Op +import spec._ +import execution.Mul +import execution.Div + +class Alu extends Module { + val io = IO(new Bundle { + val inputValid = Input(Bool()) + val aluInst = Input(new AluInstNdPort) + + val outputValid = Output(Bool()) + val result = Output(new AluResultNdPort) + + val isFlush = Input(Bool()) + }) + + io.outputValid := true.B + io.result := DontCare + + def lop = io.aluInst.leftOperand + + def rop = io.aluInst.rightOperand + + /** Result definition + */ + + val logic = io.result.logic + + val shift = io.result.shift + + val jumpBranchInfo = io.result.jumpBranchInfo + + // computed with one cycle + val arithmetic = io.result.arithmetic + + // Logic computation + + switch(io.aluInst.op) { + is(Op.nor) { + logic := ~(lop | rop) + } + is(Op.and) { + logic := lop & rop + } + is(Op.or) { + logic := lop | rop + } + is(Op.xor) { + logic := lop ^ rop + } + } + + // shift computation + + switch(io.aluInst.op) { + is(Op.sll) { + shift := lop << rop(4, 0) + } + is(Op.srl) { + shift := lop >> rop(4, 0) + } + is(Op.sra) { + shift := (lop.asSInt >> rop(4, 0)).asUInt + } + } + + // jump and branch computation + + switch(io.aluInst.op) { + is(Op.b, Op.bl) { + jumpBranchInfo.en := true.B + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.jirl) { + jumpBranchInfo.en := true.B + // jumpBranchInfo.pcAddr := lop + io.aluInst.jumpBranchAddr + } + is(Op.beq) { + jumpBranchInfo.en := lop === rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bne) { + jumpBranchInfo.en := lop =/= rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.blt) { + jumpBranchInfo.en := lop.asSInt < rop.asSInt + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bge) { + jumpBranchInfo.en := lop.asSInt >= rop.asSInt + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bltu) { + jumpBranchInfo.en := lop < rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bgeu) { + jumpBranchInfo.en := lop >= rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + } + + // arithmetic computation + + // mul + + val mulStage = Module(new Mul) + + val useSignedMul = + VecInit( + ExeInst.Op.mul, + ExeInst.Op.mulh + ).contains(io.aluInst.op) + + val useUnsignedMul = io.aluInst.op === ExeInst.Op.mulhu + + val useMul = WireDefault(useSignedMul || useUnsignedMul) + + val mulStart = useMul + + mulStage.io.isFlush := io.isFlush + mulStage.io.mulInst.valid := mulStart + mulStage.io.mulInst.bits.isSigned := useSignedMul + mulStage.io.mulInst.bits.leftOperand := lop + mulStage.io.mulInst.bits.rightOperand := rop + + val mulResult = mulStage.io.mulResult.bits + + // Div + + val useDiv = WireDefault( + VecInit( + ExeInst.Op.div, + ExeInst.Op.divu, + ExeInst.Op.mod, + ExeInst.Op.modu + ).contains(io.aluInst.op) + ) + + val divStage = Module(new Div) + + val divisorValid = rop =/= 0.U + + val divStart = useDiv && divisorValid + + divStage.io.isFlush := io.isFlush + divStage.io.divInst.valid := divStart + divStage.io.divInst.bits.isSigned := VecInit( + ExeInst.Op.div, + ExeInst.Op.mod + ).contains(io.aluInst.op) + divStage.io.divInst.bits.leftOperand := lop + divStage.io.divInst.bits.rightOperand := rop + + val quotient = divStage.io.divResult.bits.quotient + val remainder = divStage.io.divResult.bits.remainder + + io.outputValid := + !(mulStart && !mulStage.io.mulResult.valid) && ( + !(divStart && !divStage.io.divResult.valid) + ) + + switch(io.aluInst.op) { + is(Op.add) { + arithmetic := (lop.asSInt + rop.asSInt).asUInt + } + is(Op.sub) { + arithmetic := (lop.asSInt - rop.asSInt).asUInt + } + is(Op.slt) { + arithmetic := (lop.asSInt < rop.asSInt).asUInt + } + is(Op.sltu) { + arithmetic := (lop < rop).asUInt + } + is(Op.mul) { + arithmetic := mulResult(wordLength - 1, 0) + } + is(Op.mulh, Op.mulhu) { + arithmetic := mulResult(doubleWordLength - 1, wordLength) + } + is(Op.div, Op.divu) { + arithmetic := divStage.io.divResult.bits.quotient + } + is(Op.mod, Op.modu) { + arithmetic := divStage.io.divResult.bits.remainder + } + } + + when(io.isFlush) { + io.outputValid := false.B + } +} diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 13720faa..22591e64 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -7,7 +7,7 @@ import common.BaseStage import common.bundles._ import control.bundles._ import control.csrBundles._ -import execution.Alu +import pipeline.simple.execution.Alu import frontend.bundles._ import pipeline.common.bundles.{CacheMaintenanceInstNdPort, RobQueryPcPort} import pipeline.simple.bundles.InstInfoNdPort @@ -308,7 +308,7 @@ class MainExeStage isDbarBlockingReg := false.B } - val fallThroughPc = selectedIn.branchInfo.pc + 4.U + val fallThroughPc = selectedIn.branchInfo.fallThroughPc switch(selectedIn.exeSel) { is(Sel.logic) { @@ -424,6 +424,11 @@ class MainExeStage // mis predict val branchDirectionMispredict = jumpBranchInfo.en ^ inFtqInfo.predictBranch + // val jumpAddr = Mux( + // selectedIn.exeOp === ExeInst.Op.jirl, + // selectedIn.leftOperand , + // DontCare + // ) val branchTargetMispredict = ( jumpBranchInfo.en && inFtqInfo.predictBranch && diff --git a/src/src/pipeline/simple/SimpleExeStage.scala b/src/src/pipeline/simple/SimpleExeStage.scala index bffcf54b..125978ee 100644 --- a/src/src/pipeline/simple/SimpleExeStage.scala +++ b/src/src/pipeline/simple/SimpleExeStage.scala @@ -4,7 +4,7 @@ import chisel3._ import chisel3.util._ import spec.ExeInst.Sel import common.BaseStage -import execution.Alu +import pipeline.simple.execution.Alu import pipeline.simple.ExeNdPort import pipeline.simple.bundles.WbNdPort import pipeline.simple.bundles.RegWakeUpNdPort diff --git a/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala b/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala index 383b08ba..0d23571d 100644 --- a/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala +++ b/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala @@ -4,8 +4,11 @@ import chisel3._ import spec._ class MainExeBranchInfoBundle extends Bundle { - val isBranch = Bool() - val branchType = UInt(Param.BPU.BranchType.width.W) - val pc = UInt(Width.Reg.data) - val predictJumpAddr = UInt(Width.Reg.data) + val isBranch = Bool() + val branchType = UInt(Param.BPU.BranchType.width.W) + val fallThroughPc = UInt(Width.Reg.data) + val predictSubImm = UInt(Width.Reg.data) + val predictJumpAddr = UInt(Width.Reg.data) + val fallThroughPredictCorrect = Bool() + val immPredictCorrect = Bool() } diff --git a/src/src/pipeline/simple/id/IssueQueue.scala b/src/src/pipeline/simple/id/IssueQueue.scala index 1def528d..59c97cd9 100644 --- a/src/src/pipeline/simple/id/IssueQueue.scala +++ b/src/src/pipeline/simple/id/IssueQueue.scala @@ -133,11 +133,16 @@ class IssueQueue( } // reservation station enqueue bits - mainRSEnqPort.bits.mainExeBranchInfo.pc := io.ins.head.bits.pc - io.queryPcPort.ftqId := io.ins.head.bits.instInfo.ftqInfo.ftqId + 1.U - mainRSEnqPort.bits.mainExeBranchInfo.predictJumpAddr := io.queryPcPort.pc - mainRSEnqPort.bits.mainExeBranchInfo.isBranch := io.ins.head.bits.decode.info.isBranch - mainRSEnqPort.bits.mainExeBranchInfo.branchType := io.ins.head.bits.decode.info.branchType + val fallThroughPc = io.ins.head.bits.pc + 4.U + val predictPc = io.queryPcPort.pc + mainRSEnqPort.bits.mainExeBranchInfo.fallThroughPc := fallThroughPc + mainRSEnqPort.bits.mainExeBranchInfo.fallThroughPredictCorrect := fallThroughPc === predictPc + mainRSEnqPort.bits.mainExeBranchInfo.immPredictCorrect := io.ins.head.bits.decode.info.jumpBranchAddr === predictPc + mainRSEnqPort.bits.mainExeBranchInfo.predictSubImm := predictPc - io.ins.head.bits.decode.info.jumpBranchAddr + io.queryPcPort.ftqId := io.ins.head.bits.instInfo.ftqInfo.ftqId + 1.U + mainRSEnqPort.bits.mainExeBranchInfo.predictJumpAddr := predictPc + mainRSEnqPort.bits.mainExeBranchInfo.isBranch := io.ins.head.bits.decode.info.isBranch + mainRSEnqPort.bits.mainExeBranchInfo.branchType := io.ins.head.bits.decode.info.branchType rsEnqPorts.lazyZip(io.ins).lazyZip(io.regReadPorts).zipWithIndex.foreach { case ((rs, in, readRes), index) => diff --git a/src/src/pipeline/simple/id/IssueStage.scala b/src/src/pipeline/simple/id/IssueStage.scala deleted file mode 100644 index f4c19692..00000000 --- a/src/src/pipeline/simple/id/IssueStage.scala +++ /dev/null @@ -1,352 +0,0 @@ -package pipeline.simple.id - -import chisel3._ -import chisel3.util._ -import common.DistributedQueue -import common.bundles.BackendRedirectPcNdPort -import control.enums.ExceptionPos -import pipeline.common.bundles.{FetchInstInfoBundle, InstQueueEnqNdPort, PcInstBundle} -import pipeline.simple.decode._ -import pipeline.simple.decode.bundles._ -import spec._ -import frontend.bundles.QueryPcBundle -import pipeline.simple.bundles._ -import common.MultiQueue -import pipeline.simple.id.FetchInstDecodeNdPort -import pipeline.simple.MainExeNdPort -import pipeline.simple.ExeNdPort -import utils.MultiMux1 -import pipeline.simple.pmu.bundles.PmuDispatchInfoBundle - -// assert: enqueuePorts总是最低的几位有效 -class IssueStage( - issueNum: Int = Param.issueInstInfoMaxNum, - pipelineNum: Int = Param.pipelineNum) - extends Module { - val io = IO(new Bundle { - val isFrontendFlush = Input(Bool()) - val isBackendFlush = Input(Bool()) - - val enqueuePorts = Vec( - issueNum, - Flipped(Decoupled(new FetchInstInfoBundle)) - ) - - // `InstQueue` -> `IssueStage` - val dequeuePorts = new Bundle { - val mainExePort = Decoupled(new MainExeNdPort) - val simpleExePorts = Vec(pipelineNum - 1, Decoupled(new ExeNdPort)) - } - - val idleBlocking = Input(Bool()) - val hasInterrupt = Input(Bool()) - - val robIdRequests = Vec(issueNum, Flipped(new RobRequestPort)) - - val queryPcPort = Flipped(new QueryPcBundle) - - val regReadPorts = Vec(Param.issueInstInfoMaxNum, Vec(Param.regFileReadNum, Flipped(new RegReadPort))) - val occupyPorts = Output(Vec(Param.issueInstInfoMaxNum, new RegOccupyNdPort)) - - val wakeUpPorts = Input(Vec(pipelineNum + 1, new RegWakeUpNdPort)) - - val plv = Input(UInt(2.W)) - - val pmu_dispatchInfos = Option.when(Param.usePmu)(Output(Vec(Param.issueInstInfoMaxNum, new PmuDispatchInfoBundle))) - }) - require(issueNum == pipelineNum) - - private val rsLength = 2 - - val isIdle = RegInit(false.B) - when(io.hasInterrupt) { - isIdle := false.B - }.elsewhen(io.idleBlocking) { - isIdle := true.B - } - - // Decode - val decodeInstInfos = VecInit(io.enqueuePorts.map(_.bits)) - - // Select a decoder - - val decoders = Seq.fill(issueNum)(Module(new DecodeUnit)) - - decoders.zip(decodeInstInfos).foreach { - case (decoder, decodeInstInfo) => - decoder.io.in := decodeInstInfo - } - - val selectedDecoders = decoders.map(_.io.out) - - val mainRS = Module( - new MultiQueue(rsLength, 1, 1, new MainRSBundle, 0.U.asTypeOf(new MainRSBundle), writeFirst = false) - ) - val simpleRSs = Seq.fill(pipelineNum - 1)( - Module( - new MultiQueue(rsLength, 1, 1, new RSBundle, 0.U.asTypeOf(new RSBundle), writeFirst = false) - ) - ) - - val mainRSEnqPort = mainRS.io.enqueuePorts.head - val simpleRSEnqPorts = simpleRSs.map(_.io.enqueuePorts.head) - - mainRS.io.setPorts.zip(mainRS.io.elems).foreach { - case (set, elem) => - set.bits := elem - set.valid := true.B - } - mainRS.io.isFlush := io.isBackendFlush - simpleRSs.zip(simpleRSEnqPorts).foreach { - case (rs, enq) => - rs.io.setPorts.zip(rs.io.elems).foreach { - case (set, elem) => - set.bits := elem - set.valid := true.B - } - rs.io.isFlush := io.isBackendFlush - } - - val rsEnqPorts = Seq(mainRSEnqPort) ++ simpleRSEnqPorts - val rss = Seq(mainRS) ++ simpleRSs - - // reg read - io.regReadPorts.zip(rsEnqPorts).foreach { - case (readPorts, rsEnqPort) => - readPorts.zip(rsEnqPort.bits.decodePort.decode.info.gprReadPorts).foreach { - case (dst, src) => - dst.addr := src.addr - } - } - - // occupy - io.occupyPorts.lazyZip(rsEnqPorts).lazyZip(io.robIdRequests).foreach { - case (occupy, enq, robIdReq) => - occupy.en := enq.valid && enq.ready && enq.bits.decodePort.decode.info.gprWritePort.en - occupy.addr := enq.bits.decodePort.decode.info.gprWritePort.addr - occupy.robId := robIdReq.result.bits - } - - val isBlockDequeueReg = RegInit(false.B) - when(io.isBackendFlush) { - isBlockDequeueReg := false.B - }.elsewhen( - io.isFrontendFlush - || ( - rsEnqPorts.map { port => - port.valid && port.ready && ( - port.bits.decodePort.decode.info.needRefetch || - port.bits.decodePort.instInfo.exceptionPos =/= ExceptionPos.none - ) - }.reduce(_ || _) - ) - ) { - isBlockDequeueReg := true.B - } - - // rob id request - - rsEnqPorts.lazyZip(io.enqueuePorts).lazyZip(io.robIdRequests).zipWithIndex.foreach { - case ((dst, src, robIdReq), idx) => - src.ready := dst.ready - dst.valid := src.valid - - robIdReq.request.valid := src.valid && src.ready - robIdReq.request.bits.pcAddr := src.bits.pcAddr - robIdReq.request.bits.inst := src.bits.inst - - // block - when( - isBlockDequeueReg || - isIdle || - // io.isFrontendFlush || - !robIdReq.result.valid - ) { - dst.valid := false.B - src.ready := false.B - } - - rsEnqPorts.take(idx).foreach { prev => - val prevGprWrite = prev.bits.decodePort.decode.info.gprWritePort - - // data dependence - // dst.bits.decodePort.decode.info.gprReadPorts.foreach { r => - // when(r.en && prevGprWrite.en && r.addr === prevGprWrite.addr) { - // dst.valid := false.B - // src.ready := false.B - // } - // } - - // issue in order - when(!(prev.ready && prev.valid)) { - dst.valid := false.B - src.ready := false.B - } - } - - // should issue in main - if (idx != 0) { - when(dst.bits.decodePort.decode.info.isIssueMainPipeline) { - dst.valid := false.B - src.ready := false.B - } - } - } - - // reservation station enqueue bits - mainRSEnqPort.bits.mainExeBranchInfo.pc := decodeInstInfos.head.pcAddr - io.queryPcPort.ftqId := decodeInstInfos.head.ftqInfo.ftqId + 1.U - mainRSEnqPort.bits.mainExeBranchInfo.predictJumpAddr := io.queryPcPort.pc - mainRSEnqPort.bits.mainExeBranchInfo.isBranch := decoders.head.io.out.info.isBranch - mainRSEnqPort.bits.mainExeBranchInfo.branchType := decoders.head.io.out.info.branchType - - rsEnqPorts - .lazyZip(selectedDecoders) - .lazyZip(decodeInstInfos) - .zipWithIndex - .foreach { - case ( - ( - rs, - selectedDecoder, - decodeInstInfo - ), - index - ) => - val robIdReq = io.robIdRequests(index) - - val outReadResults = io.regReadPorts(index) - - rs.bits.regReadResults.lazyZip(outReadResults).lazyZip(selectedDecoder.info.gprReadPorts).foreach { - case (dst, readRes, decodeRead) => - dst.valid := !(decodeRead.en && !readRes.data.valid) - dst.bits := readRes.data.bits - - // data dependence - selectedDecoders.take(index).zipWithIndex.foreach { - case (prev, prevIdx) => - when(decodeRead.en && prev.info.gprWritePort.en && prev.info.gprWritePort.addr === decodeRead.addr) { - dst.valid := false.B - dst.bits := io.robIdRequests(prevIdx).result.bits - } - } - } - - val outInstInfo = rs.bits.decodePort.instInfo - - rs.bits.decodePort.decode := selectedDecoder - - outInstInfo := InstInfoNdPort.default - - val isMatched = selectedDecoder.isMatched - outInstInfo.isValid := true.B - outInstInfo.isCsrWrite := selectedDecoder.info.csrWriteEn - outInstInfo.exeOp := selectedDecoder.info.exeOp - outInstInfo.isTlb := selectedDecoder.info.isTlb - outInstInfo.needRefetch := selectedDecoder.info.needRefetch - outInstInfo.ftqInfo := decodeInstInfo.ftqInfo - - outInstInfo.forbidParallelCommit := selectedDecoder.info.needRefetch - - outInstInfo.exceptionPos := ExceptionPos.none - outInstInfo.exceptionRecord := DontCare - when(io.hasInterrupt) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := Csr.ExceptionIndex.int - }.elsewhen(decodeInstInfo.exceptionValid) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := decodeInstInfo.exception - }.elsewhen(!isMatched) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := Csr.ExceptionIndex.ine - }.elsewhen( - io.plv === 3.U && - selectedDecoder.info.isPrivilege - ) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := Csr.ExceptionIndex.ipe - } - - outInstInfo.robId := robIdReq.result.bits - - if (Param.isDiffTest) { - outInstInfo.pc.get := decodeInstInfo.pcAddr - outInstInfo.inst.get := decodeInstInfo.inst - } - - } - - // wake up - rss.foreach { rs => - rs.io.setPorts.zip(rs.io.elems).foreach { - case (set, elem) => - set.bits.regReadResults.lazyZip(elem.regReadResults).lazyZip(elem.decodePort.decode.info.gprReadPorts).foreach { - case (setRegData, elemData, decodeRead) => - setRegData := elemData - - val mux = Module(new MultiMux1(pipelineNum + 1, UInt(Width.Reg.data), zeroWord)) - mux.io.inputs.zip(io.wakeUpPorts).foreach { - case (input, wakeUp) => - input.valid := wakeUp.en && - wakeUp.addr === decodeRead.addr && - wakeUp.robId(Param.Width.Rob._id - 1, 0) === elemData.bits(Param.Width.Rob._id - 1, 0) - input.bits := wakeUp.data - } - when(!elemData.valid && mux.io.output.valid) { - setRegData.valid := true.B - setRegData.bits := mux.io.output.bits - } - } - } - } - - // output - io.dequeuePorts.mainExePort.bits.branchInfo := mainRS.io.dequeuePorts.head.bits.mainExeBranchInfo - (Seq(io.dequeuePorts.mainExePort) ++ io.dequeuePorts.simpleExePorts).zip(rss.map(_.io.dequeuePorts.head)).foreach { - case (out, rs) => - val regReadResults = WireDefault(rs.bits.regReadResults) - - regReadResults.lazyZip(rs.bits.regReadResults).lazyZip(rs.bits.decodePort.decode.info.gprReadPorts).foreach { - case (setRegData, elemData, decodeRead) => - val mux = Module(new MultiMux1(pipelineNum + 1, UInt(Width.Reg.data), zeroWord)) - mux.io.inputs.zip(io.wakeUpPorts).foreach { - case (input, wakeUp) => - input.valid := wakeUp.en && - // wakeUp.addr === decodeRead.addr && - wakeUp.robId(Param.Width.Rob._id - 1, 0) === elemData.bits(Param.Width.Rob._id - 1, 0) - input.bits := wakeUp.data - } - when(!elemData.valid && mux.io.output.valid) { - setRegData.valid := true.B - setRegData.bits := mux.io.output.bits - } - - } - - val deqEn = regReadResults.map(_.valid).reduce(_ && _) - out.valid := rs.valid && deqEn - rs.ready := out.ready && deqEn - out.bits.exeOp := rs.bits.decodePort.decode.info.exeOp - out.bits.exeSel := rs.bits.decodePort.decode.info.exeSel - out.bits.gprWritePort := rs.bits.decodePort.decode.info.gprWritePort - out.bits.instInfo := rs.bits.decodePort.instInfo - out.bits.jumpBranchAddr := rs.bits.decodePort.decode.info.jumpBranchAddr - out.bits.leftOperand := regReadResults(0).bits - out.bits.rightOperand := Mux( - rs.bits.decodePort.decode.info.isHasImm, - rs.bits.decodePort.decode.info.imm, - regReadResults(1).bits - ) - } - - if (Param.usePmu) { - val pmuInfos = io.pmu_dispatchInfos.get - pmuInfos.lazyZip(rss).lazyZip(Seq(io.dequeuePorts.mainExePort) ++ io.dequeuePorts.simpleExePorts).foreach { - case (pmu, rs, out) => - pmu.isIssueInst := out.valid && out.ready && !io.isBackendFlush - pmu.bubbleFromFrontend := !rs.io.dequeuePorts.head.valid && !io.isBackendFlush && !isBlockDequeueReg - pmu.bubbleFromBackend := out.valid && !out.ready && !io.isBackendFlush - pmu.bubbleFromDataDependence := rs.io.dequeuePorts.head.valid && !out.valid && !io.isBackendFlush - } - } -} From bbad257240e634df12178eae68f11e9b7e9da95b Mon Sep 17 00:00:00 2001 From: Chrisqcwx <92083012+Chrisqcwx@users.noreply.github.com> Date: Fri, 11 Aug 2023 00:02:29 +0800 Subject: [PATCH 09/16] refactor branch in exe (#312) * refactor: some logic for branch in exe calc early * refactor branch in exe * refactor : change length of issue queue * Revert "refactor : change length of issue queue" This reverts commit 16e3d19960e131444c99dbc34d5c8c52b1bc84ed. --- src/src/SimpleCoreCpuTop.scala | 1 - .../complex}/execution/Alu.scala | 4 +- .../complex/execution/ExePassWbStage.scala | 2 +- src/src/pipeline/simple/Alu.scala | 200 ++++++++++ src/src/pipeline/simple/MainExeStage.scala | 24 +- src/src/pipeline/simple/SimpleExeStage.scala | 2 +- .../bundles/MainExeBranchInfoBundle.scala | 11 +- src/src/pipeline/simple/id/IssueQueue.scala | 15 +- src/src/pipeline/simple/id/IssueStage.scala | 352 ------------------ 9 files changed, 239 insertions(+), 372 deletions(-) rename src/src/{ => pipeline/complex}/execution/Alu.scala (98%) create mode 100644 src/src/pipeline/simple/Alu.scala delete mode 100644 src/src/pipeline/simple/id/IssueStage.scala diff --git a/src/src/SimpleCoreCpuTop.scala b/src/src/SimpleCoreCpuTop.scala index 742922d5..ed57d014 100644 --- a/src/src/SimpleCoreCpuTop.scala +++ b/src/src/SimpleCoreCpuTop.scala @@ -1,5 +1,4 @@ import pipeline.simple.MainExeStage -import pipeline.simple.id.IssueStage import axi.Axi3x1Crossbar import axi.bundles.AxiMasterInterface import chisel3._ diff --git a/src/src/execution/Alu.scala b/src/src/pipeline/complex/execution/Alu.scala similarity index 98% rename from src/src/execution/Alu.scala rename to src/src/pipeline/complex/execution/Alu.scala index 8bdb54c7..1a6235be 100644 --- a/src/src/execution/Alu.scala +++ b/src/src/pipeline/complex/execution/Alu.scala @@ -1,4 +1,4 @@ -package execution +package pipeline.complex.execution import chisel3._ import chisel3.util._ @@ -6,6 +6,8 @@ import execution.bundles.{AluInstNdPort, AluResultNdPort} import pipeline.complex.execution.bundles.JumpBranchInfoNdPort import spec.ExeInst.Op import spec._ +import execution.Mul +import execution.Div class Alu extends Module { val io = IO(new Bundle { diff --git a/src/src/pipeline/complex/execution/ExePassWbStage.scala b/src/src/pipeline/complex/execution/ExePassWbStage.scala index cb70dc09..e2fddbc8 100644 --- a/src/src/pipeline/complex/execution/ExePassWbStage.scala +++ b/src/src/pipeline/complex/execution/ExePassWbStage.scala @@ -7,7 +7,7 @@ import common.bundles._ import control.bundles.{CsrReadPort, CsrWriteNdPort, StableCounterReadPort} import control.csrBundles.{EraBundle, LlbctlBundle} import control.enums.ExceptionPos -import execution.Alu +import pipeline.complex.execution.Alu import frontend.bundles.ExeFtqPort import pipeline.common.bundles.RobQueryPcPort import pipeline.complex.bundles.InstInfoNdPort diff --git a/src/src/pipeline/simple/Alu.scala b/src/src/pipeline/simple/Alu.scala new file mode 100644 index 00000000..cb647bc5 --- /dev/null +++ b/src/src/pipeline/simple/Alu.scala @@ -0,0 +1,200 @@ +package pipeline.simple.execution + +import chisel3._ +import chisel3.util._ +import execution.bundles.{AluInstNdPort, AluResultNdPort} +import pipeline.complex.execution.bundles.JumpBranchInfoNdPort +import spec.ExeInst.Op +import spec._ +import execution.Mul +import execution.Div + +class Alu extends Module { + val io = IO(new Bundle { + val inputValid = Input(Bool()) + val aluInst = Input(new AluInstNdPort) + + val outputValid = Output(Bool()) + val result = Output(new AluResultNdPort) + + val isFlush = Input(Bool()) + }) + + io.outputValid := true.B + io.result := DontCare + + def lop = io.aluInst.leftOperand + + def rop = io.aluInst.rightOperand + + /** Result definition + */ + + val logic = io.result.logic + + val shift = io.result.shift + + val jumpBranchInfo = io.result.jumpBranchInfo + + // computed with one cycle + val arithmetic = io.result.arithmetic + + // Logic computation + + switch(io.aluInst.op) { + is(Op.nor) { + logic := ~(lop | rop) + } + is(Op.and) { + logic := lop & rop + } + is(Op.or) { + logic := lop | rop + } + is(Op.xor) { + logic := lop ^ rop + } + } + + // shift computation + + switch(io.aluInst.op) { + is(Op.sll) { + shift := lop << rop(4, 0) + } + is(Op.srl) { + shift := lop >> rop(4, 0) + } + is(Op.sra) { + shift := (lop.asSInt >> rop(4, 0)).asUInt + } + } + + // jump and branch computation + + switch(io.aluInst.op) { + is(Op.b, Op.bl) { + jumpBranchInfo.en := true.B + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.jirl) { + jumpBranchInfo.en := true.B + // jumpBranchInfo.pcAddr := lop + io.aluInst.jumpBranchAddr + } + is(Op.beq) { + jumpBranchInfo.en := lop === rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bne) { + jumpBranchInfo.en := lop =/= rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.blt) { + jumpBranchInfo.en := lop.asSInt < rop.asSInt + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bge) { + jumpBranchInfo.en := lop.asSInt >= rop.asSInt + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bltu) { + jumpBranchInfo.en := lop < rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + is(Op.bgeu) { + jumpBranchInfo.en := lop >= rop + // jumpBranchInfo.pcAddr := io.aluInst.jumpBranchAddr + } + } + + // arithmetic computation + + // mul + + val mulStage = Module(new Mul) + + val useSignedMul = + VecInit( + ExeInst.Op.mul, + ExeInst.Op.mulh + ).contains(io.aluInst.op) + + val useUnsignedMul = io.aluInst.op === ExeInst.Op.mulhu + + val useMul = WireDefault(useSignedMul || useUnsignedMul) + + val mulStart = useMul + + mulStage.io.isFlush := io.isFlush + mulStage.io.mulInst.valid := mulStart + mulStage.io.mulInst.bits.isSigned := useSignedMul + mulStage.io.mulInst.bits.leftOperand := lop + mulStage.io.mulInst.bits.rightOperand := rop + + val mulResult = mulStage.io.mulResult.bits + + // Div + + val useDiv = WireDefault( + VecInit( + ExeInst.Op.div, + ExeInst.Op.divu, + ExeInst.Op.mod, + ExeInst.Op.modu + ).contains(io.aluInst.op) + ) + + val divStage = Module(new Div) + + val divisorValid = rop =/= 0.U + + val divStart = useDiv && divisorValid + + divStage.io.isFlush := io.isFlush + divStage.io.divInst.valid := divStart + divStage.io.divInst.bits.isSigned := VecInit( + ExeInst.Op.div, + ExeInst.Op.mod + ).contains(io.aluInst.op) + divStage.io.divInst.bits.leftOperand := lop + divStage.io.divInst.bits.rightOperand := rop + + val quotient = divStage.io.divResult.bits.quotient + val remainder = divStage.io.divResult.bits.remainder + + io.outputValid := + !(mulStart && !mulStage.io.mulResult.valid) && ( + !(divStart && !divStage.io.divResult.valid) + ) + + switch(io.aluInst.op) { + is(Op.add) { + arithmetic := (lop.asSInt + rop.asSInt).asUInt + } + is(Op.sub) { + arithmetic := (lop.asSInt - rop.asSInt).asUInt + } + is(Op.slt) { + arithmetic := (lop.asSInt < rop.asSInt).asUInt + } + is(Op.sltu) { + arithmetic := (lop < rop).asUInt + } + is(Op.mul) { + arithmetic := mulResult(wordLength - 1, 0) + } + is(Op.mulh, Op.mulhu) { + arithmetic := mulResult(doubleWordLength - 1, wordLength) + } + is(Op.div, Op.divu) { + arithmetic := divStage.io.divResult.bits.quotient + } + is(Op.mod, Op.modu) { + arithmetic := divStage.io.divResult.bits.remainder + } + } + + when(io.isFlush) { + io.outputValid := false.B + } +} diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 13720faa..2d6efc6e 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -7,7 +7,7 @@ import common.BaseStage import common.bundles._ import control.bundles._ import control.csrBundles._ -import execution.Alu +import pipeline.simple.execution.Alu import frontend.bundles._ import pipeline.common.bundles.{CacheMaintenanceInstNdPort, RobQueryPcPort} import pipeline.simple.bundles.InstInfoNdPort @@ -308,7 +308,7 @@ class MainExeStage isDbarBlockingReg := false.B } - val fallThroughPc = selectedIn.branchInfo.pc + 4.U + val fallThroughPc = selectedIn.branchInfo.fallThroughPc switch(selectedIn.exeSel) { is(Sel.logic) { @@ -427,12 +427,16 @@ class MainExeStage val branchTargetMispredict = ( jumpBranchInfo.en && inFtqInfo.predictBranch && - jumpBranchInfo.pcAddr =/= ftqQueryPc + Mux( + selectedIn.exeOp === ExeInst.Op.jirl, + selectedIn.leftOperand =/= selectedIn.branchInfo.predictSubImm, + !selectedIn.branchInfo.immPredictCorrect + ) ) || ( !jumpBranchInfo.en && !inFtqInfo.predictBranch && inFtqInfo.isLastInBlock && - fallThroughPc =/= ftqQueryPc + !selectedIn.branchInfo.fallThroughPredictCorrect ) // is branch @@ -454,9 +458,15 @@ class MainExeStage branchSetPort.en := isRedirect && !isBlocking branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId + val jumpAddr = Mux( + selectedIn.exeOp === ExeInst.Op.jirl, + selectedIn.leftOperand + selectedIn.jumpBranchAddr, + selectedIn.jumpBranchAddr + ) + branchSetPort.pcAddr := Mux( jumpBranchInfo.en, - jumpBranchInfo.pcAddr, + jumpAddr, fallThroughPc ) @@ -471,7 +481,7 @@ class MainExeStage (RegNext(jumpBranchInfo.en, false.B) && !RegNext(inFtqInfo.isLastInBlock, false.B)) || (RegNext(!isBranchInst, false.B) && RegNext(inFtqInfo.predictBranch, false.B)) feedbackFtq.commitBundle.ftqUpdateMetaId := RegNext(inFtqInfo.ftqId, 0.U) - feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpBranchInfo.pcAddr, 0.U) + feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpAddr, 0.U) feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) feedbackFtq.fixGhrBundle.isExeFixValid := RegNext( @@ -489,7 +499,7 @@ class MainExeStage feedbackFtq.commitBundle.ftqMetaUpdateFtbDirty := branchTargetMispredict || (jumpBranchInfo.en && !inFtqInfo.isLastInBlock) || (!isBranchInst && inFtqInfo.predictBranch) feedbackFtq.commitBundle.ftqUpdateMetaId := inFtqInfo.ftqId - feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := jumpBranchInfo.pcAddr + feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := jumpAddr feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := fallThroughPc feedbackFtq.fixGhrBundle.isExeFixValid := branchDirectionMispredict && !isBlocking && isBranchInst diff --git a/src/src/pipeline/simple/SimpleExeStage.scala b/src/src/pipeline/simple/SimpleExeStage.scala index bffcf54b..125978ee 100644 --- a/src/src/pipeline/simple/SimpleExeStage.scala +++ b/src/src/pipeline/simple/SimpleExeStage.scala @@ -4,7 +4,7 @@ import chisel3._ import chisel3.util._ import spec.ExeInst.Sel import common.BaseStage -import execution.Alu +import pipeline.simple.execution.Alu import pipeline.simple.ExeNdPort import pipeline.simple.bundles.WbNdPort import pipeline.simple.bundles.RegWakeUpNdPort diff --git a/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala b/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala index 383b08ba..0d23571d 100644 --- a/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala +++ b/src/src/pipeline/simple/bundles/MainExeBranchInfoBundle.scala @@ -4,8 +4,11 @@ import chisel3._ import spec._ class MainExeBranchInfoBundle extends Bundle { - val isBranch = Bool() - val branchType = UInt(Param.BPU.BranchType.width.W) - val pc = UInt(Width.Reg.data) - val predictJumpAddr = UInt(Width.Reg.data) + val isBranch = Bool() + val branchType = UInt(Param.BPU.BranchType.width.W) + val fallThroughPc = UInt(Width.Reg.data) + val predictSubImm = UInt(Width.Reg.data) + val predictJumpAddr = UInt(Width.Reg.data) + val fallThroughPredictCorrect = Bool() + val immPredictCorrect = Bool() } diff --git a/src/src/pipeline/simple/id/IssueQueue.scala b/src/src/pipeline/simple/id/IssueQueue.scala index 1def528d..59c97cd9 100644 --- a/src/src/pipeline/simple/id/IssueQueue.scala +++ b/src/src/pipeline/simple/id/IssueQueue.scala @@ -133,11 +133,16 @@ class IssueQueue( } // reservation station enqueue bits - mainRSEnqPort.bits.mainExeBranchInfo.pc := io.ins.head.bits.pc - io.queryPcPort.ftqId := io.ins.head.bits.instInfo.ftqInfo.ftqId + 1.U - mainRSEnqPort.bits.mainExeBranchInfo.predictJumpAddr := io.queryPcPort.pc - mainRSEnqPort.bits.mainExeBranchInfo.isBranch := io.ins.head.bits.decode.info.isBranch - mainRSEnqPort.bits.mainExeBranchInfo.branchType := io.ins.head.bits.decode.info.branchType + val fallThroughPc = io.ins.head.bits.pc + 4.U + val predictPc = io.queryPcPort.pc + mainRSEnqPort.bits.mainExeBranchInfo.fallThroughPc := fallThroughPc + mainRSEnqPort.bits.mainExeBranchInfo.fallThroughPredictCorrect := fallThroughPc === predictPc + mainRSEnqPort.bits.mainExeBranchInfo.immPredictCorrect := io.ins.head.bits.decode.info.jumpBranchAddr === predictPc + mainRSEnqPort.bits.mainExeBranchInfo.predictSubImm := predictPc - io.ins.head.bits.decode.info.jumpBranchAddr + io.queryPcPort.ftqId := io.ins.head.bits.instInfo.ftqInfo.ftqId + 1.U + mainRSEnqPort.bits.mainExeBranchInfo.predictJumpAddr := predictPc + mainRSEnqPort.bits.mainExeBranchInfo.isBranch := io.ins.head.bits.decode.info.isBranch + mainRSEnqPort.bits.mainExeBranchInfo.branchType := io.ins.head.bits.decode.info.branchType rsEnqPorts.lazyZip(io.ins).lazyZip(io.regReadPorts).zipWithIndex.foreach { case ((rs, in, readRes), index) => diff --git a/src/src/pipeline/simple/id/IssueStage.scala b/src/src/pipeline/simple/id/IssueStage.scala deleted file mode 100644 index f4c19692..00000000 --- a/src/src/pipeline/simple/id/IssueStage.scala +++ /dev/null @@ -1,352 +0,0 @@ -package pipeline.simple.id - -import chisel3._ -import chisel3.util._ -import common.DistributedQueue -import common.bundles.BackendRedirectPcNdPort -import control.enums.ExceptionPos -import pipeline.common.bundles.{FetchInstInfoBundle, InstQueueEnqNdPort, PcInstBundle} -import pipeline.simple.decode._ -import pipeline.simple.decode.bundles._ -import spec._ -import frontend.bundles.QueryPcBundle -import pipeline.simple.bundles._ -import common.MultiQueue -import pipeline.simple.id.FetchInstDecodeNdPort -import pipeline.simple.MainExeNdPort -import pipeline.simple.ExeNdPort -import utils.MultiMux1 -import pipeline.simple.pmu.bundles.PmuDispatchInfoBundle - -// assert: enqueuePorts总是最低的几位有效 -class IssueStage( - issueNum: Int = Param.issueInstInfoMaxNum, - pipelineNum: Int = Param.pipelineNum) - extends Module { - val io = IO(new Bundle { - val isFrontendFlush = Input(Bool()) - val isBackendFlush = Input(Bool()) - - val enqueuePorts = Vec( - issueNum, - Flipped(Decoupled(new FetchInstInfoBundle)) - ) - - // `InstQueue` -> `IssueStage` - val dequeuePorts = new Bundle { - val mainExePort = Decoupled(new MainExeNdPort) - val simpleExePorts = Vec(pipelineNum - 1, Decoupled(new ExeNdPort)) - } - - val idleBlocking = Input(Bool()) - val hasInterrupt = Input(Bool()) - - val robIdRequests = Vec(issueNum, Flipped(new RobRequestPort)) - - val queryPcPort = Flipped(new QueryPcBundle) - - val regReadPorts = Vec(Param.issueInstInfoMaxNum, Vec(Param.regFileReadNum, Flipped(new RegReadPort))) - val occupyPorts = Output(Vec(Param.issueInstInfoMaxNum, new RegOccupyNdPort)) - - val wakeUpPorts = Input(Vec(pipelineNum + 1, new RegWakeUpNdPort)) - - val plv = Input(UInt(2.W)) - - val pmu_dispatchInfos = Option.when(Param.usePmu)(Output(Vec(Param.issueInstInfoMaxNum, new PmuDispatchInfoBundle))) - }) - require(issueNum == pipelineNum) - - private val rsLength = 2 - - val isIdle = RegInit(false.B) - when(io.hasInterrupt) { - isIdle := false.B - }.elsewhen(io.idleBlocking) { - isIdle := true.B - } - - // Decode - val decodeInstInfos = VecInit(io.enqueuePorts.map(_.bits)) - - // Select a decoder - - val decoders = Seq.fill(issueNum)(Module(new DecodeUnit)) - - decoders.zip(decodeInstInfos).foreach { - case (decoder, decodeInstInfo) => - decoder.io.in := decodeInstInfo - } - - val selectedDecoders = decoders.map(_.io.out) - - val mainRS = Module( - new MultiQueue(rsLength, 1, 1, new MainRSBundle, 0.U.asTypeOf(new MainRSBundle), writeFirst = false) - ) - val simpleRSs = Seq.fill(pipelineNum - 1)( - Module( - new MultiQueue(rsLength, 1, 1, new RSBundle, 0.U.asTypeOf(new RSBundle), writeFirst = false) - ) - ) - - val mainRSEnqPort = mainRS.io.enqueuePorts.head - val simpleRSEnqPorts = simpleRSs.map(_.io.enqueuePorts.head) - - mainRS.io.setPorts.zip(mainRS.io.elems).foreach { - case (set, elem) => - set.bits := elem - set.valid := true.B - } - mainRS.io.isFlush := io.isBackendFlush - simpleRSs.zip(simpleRSEnqPorts).foreach { - case (rs, enq) => - rs.io.setPorts.zip(rs.io.elems).foreach { - case (set, elem) => - set.bits := elem - set.valid := true.B - } - rs.io.isFlush := io.isBackendFlush - } - - val rsEnqPorts = Seq(mainRSEnqPort) ++ simpleRSEnqPorts - val rss = Seq(mainRS) ++ simpleRSs - - // reg read - io.regReadPorts.zip(rsEnqPorts).foreach { - case (readPorts, rsEnqPort) => - readPorts.zip(rsEnqPort.bits.decodePort.decode.info.gprReadPorts).foreach { - case (dst, src) => - dst.addr := src.addr - } - } - - // occupy - io.occupyPorts.lazyZip(rsEnqPorts).lazyZip(io.robIdRequests).foreach { - case (occupy, enq, robIdReq) => - occupy.en := enq.valid && enq.ready && enq.bits.decodePort.decode.info.gprWritePort.en - occupy.addr := enq.bits.decodePort.decode.info.gprWritePort.addr - occupy.robId := robIdReq.result.bits - } - - val isBlockDequeueReg = RegInit(false.B) - when(io.isBackendFlush) { - isBlockDequeueReg := false.B - }.elsewhen( - io.isFrontendFlush - || ( - rsEnqPorts.map { port => - port.valid && port.ready && ( - port.bits.decodePort.decode.info.needRefetch || - port.bits.decodePort.instInfo.exceptionPos =/= ExceptionPos.none - ) - }.reduce(_ || _) - ) - ) { - isBlockDequeueReg := true.B - } - - // rob id request - - rsEnqPorts.lazyZip(io.enqueuePorts).lazyZip(io.robIdRequests).zipWithIndex.foreach { - case ((dst, src, robIdReq), idx) => - src.ready := dst.ready - dst.valid := src.valid - - robIdReq.request.valid := src.valid && src.ready - robIdReq.request.bits.pcAddr := src.bits.pcAddr - robIdReq.request.bits.inst := src.bits.inst - - // block - when( - isBlockDequeueReg || - isIdle || - // io.isFrontendFlush || - !robIdReq.result.valid - ) { - dst.valid := false.B - src.ready := false.B - } - - rsEnqPorts.take(idx).foreach { prev => - val prevGprWrite = prev.bits.decodePort.decode.info.gprWritePort - - // data dependence - // dst.bits.decodePort.decode.info.gprReadPorts.foreach { r => - // when(r.en && prevGprWrite.en && r.addr === prevGprWrite.addr) { - // dst.valid := false.B - // src.ready := false.B - // } - // } - - // issue in order - when(!(prev.ready && prev.valid)) { - dst.valid := false.B - src.ready := false.B - } - } - - // should issue in main - if (idx != 0) { - when(dst.bits.decodePort.decode.info.isIssueMainPipeline) { - dst.valid := false.B - src.ready := false.B - } - } - } - - // reservation station enqueue bits - mainRSEnqPort.bits.mainExeBranchInfo.pc := decodeInstInfos.head.pcAddr - io.queryPcPort.ftqId := decodeInstInfos.head.ftqInfo.ftqId + 1.U - mainRSEnqPort.bits.mainExeBranchInfo.predictJumpAddr := io.queryPcPort.pc - mainRSEnqPort.bits.mainExeBranchInfo.isBranch := decoders.head.io.out.info.isBranch - mainRSEnqPort.bits.mainExeBranchInfo.branchType := decoders.head.io.out.info.branchType - - rsEnqPorts - .lazyZip(selectedDecoders) - .lazyZip(decodeInstInfos) - .zipWithIndex - .foreach { - case ( - ( - rs, - selectedDecoder, - decodeInstInfo - ), - index - ) => - val robIdReq = io.robIdRequests(index) - - val outReadResults = io.regReadPorts(index) - - rs.bits.regReadResults.lazyZip(outReadResults).lazyZip(selectedDecoder.info.gprReadPorts).foreach { - case (dst, readRes, decodeRead) => - dst.valid := !(decodeRead.en && !readRes.data.valid) - dst.bits := readRes.data.bits - - // data dependence - selectedDecoders.take(index).zipWithIndex.foreach { - case (prev, prevIdx) => - when(decodeRead.en && prev.info.gprWritePort.en && prev.info.gprWritePort.addr === decodeRead.addr) { - dst.valid := false.B - dst.bits := io.robIdRequests(prevIdx).result.bits - } - } - } - - val outInstInfo = rs.bits.decodePort.instInfo - - rs.bits.decodePort.decode := selectedDecoder - - outInstInfo := InstInfoNdPort.default - - val isMatched = selectedDecoder.isMatched - outInstInfo.isValid := true.B - outInstInfo.isCsrWrite := selectedDecoder.info.csrWriteEn - outInstInfo.exeOp := selectedDecoder.info.exeOp - outInstInfo.isTlb := selectedDecoder.info.isTlb - outInstInfo.needRefetch := selectedDecoder.info.needRefetch - outInstInfo.ftqInfo := decodeInstInfo.ftqInfo - - outInstInfo.forbidParallelCommit := selectedDecoder.info.needRefetch - - outInstInfo.exceptionPos := ExceptionPos.none - outInstInfo.exceptionRecord := DontCare - when(io.hasInterrupt) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := Csr.ExceptionIndex.int - }.elsewhen(decodeInstInfo.exceptionValid) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := decodeInstInfo.exception - }.elsewhen(!isMatched) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := Csr.ExceptionIndex.ine - }.elsewhen( - io.plv === 3.U && - selectedDecoder.info.isPrivilege - ) { - outInstInfo.exceptionPos := ExceptionPos.frontend - outInstInfo.exceptionRecord := Csr.ExceptionIndex.ipe - } - - outInstInfo.robId := robIdReq.result.bits - - if (Param.isDiffTest) { - outInstInfo.pc.get := decodeInstInfo.pcAddr - outInstInfo.inst.get := decodeInstInfo.inst - } - - } - - // wake up - rss.foreach { rs => - rs.io.setPorts.zip(rs.io.elems).foreach { - case (set, elem) => - set.bits.regReadResults.lazyZip(elem.regReadResults).lazyZip(elem.decodePort.decode.info.gprReadPorts).foreach { - case (setRegData, elemData, decodeRead) => - setRegData := elemData - - val mux = Module(new MultiMux1(pipelineNum + 1, UInt(Width.Reg.data), zeroWord)) - mux.io.inputs.zip(io.wakeUpPorts).foreach { - case (input, wakeUp) => - input.valid := wakeUp.en && - wakeUp.addr === decodeRead.addr && - wakeUp.robId(Param.Width.Rob._id - 1, 0) === elemData.bits(Param.Width.Rob._id - 1, 0) - input.bits := wakeUp.data - } - when(!elemData.valid && mux.io.output.valid) { - setRegData.valid := true.B - setRegData.bits := mux.io.output.bits - } - } - } - } - - // output - io.dequeuePorts.mainExePort.bits.branchInfo := mainRS.io.dequeuePorts.head.bits.mainExeBranchInfo - (Seq(io.dequeuePorts.mainExePort) ++ io.dequeuePorts.simpleExePorts).zip(rss.map(_.io.dequeuePorts.head)).foreach { - case (out, rs) => - val regReadResults = WireDefault(rs.bits.regReadResults) - - regReadResults.lazyZip(rs.bits.regReadResults).lazyZip(rs.bits.decodePort.decode.info.gprReadPorts).foreach { - case (setRegData, elemData, decodeRead) => - val mux = Module(new MultiMux1(pipelineNum + 1, UInt(Width.Reg.data), zeroWord)) - mux.io.inputs.zip(io.wakeUpPorts).foreach { - case (input, wakeUp) => - input.valid := wakeUp.en && - // wakeUp.addr === decodeRead.addr && - wakeUp.robId(Param.Width.Rob._id - 1, 0) === elemData.bits(Param.Width.Rob._id - 1, 0) - input.bits := wakeUp.data - } - when(!elemData.valid && mux.io.output.valid) { - setRegData.valid := true.B - setRegData.bits := mux.io.output.bits - } - - } - - val deqEn = regReadResults.map(_.valid).reduce(_ && _) - out.valid := rs.valid && deqEn - rs.ready := out.ready && deqEn - out.bits.exeOp := rs.bits.decodePort.decode.info.exeOp - out.bits.exeSel := rs.bits.decodePort.decode.info.exeSel - out.bits.gprWritePort := rs.bits.decodePort.decode.info.gprWritePort - out.bits.instInfo := rs.bits.decodePort.instInfo - out.bits.jumpBranchAddr := rs.bits.decodePort.decode.info.jumpBranchAddr - out.bits.leftOperand := regReadResults(0).bits - out.bits.rightOperand := Mux( - rs.bits.decodePort.decode.info.isHasImm, - rs.bits.decodePort.decode.info.imm, - regReadResults(1).bits - ) - } - - if (Param.usePmu) { - val pmuInfos = io.pmu_dispatchInfos.get - pmuInfos.lazyZip(rss).lazyZip(Seq(io.dequeuePorts.mainExePort) ++ io.dequeuePorts.simpleExePorts).foreach { - case (pmu, rs, out) => - pmu.isIssueInst := out.valid && out.ready && !io.isBackendFlush - pmu.bubbleFromFrontend := !rs.io.dequeuePorts.head.valid && !io.isBackendFlush && !isBlockDequeueReg - pmu.bubbleFromBackend := out.valid && !out.ready && !io.isBackendFlush - pmu.bubbleFromDataDependence := rs.io.dequeuePorts.head.valid && !out.valid && !io.isBackendFlush - } - } -} From 1c32bf1035512c0a6f835c24369b613aaa868e69 Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Fri, 11 Aug 2023 02:40:49 +0800 Subject: [PATCH 10/16] feat:implement mux checkPoint ghr --- src/src/frontend/bpu/TagePredictor.scala | 72 ++++++++++--------- .../bpu/components/Bundles/TageMetaPort.scala | 2 +- src/src/spec/Param.scala | 5 +- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 3c211a94..8bc653d1 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -138,22 +138,23 @@ class TagePredictor( // Global History Register speculative update logic //////////////////////////////////////////////////////////////////////////////////////////// // predict queue - val specPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) - val nextSpecPtr = Wire(UInt(Param.BPU.ftqPtrWidth.W)) - val commitPtr = RegInit(0.U(Param.BPU.ftqPtrWidth.W)) - val checkPtr = WireDefault(0.U(Param.BPU.ftqPtrWidth.W)) - val checkDepth = Wire(UInt(Param.BPU.ftqPtrWidth.W)) + val specPtr = RegInit(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W)) + val nextSpecPtr = Wire(UInt(Param.BPU.TagePredictor.ghrPtrWidth.W)) + val commitPtr = RegInit(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W)) + val checkPtr = WireDefault(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W)) + val checkDepth = Wire(UInt(Param.BPU.TagePredictor.ghrPtrWidth.W)) checkPtr := io.ghrUpdateNdBundle.tageGhrInfo.checkPtr checkDepth := checkPtr - commitPtr // calculate the location of the correct old history // Global History Register - val globalHistoryReg = RegInit(0.U(ghrDepth.W)) - val nextGlobalHistory = Wire(UInt(ghrDepth.W)) + val speculativeHistoryReg = RegInit(VecInit(Seq.fill(ghrDepth)(false.B))) + val nextGlobalHistory = Wire(Vec(ghrDepth, Bool())) + val shiftedGlobalHistory = Wire(UInt(ghrDepth.W)) // default nextGhr keep value; ghr = RegNext(nextGhr) (assign in the next clock) - nextGlobalHistory := globalHistoryReg - globalHistoryReg := nextGlobalHistory - nextSpecPtr := specPtr - specPtr := nextSpecPtr + nextGlobalHistory := speculativeHistoryReg + speculativeHistoryReg := nextGlobalHistory + nextSpecPtr := specPtr + specPtr := nextSpecPtr // signal that indicates how to fix globalHistory Hash value val isFixUpdateCsr = WireDefault(false.B) @@ -177,40 +178,43 @@ class TagePredictor( // 4.spec update when(isUpdateValid) { - commitPtr := commitPtr + 1.U + commitPtr := commitPtr - 1.U } when(io.ghrUpdateNdBundle.fixBundle.isFixGhrValid) { switch(io.ghrUpdateNdBundle.fixBundle.ghrFixType) { is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { - nextGlobalHistory := globalHistoryReg >> checkDepth // recover to the old history - nextSpecPtr := checkPtr - 1.U - isRecoverCsr := true.B + // recover to the old history + nextSpecPtr := checkPtr + 1.U + isRecoverCsr := true.B } is(GhrFixType.exeFixDirection) { - nextGlobalHistory := Cat( - globalHistoryReg >> checkDepth, - io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken - ) // fix error predict - nextSpecPtr := checkPtr - isFixDirectionCsr := true.B + // fix error predict + nextSpecPtr := checkPtr + nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken + isFixDirectionCsr := true.B } is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { - nextGlobalHistory := Cat( - globalHistoryReg >> checkDepth, - true.B - ) // update the branch that has not been predicted - nextSpecPtr := checkPtr + 1.U - isFixUpdateCsr := true.B + // update the branch that has not been predicted + nextSpecPtr := checkPtr - 1.U + nextGlobalHistory(nextSpecPtr) := true.B + isFixUpdateCsr := true.B } } }.elsewhen(io.ghrUpdateNdBundle.bpuSpecValid) { - nextGlobalHistory := Cat(globalHistoryReg(ghrDepth - 2, 0), io.ghrUpdateNdBundle.bpuSpecTaken) - nextSpecPtr := specPtr + 1.U + nextSpecPtr := specPtr - 1.U + nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.bpuSpecTaken + } + shiftedGlobalHistory := nextGlobalHistory.asUInt >> nextSpecPtr + // TODO use the correct Cat history +// shiftedGlobalHistory := Cat( +// nextGlobalHistory.asUInt(nextSpecPtr, 0), +// nextGlobalHistory.asUInt(Param.BPU.TagePredictor.ghrLength, nextSpecPtr) +// ) + + val ghr = dontTouch(RegInit((0.U(ghrDepth.W)))) + when(isUpdateValid) { + ghr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) } - -// when(isUpdateValid) { -// nextGhr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) -// } // output io.tageQueryMeta.tageGhrInfo.checkPtr := nextSpecPtr @@ -241,7 +245,7 @@ class TagePredictor( ) // Query taggedPreditor.io.isGlobalHistoryUpdate := io.ghrUpdateNdBundle.bpuSpecValid - taggedPreditor.io.globalHistory := nextGlobalHistory(historyLengths(providerId + 1) - 1, 0) + taggedPreditor.io.globalHistory := shiftedGlobalHistory(historyLengths(providerId + 1) - 1, 0) taggedPreditor.io.pc := io.pc tagUsefulbits(providerId) := taggedPreditor.io.usefulBits tagCtrbits(providerId) := taggedPreditor.io.ctrBits diff --git a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala index fc17a326..43dd0ce8 100644 --- a/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala +++ b/src/src/frontend/bpu/components/Bundles/TageMetaPort.scala @@ -9,7 +9,7 @@ class TageGhrInfo( tagComponentTagWidth: Int = Param.BPU.TagePredictor.tagComponentTagWidth, phtAddrWidth: Int = log2Ceil(Param.BPU.TagePredictor.componentTableDepth(1))) extends Bundle { - val checkPtr = UInt(Param.BPU.ftqPtrWidth.W) + val checkPtr = UInt(Param.BPU.TagePredictor.ghrPtrWidth.W) val tagGhtHashs = Vec(tagComponentNum, UInt(phtAddrWidth.W)) val tagTagHashCsr1s = Vec(tagComponentNum, UInt(tagComponentTagWidth.W)) val tagTagHashCsr2s = Vec(tagComponentNum, UInt((tagComponentTagWidth - 1).W)) diff --git a/src/src/spec/Param.scala b/src/src/spec/Param.scala index 7a555b16..710b8740 100644 --- a/src/src/spec/Param.scala +++ b/src/src/spec/Param.scala @@ -186,13 +186,14 @@ object Param { // predictor num = tagComponentNum + 1 (BasePredictor) val tagComponentTagWidth = 12 val tagComponentNum = 4 - val componentHistoryLength = Seq(0, 11, 23, 53, 131) + val componentHistoryLength = Seq(0, 11, 23, 53, 112) val componentTableDepth = Seq(8192, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024) val componentCtrWidth = Seq(2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) val componentUsefulWidth = Seq(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) // tage paper suggest 2-bits useful, but in order to save source, we use 1 bit(won't decrease ipc) - val ghrLength = componentHistoryLength(tagComponentNum) + ftqSize + val ghrLength = componentHistoryLength(tagComponentNum) + ftqSize + val ghrPtrWidth = log2Ceil(ghrLength) } object FTB { From e1678f288d3f283b088dbef40252ac719c0dceb5 Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Fri, 11 Aug 2023 03:22:42 +0800 Subject: [PATCH 11/16] fix:shift history lose infomation --- src/src/frontend/bpu/TagePredictor.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index 8bc653d1..d372d4d4 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -204,11 +204,13 @@ class TagePredictor( nextSpecPtr := specPtr - 1.U nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.bpuSpecTaken } - shiftedGlobalHistory := nextGlobalHistory.asUInt >> nextSpecPtr +// val shiftHistoryVec = Wire(Vec(ghrDepth, Bool())) + + shiftedGlobalHistory := (nextGlobalHistory.asUInt >> nextSpecPtr).asUInt | (nextGlobalHistory.asUInt << (Param.BPU.TagePredictor.ghrLength.U - nextSpecPtr)).asUInt // TODO use the correct Cat history // shiftedGlobalHistory := Cat( // nextGlobalHistory.asUInt(nextSpecPtr, 0), -// nextGlobalHistory.asUInt(Param.BPU.TagePredictor.ghrLength, nextSpecPtr) +// nextGlobalHistory.asUInt(Param.BPU.TagePredictor.ghrLength-1, nextSpecPtr) // ) val ghr = dontTouch(RegInit((0.U(ghrDepth.W)))) From f4b1988c80e49830bdcf154c783601f15159302f Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Fri, 11 Aug 2023 19:24:52 +0800 Subject: [PATCH 12/16] fix:casHash --- src/src/frontend/bpu/TagePredictor.scala | 28 +++++++++++-------- .../bpu/components/TaggedPreditor.scala | 16 +++++------ src/src/frontend/bpu/utils/CsrHash.scala | 24 ++++++---------- src/src/spec/Param.scala | 2 +- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index d372d4d4..e0ad1eff 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -140,7 +140,7 @@ class TagePredictor( // predict queue val specPtr = RegInit(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W)) val nextSpecPtr = Wire(UInt(Param.BPU.TagePredictor.ghrPtrWidth.W)) - val commitPtr = RegInit(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W)) + val commitPtr = dontTouch(RegInit(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W))) val checkPtr = WireDefault(0.U(Param.BPU.TagePredictor.ghrPtrWidth.W)) val checkDepth = Wire(UInt(Param.BPU.TagePredictor.ghrPtrWidth.W)) checkPtr := io.ghrUpdateNdBundle.tageGhrInfo.checkPtr @@ -149,7 +149,7 @@ class TagePredictor( // Global History Register val speculativeHistoryReg = RegInit(VecInit(Seq.fill(ghrDepth)(false.B))) val nextGlobalHistory = Wire(Vec(ghrDepth, Bool())) - val shiftedGlobalHistory = Wire(UInt(ghrDepth.W)) + val shiftedGlobalHistory = dontTouch(Wire(UInt(ghrDepth.W))) // default nextGhr keep value; ghr = RegNext(nextGhr) (assign in the next clock) nextGlobalHistory := speculativeHistoryReg speculativeHistoryReg := nextGlobalHistory @@ -157,8 +157,8 @@ class TagePredictor( specPtr := nextSpecPtr // signal that indicates how to fix globalHistory Hash value - val isFixUpdateCsr = WireDefault(false.B) - val isFixDirectionCsr = WireDefault(false.B) + val isExeFixCsr = WireDefault(false.B) + val isPredecodeFixCsr = WireDefault(false.B) val isRecoverCsr = WireDefault(false.B) // val originHash = Input(UInt(outputLength.W)) @@ -191,22 +191,28 @@ class TagePredictor( // fix error predict nextSpecPtr := checkPtr nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken - isFixDirectionCsr := true.B + isExeFixCsr := true.B } - is(GhrFixType.exeUpdateJump, GhrFixType.decodeUpdateJump) { + is(GhrFixType.exeUpdateJump) { // update the branch that has not been predicted nextSpecPtr := checkPtr - 1.U nextGlobalHistory(nextSpecPtr) := true.B - isFixUpdateCsr := true.B + isExeFixCsr := true.B + } + is(GhrFixType.decodeUpdateJump) { + // update the branch that has not been predicted + nextSpecPtr := checkPtr - 1.U + nextGlobalHistory(nextSpecPtr) := true.B + isPredecodeFixCsr := true.B } } }.elsewhen(io.ghrUpdateNdBundle.bpuSpecValid) { nextSpecPtr := specPtr - 1.U nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.bpuSpecTaken } -// val shiftHistoryVec = Wire(Vec(ghrDepth, Bool())) - shiftedGlobalHistory := (nextGlobalHistory.asUInt >> nextSpecPtr).asUInt | (nextGlobalHistory.asUInt << (Param.BPU.TagePredictor.ghrLength.U - nextSpecPtr)).asUInt + shiftedGlobalHistory := Cat(nextGlobalHistory.asUInt, nextGlobalHistory.asUInt) >> nextSpecPtr +// shiftedGlobalHistory := (nextGlobalHistory.asUInt >> nextSpecPtr).asUInt | (nextGlobalHistory.asUInt << (Param.BPU.TagePredictor.ghrLength.U - nextSpecPtr)).asUInt // TODO use the correct Cat history // shiftedGlobalHistory := Cat( // nextGlobalHistory.asUInt(nextSpecPtr, 0), @@ -273,8 +279,8 @@ class TagePredictor( taggedPreditor.io.updateTag := tagUpdateNewTags(providerId) taggedPreditor.io.updateIndex := updateMetaBundle.tagPredictorHitIndexs(providerId) taggedPreditor.io.isRecoverCsr := isRecoverCsr - taggedPreditor.io.isFixUpdateCsr := isFixUpdateCsr - taggedPreditor.io.isFixDirectionCsr := isFixDirectionCsr + taggedPreditor.io.isExeFixCsr := isExeFixCsr + taggedPreditor.io.isPredecodeFixCsr := isPredecodeFixCsr taggedPreditor.io.originGhtHash := updateMetaBundle.tageGhrInfo.tagGhtHashs(providerId) taggedPreditor.io.originTagHashCsr1 := updateMetaBundle.tageGhrInfo.tagTagHashCsr1s(providerId) taggedPreditor.io.originTagHashCsr2 := updateMetaBundle.tageGhrInfo.tagTagHashCsr2s(providerId) diff --git a/src/src/frontend/bpu/components/TaggedPreditor.scala b/src/src/frontend/bpu/components/TaggedPreditor.scala index 1bd912e1..7256634b 100644 --- a/src/src/frontend/bpu/components/TaggedPreditor.scala +++ b/src/src/frontend/bpu/components/TaggedPreditor.scala @@ -67,8 +67,8 @@ class TaggedPreditor( val updateIndex = Input(UInt(log2Ceil(phtDepth).W)) // speculative update hash value - val isFixUpdateCsr = Input(Bool()) - val isFixDirectionCsr = Input(Bool()) + val isExeFixCsr = Input(Bool()) + val isPredecodeFixCsr = Input(Bool()) val isRecoverCsr = Input(Bool()) val originGhtHash = Input(UInt(phtAddrWidth.W)) val originTagHashCsr1 = Input(UInt(phtTagWidth.W)) @@ -182,8 +182,8 @@ class TaggedPreditor( hashedGhtInput := ghtHashCsrHash.io.hash ghtHashCsrHash.io.originHash := io.originGhtHash ghtHashCsrHash.io.isRecoverCsr := io.isRecoverCsr - ghtHashCsrHash.io.isFixUpdateCsr := io.isFixUpdateCsr - ghtHashCsrHash.io.isFixDirectionCsr := io.isFixDirectionCsr + ghtHashCsrHash.io.isExeFixCsr := io.isExeFixCsr + ghtHashCsrHash.io.isPredecodeFixCsr := io.isPredecodeFixCsr io.queryGhtHash := ghtHashCsrHash.io.hash val pcHashCsrHash1 = Module(new CsrHash(ghrLength, phtTagWidth)) @@ -192,8 +192,8 @@ class TaggedPreditor( tagHashCsr1 := pcHashCsrHash1.io.hash pcHashCsrHash1.io.originHash := io.originTagHashCsr1 pcHashCsrHash1.io.isRecoverCsr := io.isRecoverCsr - pcHashCsrHash1.io.isFixUpdateCsr := io.isFixUpdateCsr - pcHashCsrHash1.io.isFixDirectionCsr := io.isFixDirectionCsr + pcHashCsrHash1.io.isExeFixCsr := io.isExeFixCsr + pcHashCsrHash1.io.isPredecodeFixCsr := io.isPredecodeFixCsr io.queryTagHashCsr1 := pcHashCsrHash1.io.hash val pcHashCsrHash2 = Module(new CsrHash(ghrLength, phtTagWidth - 1)) @@ -202,8 +202,8 @@ class TaggedPreditor( tagHashCsr2 := pcHashCsrHash2.io.hash pcHashCsrHash2.io.originHash := io.originTagHashCsr2 pcHashCsrHash2.io.isRecoverCsr := io.isRecoverCsr - pcHashCsrHash2.io.isFixUpdateCsr := io.isFixUpdateCsr - pcHashCsrHash2.io.isFixDirectionCsr := io.isFixDirectionCsr + pcHashCsrHash2.io.isExeFixCsr := io.isExeFixCsr + pcHashCsrHash2.io.isPredecodeFixCsr := io.isPredecodeFixCsr io.queryTagHashCsr2 := pcHashCsrHash2.io.hash val phtRam = Module( diff --git a/src/src/frontend/bpu/utils/CsrHash.scala b/src/src/frontend/bpu/utils/CsrHash.scala index af25a246..bcfaabf3 100644 --- a/src/src/frontend/bpu/utils/CsrHash.scala +++ b/src/src/frontend/bpu/utils/CsrHash.scala @@ -11,8 +11,8 @@ class CsrHash( val dataUpdate = Input(Bool()) val data = Input(UInt(inputLength.W)) val hash = Output(UInt(outputLength.W)) - val isFixUpdateCsr = Input(Bool()) - val isFixDirectionCsr = Input(Bool()) + val isExeFixCsr = Input(Bool()) + val isPredecodeFixCsr = Input(Bool()) val isRecoverCsr = Input(Bool()) val originHash = Input(UInt(outputLength.W)) }) @@ -23,16 +23,7 @@ class CsrHash( val residual = (inputLength - 1) % outputLength // nextCSR := Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) // nextCSR(residual) := nextCSR(residual, residual) ^ io.data(inputLength - 1) - val updateCSR = WireDefault(0.U(outputLength.W)) - updateCSR := Mux( - io.isFixUpdateCsr || io.isFixDirectionCsr, - Cat(io.originHash(outputLength - 2, 0), io.originHash(outputLength - 1) ^ io.data(0)) ^ (io.data( - inputLength - 1 - ) << residual).asUInt, - Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( - inputLength - 1 - ) << residual).asUInt - ) + val keepCSR = WireDefault(0.U(outputLength.W)) keepCSR := Mux(io.isRecoverCsr, io.originHash, csr) @@ -40,7 +31,7 @@ class CsrHash( io.isRecoverCsr, io.originHash, Mux( - io.isFixUpdateCsr || io.isFixDirectionCsr, + io.isExeFixCsr || io.isPredecodeFixCsr, Cat(io.originHash(outputLength - 2, 0), io.originHash(outputLength - 1) ^ io.data(0)) ^ (io.data( inputLength - 1 ) << residual).asUInt, @@ -62,9 +53,10 @@ class CsrHash( // csr // ) - when(io.dataUpdate) { - csr := nextCSR - } +// when(io.dataUpdate) { +// csr := nextCSR +// } + csr := nextCSR io.hash := nextCSR diff --git a/src/src/spec/Param.scala b/src/src/spec/Param.scala index 710b8740..b3d468fb 100644 --- a/src/src/spec/Param.scala +++ b/src/src/spec/Param.scala @@ -20,7 +20,7 @@ object Param { val isFullUncachedPatch = true val isMmioDelay = false || isChiplab || isFullFpga val isNoPrivilege = false || isReleasePackage - val isCacheOnPg = false + val isCacheOnPg = true val isForcedCache = false || isReleasePackage val isForcedUncached = false val isBranchPredict = true From 0513e7353aa7ecd2ea89ff0dc48ff49e6340faca Mon Sep 17 00:00:00 2001 From: Chrisqcwx <3075401625@qq.com> Date: Fri, 11 Aug 2023 19:38:10 +0800 Subject: [PATCH 13/16] commit ftq early when no privilege --- src/src/SimpleCoreCpuTop.scala | 9 ++++++--- src/src/pipeline/simple/MainExeStage.scala | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/src/SimpleCoreCpuTop.scala b/src/src/SimpleCoreCpuTop.scala index ed57d014..bf1ee20f 100644 --- a/src/src/SimpleCoreCpuTop.scala +++ b/src/src/SimpleCoreCpuTop.scala @@ -189,9 +189,12 @@ class SimpleCoreCpuTop extends Module { // TODO: Connect frontend frontend.io.exeFtqPort.queryPcBundle <> issueQueue.io.queryPcPort frontend.io.exeFtqPort.feedBack := mainExeStage.io.peer.get.feedbackFtq - frontend.io.commitFtqTrainPort := addrTransStage.io.peer.get.commitFtqPort - frontend.io.commitFixBranch := false.B - frontend.io.commitFixId := 0.U + val commitFtqPort = + if (isNoPrivilege) mainExeStage.io.peer.get.commitFtqPort + else addrTransStage.io.peer.get.commitFtqPort + frontend.io.commitFtqTrainPort := commitFtqPort + frontend.io.commitFixBranch := false.B + frontend.io.commitFixId := 0.U connectVec(frontend.io.commitBitMask, cu.io.commitBitMask) // Instruction queue diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 8058dbed..75c1e32c 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -77,6 +77,9 @@ class ExePeerPort extends Bundle { // val robQueryPcPort = Flipped(new RobQueryPcPort) val regWakeUpPort = Output(new RegWakeUpNdPort) + + val commitFtqPort = new CommitFtqTrainNdPort + } class MainExeStage @@ -92,6 +95,8 @@ class MainExeStage resultOutReg.bits := out val peer = io.peer.get + peer.commitFtqPort := out.commitFtqPort + // Fallback // ALU module val alu = Module(new Alu) From eba98edd01f4e53dad8a8941ceb6c0f208f75606 Mon Sep 17 00:00:00 2001 From: Chrisqcwx <3075401625@qq.com> Date: Fri, 11 Aug 2023 19:47:36 +0800 Subject: [PATCH 14/16] fix: reg next of commit ftq port --- src/src/pipeline/simple/MainExeStage.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 75c1e32c..0c61b15b 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -95,7 +95,7 @@ class MainExeStage resultOutReg.bits := out val peer = io.peer.get - peer.commitFtqPort := out.commitFtqPort + peer.commitFtqPort := RegNext(out.commitFtqPort) // Fallback // ALU module From 49a2e11ad9de5f1e2b9ce017237c8806e0c4e1ff Mon Sep 17 00:00:00 2001 From: Chrisqcwx <3075401625@qq.com> Date: Fri, 11 Aug 2023 21:24:34 +0800 Subject: [PATCH 15/16] fix: commit ftq after exe --- src/src/pipeline/simple/MainExeStage.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 0c61b15b..43c5f9f9 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -95,7 +95,8 @@ class MainExeStage resultOutReg.bits := out val peer = io.peer.get - peer.commitFtqPort := RegNext(out.commitFtqPort) + peer.commitFtqPort := (if (Param.exeFeedBackFtqDelay) RegNext(RegNext(out.commitFtqPort)) + else RegNext(out.commitFtqPort)) // Fallback // ALU module From c264148c73d385bea55697d0cef17d6dec738b1b Mon Sep 17 00:00:00 2001 From: zhengyujie <3257144507@qq.com> Date: Sat, 12 Aug 2023 14:06:12 +0800 Subject: [PATCH 16/16] feat:param isSpeculativeGlobalHistory --- src/src/frontend/FetchTargetQueue.scala | 12 ++--- src/src/frontend/Frontend.scala | 2 - src/src/frontend/bpu/BPU.scala | 13 +++-- src/src/frontend/bpu/TagePredictor.scala | 34 +++++++++---- src/src/frontend/bpu/utils/CsrHash.scala | 49 ++++++++++--------- src/src/frontend/bundles/FtqBpuMetaPort.scala | 1 + .../frontend/fetch/InstPreDecodeStage.scala | 3 +- .../complex/execution/ExePassWbStage.scala | 5 +- src/src/pipeline/simple/MainExeStage.scala | 13 +++-- src/src/spec/Param.scala | 30 ++++++------ 10 files changed, 91 insertions(+), 71 deletions(-) diff --git a/src/src/frontend/FetchTargetQueue.scala b/src/src/frontend/FetchTargetQueue.scala index 7bd886a5..b0f76ae4 100644 --- a/src/src/frontend/FetchTargetQueue.scala +++ b/src/src/frontend/FetchTargetQueue.scala @@ -30,8 +30,6 @@ class FetchTargetQueue( // <-> Cu commit val commitFtqTrainPort = Input(new CommitFtqTrainNdPort) val commitBitMask = Input(Vec(Param.commitNum, Bool())) - val commitFixBranch = Input(Bool()) - val commitFixId = Input(UInt(ptrWidth.W)) // <-> Ex query port val exeFtqPort = new ExeFtqPort @@ -194,15 +192,12 @@ class FetchTargetQueue( io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.exeFixBundle := io.exeFtqPort.feedBack.fixGhrBundle io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.isPredecoderFixGhr := io.preDecoderFlush io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle.isPredecoderBranchTaken := io.preDecoderBranchTaken - io.bpuFtqPort.ftqBpuTrainMeta.tageGhrInfo := Mux( - io.commitFixBranch, - ftqBpuMetaRegs(io.commitFixId).tageQueryMeta.tageGhrInfo, + io.bpuFtqPort.ftqBpuTrainMeta.tageGhrInfo := Mux( - io.exeFtqPort.feedBack.fixGhrBundle.isExeFixValid, + io.backendFlush, ftqBpuMetaRegs(io.backendFlushFtqId).tageQueryMeta.tageGhrInfo, ftqBpuMetaRegs(io.preDecoderFtqId).tageQueryMeta.tageGhrInfo ) - ) // when( // io.cuCommitFtqPort.blockBitmask(0) & io.cuCommitFtqPort.meta.isBranch // ) { @@ -275,6 +270,9 @@ class FetchTargetQueue( when(bpuMetaWriteValid) { ftqBpuMetaRegs(bpuMetaWritePtr) := bpuMetaWriteEntry } + when(io.preDecoderFlush) { + ftqBpuMetaRegs(io.preDecoderFtqId).tageQueryMeta.tageGhrInfo := io.bpuFtqPort.bpuQueryMeta.tageQueryMeta.tageGhrInfo + } // update pc from backend when(io.exeFtqPort.feedBack.commitBundle.ftqMetaUpdateValid) { val ftqUpdateMetaId = WireDefault(io.exeFtqPort.feedBack.commitBundle.ftqUpdateMetaId) diff --git a/src/src/frontend/Frontend.scala b/src/src/frontend/Frontend.scala index 3f0044d4..107f343a 100644 --- a/src/src/frontend/Frontend.scala +++ b/src/src/frontend/Frontend.scala @@ -73,8 +73,6 @@ class Frontend extends Module { ftq.io.preDecoderFlush := instFetch.io.preDecodeRedirectPort.predecodeRedirect // TODO add predecoder stage ftq.io.preDecoderFtqId := instFetch.io.preDecodeRedirectPort.redirectFtqId ftq.io.preDecoderBranchTaken := instFetch.io.preDecodeRedirectPort.predecoderBranch - ftq.io.commitFixId := io.commitFixId - ftq.io.commitFixBranch := io.commitFixBranch instFetch.io.preDecodeRedirectPort.commitRasPort := ftq.io.ftqRasPort ftq.io.commitFtqTrainPort := io.commitFtqTrainPort ftq.io.exeFtqPort <> io.exeFtqPort diff --git a/src/src/frontend/bpu/BPU.scala b/src/src/frontend/bpu/BPU.scala index 247fe748..79c507ce 100644 --- a/src/src/frontend/bpu/BPU.scala +++ b/src/src/frontend/bpu/BPU.scala @@ -206,14 +206,19 @@ class BPU( val ghrUpdateSignalBundle = WireDefault( io.bpuFtqPort.ftqBpuTrainMeta.ghrUpdateSignalBundle ) - ghrFixBundle.isFixGhrValid := ghrUpdateSignalBundle.isPredecoderFixGhr || ghrUpdateSignalBundle.isCommitFixGhr || ghrUpdateSignalBundle.exeFixBundle.isExeFixValid + ghrFixBundle.isFixGhrValid := ghrUpdateSignalBundle.isPredecoderFixGhr || io.backendFlush ghrFixBundle.isFixBranchTaken := ghrUpdateSignalBundle.exeFixBundle.exeFixIsTaken +// ghrUpdateSignalBundle.isCommitFixGhr ghrFixBundle.ghrFixType := Mux( - ghrUpdateSignalBundle.isCommitFixGhr, - GhrFixType.commitBrExcp, + io.backendFlush && !ghrUpdateSignalBundle.exeFixBundle.isExeFixValid && !ghrUpdateSignalBundle.isPredecoderFixGhr, + GhrFixType.commitRecover, Mux( ghrUpdateSignalBundle.exeFixBundle.isExeFixValid, - Mux(ghrUpdateSignalBundle.exeFixBundle.exeFixFirstBrTaken, GhrFixType.exeUpdateJump, GhrFixType.exeFixDirection), + Mux( + ghrUpdateSignalBundle.exeFixBundle.exeFixFirstBrTaken, + GhrFixType.exeUpdateJump, + Mux(ghrUpdateSignalBundle.exeFixBundle.exeFixJumpError, GhrFixType.exeFixJumpError, GhrFixType.exeRecover) + ), Mux(ghrUpdateSignalBundle.isPredecoderBranchTaken, GhrFixType.decodeUpdateJump, GhrFixType.decodeBrExcp) ) ) diff --git a/src/src/frontend/bpu/TagePredictor.scala b/src/src/frontend/bpu/TagePredictor.scala index e0ad1eff..7f1cbfea 100644 --- a/src/src/frontend/bpu/TagePredictor.scala +++ b/src/src/frontend/bpu/TagePredictor.scala @@ -182,12 +182,17 @@ class TagePredictor( } when(io.ghrUpdateNdBundle.fixBundle.isFixGhrValid) { switch(io.ghrUpdateNdBundle.fixBundle.ghrFixType) { - is(GhrFixType.commitBrExcp, GhrFixType.decodeBrExcp) { + is(GhrFixType.commitRecover) { // recover to the old history + nextSpecPtr := checkPtr + isRecoverCsr := true.B + } + is(GhrFixType.decodeBrExcp) { + // recover to the old history,quit predict info nextSpecPtr := checkPtr + 1.U isRecoverCsr := true.B } - is(GhrFixType.exeFixDirection) { + is(GhrFixType.exeFixJumpError, GhrFixType.exeRecover) { // fix error predict nextSpecPtr := checkPtr nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.fixBundle.isFixBranchTaken @@ -210,19 +215,22 @@ class TagePredictor( nextSpecPtr := specPtr - 1.U nextGlobalHistory(nextSpecPtr) := io.ghrUpdateNdBundle.bpuSpecTaken } - - shiftedGlobalHistory := Cat(nextGlobalHistory.asUInt, nextGlobalHistory.asUInt) >> nextSpecPtr -// shiftedGlobalHistory := (nextGlobalHistory.asUInt >> nextSpecPtr).asUInt | (nextGlobalHistory.asUInt << (Param.BPU.TagePredictor.ghrLength.U - nextSpecPtr)).asUInt + val ghr = dontTouch(RegInit((0.U(ghrDepth.W)))) + when(isUpdateValid) { + ghr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) + } + if (Param.isSpeculativeGlobalHistory) { + shiftedGlobalHistory := Cat(nextGlobalHistory.asUInt, nextGlobalHistory.asUInt) >> nextSpecPtr + } else { + shiftedGlobalHistory := ghr + } + // shiftedGlobalHistory := (nextGlobalHistory.asUInt >> nextSpecPtr).asUInt | (nextGlobalHistory.asUInt << (Param.BPU.TagePredictor.ghrLength.U - nextSpecPtr)).asUInt // TODO use the correct Cat history // shiftedGlobalHistory := Cat( // nextGlobalHistory.asUInt(nextSpecPtr, 0), // nextGlobalHistory.asUInt(Param.BPU.TagePredictor.ghrLength-1, nextSpecPtr) // ) - val ghr = dontTouch(RegInit((0.U(ghrDepth.W)))) - when(isUpdateValid) { - ghr := Cat(ghr(ghrDepth - 2, 0), updateBranchTaken) - } // output io.tageQueryMeta.tageGhrInfo.checkPtr := nextSpecPtr @@ -240,6 +248,12 @@ class TagePredictor( basePredictor.io.isCtrInc := updateBranchTaken basePredictor.io.updateCtr := updateMetaBundle.providerCtrBits(0) + val isGlobalHistoryUpdate = WireDefault(false.B) + if (Param.isSpeculativeGlobalHistory) { + isGlobalHistoryUpdate := io.ghrUpdateNdBundle.bpuSpecValid + } else { + isGlobalHistoryUpdate := isUpdateValid + } // Tagged Predictor Generate val taggedPreditors = Seq.range(0, tagComponentNum).map { providerId => { @@ -252,7 +266,7 @@ class TagePredictor( ) ) // Query - taggedPreditor.io.isGlobalHistoryUpdate := io.ghrUpdateNdBundle.bpuSpecValid + taggedPreditor.io.isGlobalHistoryUpdate := isGlobalHistoryUpdate taggedPreditor.io.globalHistory := shiftedGlobalHistory(historyLengths(providerId + 1) - 1, 0) taggedPreditor.io.pc := io.pc tagUsefulbits(providerId) := taggedPreditor.io.usefulBits diff --git a/src/src/frontend/bpu/utils/CsrHash.scala b/src/src/frontend/bpu/utils/CsrHash.scala index bcfaabf3..55a85a87 100644 --- a/src/src/frontend/bpu/utils/CsrHash.scala +++ b/src/src/frontend/bpu/utils/CsrHash.scala @@ -1,6 +1,7 @@ package frontend.bpu.utils import chisel3._ import chisel3.util._ +import spec.Param // Implement GHR hash using a CSR (Circular Shifted Register) class CsrHash( @@ -24,40 +25,40 @@ class CsrHash( // nextCSR := Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) // nextCSR(residual) := nextCSR(residual, residual) ^ io.data(inputLength - 1) - val keepCSR = WireDefault(0.U(outputLength.W)) - keepCSR := Mux(io.isRecoverCsr, io.originHash, csr) - - nextCSR := Mux( - io.isRecoverCsr, - io.originHash, - Mux( - io.isExeFixCsr || io.isPredecodeFixCsr, - Cat(io.originHash(outputLength - 2, 0), io.originHash(outputLength - 1) ^ io.data(0)) ^ (io.data( - inputLength - 1 - ) << residual).asUInt, + if (Param.isSpeculativeGlobalHistory) { + nextCSR := Mux( + io.isRecoverCsr, + io.originHash, Mux( - io.dataUpdate, - Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( + io.isExeFixCsr || io.isPredecodeFixCsr, + Cat(io.originHash(outputLength - 2, 0), io.originHash(outputLength - 1) ^ io.data(0)) ^ (io.data( inputLength - 1 ) << residual).asUInt, - csr + Mux( + io.dataUpdate, + Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( + inputLength - 1 + ) << residual).asUInt, + csr + ) ) ) - ) - // commit update -// nextCSR := Mux( -// io.dataUpdate, -// Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( -// inputLength - 1 -// ) << residual).asUInt, -// csr -// ) + } else { + // commit update + nextCSR := Mux( + io.dataUpdate, + Cat(csr(outputLength - 2, 0), csr(outputLength - 1) ^ io.data(0)) ^ (io.data( + inputLength - 1 + ) << residual).asUInt, + csr + ) + } // when(io.dataUpdate) { // csr := nextCSR // } csr := nextCSR - io.hash := nextCSR + io.hash := csr } diff --git a/src/src/frontend/bundles/FtqBpuMetaPort.scala b/src/src/frontend/bundles/FtqBpuMetaPort.scala index 9ad3ccaa..57bfcd23 100644 --- a/src/src/frontend/bundles/FtqBpuMetaPort.scala +++ b/src/src/frontend/bundles/FtqBpuMetaPort.scala @@ -13,6 +13,7 @@ class BranchAddrBundle extends Bundle { class ExeFtqFixGhrBundle extends Bundle { val isExeFixValid = Bool() val exeFixFirstBrTaken = Bool() + val exeFixJumpError = Bool() val exeFixIsTaken = Bool() } class GhrUpdateSignalBundle extends Bundle { diff --git a/src/src/frontend/fetch/InstPreDecodeStage.scala b/src/src/frontend/fetch/InstPreDecodeStage.scala index 7d5ed4eb..5ccbf346 100644 --- a/src/src/frontend/fetch/InstPreDecodeStage.scala +++ b/src/src/frontend/fetch/InstPreDecodeStage.scala @@ -109,7 +109,8 @@ class InstPreDecodeStage val isPredecoderRedirect = WireDefault(false.B) isPredecoderRedirect := isDataValid && ((isJump && canJump) || isErrorPredict) val isPredecoderRedirectReg = RegNext(isPredecoderRedirect, false.B) - peer.predecoderBranch := RegNext(isDataValid && (isJump && canJump), false.B) +// peer.predecoderBranch := RegNext(isDataValid && (isJump && canJump), false.B) + peer.predecoderBranch := true.B // decrease net delay ,do not care non branch inst jump effect branch history // connect return address stack module val rasModule = Module(new RAS) diff --git a/src/src/pipeline/complex/execution/ExePassWbStage.scala b/src/src/pipeline/complex/execution/ExePassWbStage.scala index e2fddbc8..607913d6 100644 --- a/src/src/pipeline/complex/execution/ExePassWbStage.scala +++ b/src/src/pipeline/complex/execution/ExePassWbStage.scala @@ -235,9 +235,10 @@ class ExePassWbStage(supportBranchCsr: Boolean = true) branchSetPort.en := isRedirect branchSetPort.ftqId := selectedIn.instInfo.ftqInfo.ftqId - feedbackFtq.feedBack.fixGhrBundle.isExeFixValid := branchDirectionMispredict && branchEnableFlag && isBranchInst + feedbackFtq.feedBack.fixGhrBundle.isExeFixValid := isRedirect feedbackFtq.feedBack.fixGhrBundle.exeFixFirstBrTaken := jumpBranchInfo.en && !inFtqInfo.isPredictValid && branchEnableFlag && isBranchInst // TODO predictValid - feedbackFtq.feedBack.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en + feedbackFtq.feedBack.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en + feedbackFtq.feedBack.fixGhrBundle.exeFixJumpError := branchTargetMispredict && branchEnableFlag && isBranchInst branchSetPort.pcAddr := Mux( jumpBranchInfo.en, diff --git a/src/src/pipeline/simple/MainExeStage.scala b/src/src/pipeline/simple/MainExeStage.scala index 43c5f9f9..4c0dbba7 100644 --- a/src/src/pipeline/simple/MainExeStage.scala +++ b/src/src/pipeline/simple/MainExeStage.scala @@ -495,15 +495,13 @@ class MainExeStage feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := RegNext(jumpAddr, 0.U) feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := RegNext(fallThroughPc, 0.U) - feedbackFtq.fixGhrBundle.isExeFixValid := RegNext( - branchDirectionMispredict && !isBlocking && isBranchInst, - false.B - ) + feedbackFtq.fixGhrBundle.isExeFixValid := RegNext(isRedirect && !isBlocking, false.B) feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := RegNext( jumpBranchInfo.en && !inFtqInfo.isPredictValid && !isBlocking && isBranchInst, false.B ) // TODO predictValid - feedbackFtq.fixGhrBundle.exeFixIsTaken := RegNext(jumpBranchInfo.en, false.B) + feedbackFtq.fixGhrBundle.exeFixJumpError := RegNext(isRedirect && !isBlocking, false.B) + feedbackFtq.fixGhrBundle.exeFixIsTaken := RegNext(jumpBranchInfo.en, false.B) } else { feedbackFtq.commitBundle.ftqMetaUpdateValid := (isBranchInst || (!isBranchInst && inFtqInfo.predictBranch)) && !branchBlockingReg @@ -513,10 +511,11 @@ class MainExeStage feedbackFtq.commitBundle.ftqMetaUpdateJumpTarget := jumpAddr feedbackFtq.commitBundle.ftqMetaUpdateFallThrough := fallThroughPc - feedbackFtq.fixGhrBundle.isExeFixValid := branchDirectionMispredict && !isBlocking && isBranchInst + feedbackFtq.fixGhrBundle.isExeFixValid := isRedirect && !isBlocking feedbackFtq.fixGhrBundle.exeFixFirstBrTaken := jumpBranchInfo.en && !inFtqInfo.isPredictValid && !isBlocking && isBranchInst - feedbackFtq.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en + feedbackFtq.fixGhrBundle.exeFixIsTaken := jumpBranchInfo.en + feedbackFtq.fixGhrBundle.exeFixJumpError := isRedirect && !isBlocking } // out.wb.instInfo.ftqCommitInfo.isBranchSuccess := jumpBranchInfo.en diff --git a/src/src/spec/Param.scala b/src/src/spec/Param.scala index b3d468fb..21676fb1 100644 --- a/src/src/spec/Param.scala +++ b/src/src/spec/Param.scala @@ -15,18 +15,19 @@ object Param { val usePmu = false || isChiplab // 性能计数器 - val isDiffTest = false || isChiplab - val isOutOfOrderIssue = true - val isFullUncachedPatch = true - val isMmioDelay = false || isChiplab || isFullFpga - val isNoPrivilege = false || isReleasePackage - val isCacheOnPg = true - val isForcedCache = false || isReleasePackage - val isForcedUncached = false - val isBranchPredict = true - val isPredecode = true - val isOverideRas = true - val isFTBupdateRet = true + val isDiffTest = false || isChiplab + val isOutOfOrderIssue = true + val isFullUncachedPatch = true + val isMmioDelay = false || isChiplab || isFullFpga + val isNoPrivilege = false || isReleasePackage + val isCacheOnPg = false + val isForcedCache = false || isReleasePackage + val isForcedUncached = false + val isBranchPredict = true + val isPredecode = true + val isOverideRas = true + val isFTBupdateRet = true + val isSpeculativeGlobalHistory = false val isWritebackPassThroughWakeUp = true val canIssueSameWbRegInsts = true @@ -227,9 +228,10 @@ object Param { count.U } - val commitBrExcp = 0.U - val exeFixDirection = next + val commitRecover = 0.U + val exeFixJumpError = next val exeUpdateJump = next + val exeRecover = next val decodeUpdateJump = next val decodeBrExcp = next