BranchPrediction DYNAMIC_TARGET add source PC tag to only consume entries on branch instructions

This commit is contained in:
Dolu1990 2018-01-29 14:52:31 +01:00
parent 0d318ab6b9
commit bdbf6ecf17
5 changed files with 83 additions and 23 deletions

View File

@ -123,7 +123,7 @@ object TestsWorkspace {
earlyBranch = true, earlyBranch = true,
catchAddressMisaligned = true, catchAddressMisaligned = true,
prediction = DYNAMIC_TARGET, prediction = DYNAMIC_TARGET,
historyRamSizeLog2 = 12 historyRamSizeLog2 = 8
), ),
new YamlPlugin("cpu0.yaml") new YamlPlugin("cpu0.yaml")
) )

View File

@ -32,14 +32,14 @@ object DhrystoneBench extends App{
getDmips( getDmips(
name = "GenSmallest", name = "GenSmallest",
gen = GenSmallest.main(null), gen = GenSmallest.main(null),
test = "make clean run REDO=0 IBUS=SIMPLE DBUS=SIMPLE MMU=no DEBUG_PLUGIN=no MUL=no DIV=no" test = "make clean run REDO=0 IBUS=SIMPLE DBUS=SIMPLE CSR=no MMU=no DEBUG_PLUGIN=no MUL=no DIV=no"
) )
getDmips( getDmips(
name = "GenSmallAndProductive", name = "GenSmallAndProductive",
gen = GenSmallAndProductive.main(null), gen = GenSmallAndProductive.main(null),
test = "make clean run REDO=0 IBUS=SIMPLE DBUS=SIMPLE MMU=no DEBUG_PLUGIN=no MUL=no DIV=no" test = "make clean run REDO=0 IBUS=SIMPLE DBUS=SIMPLE CSR=no MMU=no DEBUG_PLUGIN=no MUL=no DIV=no"
) )

View File

@ -78,7 +78,8 @@ object GenFullNoMmuMaxPerf extends App{
new BranchPlugin( new BranchPlugin(
earlyBranch = true, earlyBranch = true,
catchAddressMisaligned = true, catchAddressMisaligned = true,
prediction = DYNAMIC prediction = DYNAMIC_TARGET,
historyRamSizeLog2 = 8
), ),
new YamlPlugin("cpu0.yaml") new YamlPlugin("cpu0.yaml")
) )

View File

@ -275,12 +275,14 @@ class BranchPlugin(earlyBranch : Boolean,
import pipeline.config._ import pipeline.config._
case class BranchPredictorLine() extends Bundle{ case class BranchPredictorLine() extends Bundle{
val enable = Bool val source = Bits(31 - historyRamSizeLog2 bits)
val confidence = UInt(2 bits)
val target = UInt(32 bits) val target = UInt(32 bits)
} }
object PREDICTION_HAD_HAZARD extends Stageable(Bool) object PREDICTION_WRITE_HAZARD extends Stageable(Bool)
object PREDICTION extends Stageable(Flow(UInt(32 bits))) object PREDICTION extends Stageable(BranchPredictorLine())
object PREDICTION_HIT extends Stageable(Bool)
val history = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2) val history = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
val historyWrite = history.writePort val historyWrite = history.writePort
@ -288,17 +290,20 @@ class BranchPlugin(earlyBranch : Boolean,
fetch plug new Area{ fetch plug new Area{
import fetch._ import fetch._
// val line = predictorLines.readSync(prefetch.output(PC), prefetch.arbitration.isFiring) val line = history.readSync((prefetch.output(PC) >> 2).resized, prefetch.arbitration.isFiring)
val line = history.readAsync((fetch.output(PC) >> 2).resized) // val line = history.readAsync((fetch.output(PC) >> 2).resized)
predictionJumpInterface.valid := line.enable && arbitration.isFiring val hit = line.source === (input(PC).asBits >> 1 + historyRamSizeLog2)
predictionJumpInterface.payload := line.target
//Avoid write to read hazard //Avoid write to read hazard
val historyWriteLast = RegNext(historyWrite) val historyWriteLast = RegNext(historyWrite)
insert(PREDICTION_HAD_HAZARD) := historyWriteLast.valid && historyWriteLast.address === (fetch.output(PC) >> 2).resized val hazard = historyWriteLast.valid && historyWriteLast.address === (output(PC) >> 2).resized
predictionJumpInterface.valid clearWhen(input(PREDICTION_HAD_HAZARD)) insert(PREDICTION_WRITE_HAZARD) := hazard
fetch.insert(PREDICTION) := predictionJumpInterface predictionJumpInterface.valid := line.confidence.msb && hit && arbitration.isFiring && !hazard
predictionJumpInterface.payload := line.target
insert(PREDICTION) := line
insert(PREDICTION_HIT) := hit
} }
@ -339,9 +344,11 @@ class BranchPlugin(earlyBranch : Boolean,
branchStage plug new Area { branchStage plug new Area {
import branchStage._ import branchStage._
val predictionMissmatch = input(PREDICTION).confidence.msb =/= input(BRANCH_DO) || (input(BRANCH_DO) && input(PREDICTION).target =/= input(BRANCH_CALC))
historyWrite.valid := False historyWrite.valid := False
historyWrite.address := (branchStage.output(PC) >> 2).resized historyWrite.address := (branchStage.output(PC) >> 2).resized
historyWrite.data.enable := input(BRANCH_DO) historyWrite.data.source := input(PC).asBits >> 1 + historyRamSizeLog2
historyWrite.data.target := input(BRANCH_CALC) historyWrite.data.target := input(BRANCH_CALC)
jumpInterface.valid := False jumpInterface.valid := False
@ -349,20 +356,29 @@ class BranchPlugin(earlyBranch : Boolean,
when(!input(BRANCH_DO)){ when(!input(BRANCH_DO)){
when(input(PREDICTION).valid) { historyWrite.valid := arbitration.isFiring && input(PREDICTION_HIT)
jumpInterface.valid := arbitration.isFiring historyWrite.data.confidence := input(PREDICTION).confidence - (input(PREDICTION).confidence =/= 0).asUInt
jumpInterface.payload := input(PC) + 4 historyWrite.data.target := input(BRANCH_CALC)
historyWrite.valid := arbitration.isFiring
}
jumpInterface.valid := input(PREDICTION_HIT) && input(PREDICTION).confidence.msb && !input(PREDICTION_WRITE_HAZARD) && arbitration.isFiring
jumpInterface.payload := input(PC) + 4
} otherwise{ } otherwise{
when (!input(PREDICTION).valid || input(PREDICTION).payload =/= input(BRANCH_CALC)) { when(!input(PREDICTION_HIT) || input(PREDICTION_WRITE_HAZARD)){
jumpInterface.valid := arbitration.isFiring jumpInterface.valid := arbitration.isFiring
historyWrite.valid := arbitration.isFiring historyWrite.valid := arbitration.isFiring
historyWrite.data.confidence := "10"
} otherwise {
historyWrite.valid := arbitration.isFiring
historyWrite.data.confidence := input(PREDICTION).confidence + (input(PREDICTION).confidence =/= 3).asUInt
when(!input(PREDICTION).confidence.msb || input(PREDICTION).target =/= input(BRANCH_CALC)){
jumpInterface.valid := arbitration.isFiring
}
} }
} }
//Prevent rewriting an history which already had hazard //Prevent rewriting an history which already had hazard
historyWrite.valid clearWhen(input(PREDICTION_HAD_HAZARD)) historyWrite.valid clearWhen(input(PREDICTION_WRITE_HAZARD))
@ -384,7 +400,7 @@ class BranchPlugin(earlyBranch : Boolean,
prefetch.arbitration.haltByOther := True prefetch.arbitration.haltByOther := True
historyWrite.valid := True historyWrite.valid := True
historyWrite.address := counter.resized historyWrite.address := counter.resized
historyWrite.data.enable := False historyWrite.data.confidence := 0
counter := counter + 1 counter := counter + 1
} }
} }

View File

@ -0,0 +1,43 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Mon Jan 29 13:38:19 2018
[*]
[dumpfile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/dhrystoneO3M.vcd"
[dumpfile_mtime] "Mon Jan 29 13:37:19 2018"
[dumpfile_size] 1215443558
[savefile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/prediction.gtkw"
[timestart] 127017
[size] 1784 950
[pos] -383 -155
*-3.000000 127032 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] TOP.
[sst_width] 400
[signals_width] 583
[sst_expanded] 1
[sst_vpaned_height] 492
@28
TOP.VexRiscv.iBus_cmd_valid
TOP.VexRiscv.decode_arbitration_flushAll
TOP.VexRiscv.execute_arbitration_flushAll
TOP.VexRiscv.fetch_arbitration_flushAll
TOP.VexRiscv.memory_arbitration_flushAll
TOP.VexRiscv.prefetch_arbitration_flushAll
TOP.VexRiscv.writeBack_arbitration_flushAll
TOP.VexRiscv.execute_BranchPlugin_predictionMissmatch
TOP.VexRiscv.execute_PREDICTION2_confidence[1:0]
@22
TOP.VexRiscv.execute_PREDICTION2_source[18:0]
TOP.VexRiscv.execute_PREDICTION2_target[31:0]
@28
TOP.VexRiscv.execute_PREDICTION_HIT2
TOP.VexRiscv.execute_PREDICTION_WRITE_HAZARD2
@23
TOP.VexRiscv.execute_PC[31:0]
@28
TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid
@22
TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[31:0]
@29
TOP.VexRiscv.execute_arbitration_isFiring
[pattern_trace] 1
[pattern_trace] 0