BranchPrediction DYNAMIC_TARGET add source PC tag to only consume entries on branch instructions
This commit is contained in:
parent
0d318ab6b9
commit
bdbf6ecf17
|
@ -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")
|
||||||
)
|
)
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue