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,
catchAddressMisaligned = true,
prediction = DYNAMIC_TARGET,
historyRamSizeLog2 = 12
historyRamSizeLog2 = 8
),
new YamlPlugin("cpu0.yaml")
)

View File

@ -32,14 +32,14 @@ object DhrystoneBench extends App{
getDmips(
name = "GenSmallest",
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(
name = "GenSmallAndProductive",
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(
earlyBranch = true,
catchAddressMisaligned = true,
prediction = DYNAMIC
prediction = DYNAMIC_TARGET,
historyRamSizeLog2 = 8
),
new YamlPlugin("cpu0.yaml")
)

View File

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