rework flush with flushNext and flushIt

static branch prediction jump do not depend on stage fireing anymore
This commit is contained in:
Charles Papon 2019-06-09 15:44:05 +02:00
parent 0e2d40c37f
commit af0755d8cf
11 changed files with 37 additions and 21 deletions

View File

@ -17,6 +17,8 @@ trait Pipeline {
val things = mutable.HashMap[PipelineThing[_], Any]() val things = mutable.HashMap[PipelineThing[_], Any]()
// val services = ArrayBuffer[Any]() // val services = ArrayBuffer[Any]()
def stageBefore(stage : Stage) = stages(indexOf(stage)-1)
def indexOf(stage : Stage) = stages.indexOf(stage) def indexOf(stage : Stage) = stages.indexOf(stage)
def service[T](clazz : Class[T]) = { def service[T](clazz : Class[T]) = {
@ -127,7 +129,7 @@ trait Pipeline {
//Arbitration //Arbitration
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)) { for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)) {
stage.arbitration.isFlushed := stages.drop(stageIndex).map(_.arbitration.flushAll).orR stage.arbitration.isFlushed := stages.drop(stageIndex+1).map(_.arbitration.flushNext).orR || stages.drop(stageIndex).map(_.arbitration.flushIt).orR
if(!unremovableStages.contains(stage)) if(!unremovableStages.contains(stage))
stage.arbitration.removeIt setWhen stage.arbitration.isFlushed stage.arbitration.removeIt setWhen stage.arbitration.isFlushed
else else

View File

@ -49,7 +49,8 @@ class Stage() extends Area{
val haltItself = False //user settable, stuck the instruction, should only be set by the instruction itself val haltItself = False //user settable, stuck the instruction, should only be set by the instruction itself
val haltByOther = False //When settable, stuck the instruction, should only be set by something else than the stucked instruction val haltByOther = False //When settable, stuck the instruction, should only be set by something else than the stucked instruction
val removeIt = False //When settable, unschedule the instruction as if it was never executed (no side effect) val removeIt = False //When settable, unschedule the instruction as if it was never executed (no side effect)
val flushAll = False //When settable, unschedule instructions in the current stage and all prior ones val flushIt = False //When settable, unschedule the current instruction
val flushNext = False //When settable, unschedule instruction above in the pipeline
val isValid = Bool //Inform if a instruction is in the current stage val isValid = Bool //Inform if a instruction is in the current stage
val isStuck = Bool //Inform if the instruction is stuck (haltItself || haltByOther) val isStuck = Bool //Inform if the instruction is stuck (haltItself || haltByOther)
val isStuckByOthers = Bool //Inform if the instruction is stuck by sombody else val isStuckByOthers = Bool //Inform if the instruction is stuck by sombody else

View File

@ -109,7 +109,7 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
if(withMemoryStage){ if(withMemoryStage){
memory.arbitration.removeIt.noBackendCombMerge memory.arbitration.removeIt.noBackendCombMerge
} }
execute.arbitration.flushAll.noBackendCombMerge execute.arbitration.flushNext.noBackendCombMerge
this(RVC_GEN) = false this(RVC_GEN) = false
} }

View File

@ -200,11 +200,11 @@ class BranchPlugin(earlyBranch : Boolean,
//Apply branchs (JAL,JALR, Bxx) //Apply branchs (JAL,JALR, Bxx)
branchStage plug new Area { branchStage plug new Area {
import branchStage._ import branchStage._
jumpInterface.valid := arbitration.isValid && !arbitration.isStuckByOthers && input(BRANCH_DO) jumpInterface.valid := arbitration.isValid && input(BRANCH_DO)
jumpInterface.payload := input(BRANCH_CALC) jumpInterface.payload := input(BRANCH_CALC)
when(jumpInterface.valid) { when(jumpInterface.valid && !arbitration.isStuckByOthers) {
stages(indexOf(branchStage) - 1).arbitration.flushAll := True arbitration.flushNext := True
} }
if(catchAddressMisalignedForReal) { if(catchAddressMisalignedForReal) {
@ -282,11 +282,11 @@ class BranchPlugin(earlyBranch : Boolean,
val branchStage = if(earlyBranch) execute else memory val branchStage = if(earlyBranch) execute else memory
branchStage plug new Area { branchStage plug new Area {
import branchStage._ import branchStage._
jumpInterface.valid := arbitration.isValid && !arbitration.isStuckByOthers && input(BRANCH_DO) jumpInterface.valid := arbitration.isValid && input(BRANCH_DO)
jumpInterface.payload := input(BRANCH_CALC) jumpInterface.payload := input(BRANCH_CALC)
when(jumpInterface.valid) { when(jumpInterface.valid && !arbitration.isStuckByOthers) {
stages(indexOf(branchStage) - 1).arbitration.flushAll := True arbitration.flushNext := True
} }
if(catchAddressMisalignedForReal) { if(catchAddressMisalignedForReal) {
@ -361,12 +361,12 @@ class BranchPlugin(earlyBranch : Boolean,
input(PC) input(PC)
} }
jumpInterface.valid := arbitration.isValid && !arbitration.isStuckByOthers && predictionMissmatch //Probably just isValid instead of isFiring is better jumpInterface.valid := arbitration.isValid && predictionMissmatch //Probably just isValid instead of isFiring is better
jumpInterface.payload := (input(BRANCH_DO) ? input(BRANCH_CALC) | input(NEXT_PC)) jumpInterface.payload := (input(BRANCH_DO) ? input(BRANCH_CALC) | input(NEXT_PC))
when(jumpInterface.valid) { when(jumpInterface.valid && !arbitration.isStuckByOthers) {
stages(indexOf(branchStage) - 1).arbitration.flushAll := True arbitration.flushNext := True
} }
if(catchAddressMisalignedForReal) { if(catchAddressMisalignedForReal) {

View File

@ -694,7 +694,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
exceptionValids := exceptionValidsRegs exceptionValids := exceptionValidsRegs
for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage; stageId = indexOf(portInfo.stage)) { for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage; stageId = indexOf(portInfo.stage)) {
when(port.valid) { when(port.valid) {
if(indexOf(stage) != 0) stages(indexOf(stage) - 1).arbitration.flushAll := True stage.arbitration.flushNext := True
stage.arbitration.removeIt := True stage.arbitration.removeIt := True
exceptionValids(stageId) := True exceptionValids(stageId) := True
exceptionContext := port.payload exceptionContext := port.payload
@ -806,7 +806,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
jumpInterface.valid := True jumpInterface.valid := True
jumpInterface.payload := (if(!xtvecModeGen) xtvec.base @@ "00" else (xtvec.mode === 0 || hadException) ? (xtvec.base @@ "00") | ((xtvec.base + trapCause) @@ "00") ) jumpInterface.payload := (if(!xtvecModeGen) xtvec.base @@ "00" else (xtvec.mode === 0 || hadException) ? (xtvec.base @@ "00") | ((xtvec.base + trapCause) @@ "00") )
beforeLastStage.arbitration.flushAll := True lastStage.arbitration.flushNext := True
if(privilegeGen) privilegeReg := targetPrivilege if(privilegeGen) privilegeReg := targetPrivilege
@ -845,7 +845,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) { when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) {
fetcher.haltIt() fetcher.haltIt()
jumpInterface.valid := True jumpInterface.valid := True
beforeLastStage.arbitration.flushAll := True lastStage.arbitration.flushNext := True
switch(input(INSTRUCTION)(29 downto 28)){ switch(input(INSTRUCTION)(29 downto 28)){
is(3){ is(3){
mstatus.MPP := U"00" mstatus.MPP := U"00"

View File

@ -239,7 +239,8 @@ class DBusCachedPlugin(config : DataCacheConfig,
redoBranch.valid := False redoBranch.valid := False
redoBranch.payload := input(PC) redoBranch.payload := input(PC)
arbitration.flushAll setWhen(redoBranch.valid) arbitration.flushIt setWhen(redoBranch.valid)
arbitration.flushNext setWhen(redoBranch.valid)
if(catchSomething) { if(catchSomething) {
exceptionBus.valid := False //cache.io.cpu.writeBack.mmuMiss || cache.io.cpu.writeBack.accessError || cache.io.cpu.writeBack.illegalAccess || cache.io.cpu.writeBack.unalignedAccess exceptionBus.valid := False //cache.io.cpu.writeBack.mmuMiss || cache.io.cpu.writeBack.accessError || cache.io.cpu.writeBack.illegalAccess || cache.io.cpu.writeBack.unalignedAccess

View File

@ -476,7 +476,8 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
memoryExceptionPort.code := (input(MEMORY_STORE) ? U(15) | U(13)).resized memoryExceptionPort.code := (input(MEMORY_STORE) ? U(15) | U(13)).resized
} }
arbitration.flushAll setWhen(redoBranch.valid) arbitration.flushIt setWhen(redoBranch.valid)
arbitration.flushNext setWhen(redoBranch.valid)
} }
when(!(arbitration.isValid && input(MEMORY_ENABLE) && (Bool(cmdStage != rspStage) || !arbitration.isStuckByOthers))){ when(!(arbitration.isValid && input(MEMORY_ENABLE) && (Bool(cmdStage != rspStage) || !arbitration.isStuckByOthers))){

View File

@ -203,7 +203,8 @@ class DebugPlugin(val debugClockDomain : ClockDomain, hardwareBreakpointCount :
when(stagesFromExecute.tail.map(_.arbitration.isValid).orR === False){ when(stagesFromExecute.tail.map(_.arbitration.isValid).orR === False){
iBusFetcher.flushIt() iBusFetcher.flushIt()
iBusFetcher.haltIt() iBusFetcher.haltIt()
execute.arbitration.flushAll := True execute.arbitration.flushIt := True
execute.arbitration.flushNext := True
haltIt := True haltIt := True
haltedByBreak := True haltedByBreak := True
} }

View File

@ -103,7 +103,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
pcLoad.payload := MuxOH(OHMasking.first(valids.asBits), pcs) pcLoad.payload := MuxOH(OHMasking.first(valids.asBits), pcs)
} }
def flush = jump.pcLoad.valid || fetcherflushIt def flush = fetcherflushIt || stages.map(_.arbitration.flushNext).orR
class PcFetch extends Area{ class PcFetch extends Area{
val preOutput = Stream(UInt(32 bits)) val preOutput = Stream(UInt(32 bits))
@ -499,10 +499,15 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
decodePrediction.cmd.hadBranch clearWhen(missaligned) decodePrediction.cmd.hadBranch clearWhen(missaligned)
} }
predictionJumpInterface.valid := decodePrediction.cmd.hadBranch && decode.arbitration.isFiring //TODO OH Doublon de priorité //TODO no more fireing depedancies
predictionJumpInterface.valid := decodePrediction.cmd.hadBranch && decode.arbitration.isValid //TODO OH Doublon de priorité
predictionJumpInterface.payload := decode.input(PC) + ((decode.input(BRANCH_CTRL) === BranchCtrlEnum.JAL) ? imm.j_sext | imm.b_sext).asUInt predictionJumpInterface.payload := decode.input(PC) + ((decode.input(BRANCH_CTRL) === BranchCtrlEnum.JAL) ? imm.j_sext | imm.b_sext).asUInt
if(relaxPredictorAddress) KeepAttribute(predictionJumpInterface.payload) if(relaxPredictorAddress) KeepAttribute(predictionJumpInterface.payload)
when(predictionJumpInterface.valid && decode.arbitration.isFiring){
flushIt()
}
// when(predictionJumpInterface.payload((if(pipeline(RVC_GEN)) 0 else 1) downto 0) =/= 0){ // when(predictionJumpInterface.payload((if(pipeline(RVC_GEN)) 0 else 1) downto 0) =/= 0){
// decodePrediction.cmd.hadBranch := False // decodePrediction.cmd.hadBranch := False
// } // }

View File

@ -237,6 +237,9 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
redoBranch.valid := redoFetch redoBranch.valid := redoFetch
redoBranch.payload := (if (decodePcGen) decode.input(PC) else cacheRsp.pc) redoBranch.payload := (if (decodePcGen) decode.input(PC) else cacheRsp.pc)
when(redoBranch.valid) {
decode.arbitration.flushNext := True
}
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt) cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)
iBusRsp.output.valid := cacheRspArbitration.output.valid iBusRsp.output.valid := cacheRspArbitration.output.valid

View File

@ -351,7 +351,9 @@ class IBusSimplePlugin(resetVector : BigInt,
redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling) redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling)
redoBranch.valid := redoRequired && iBusRsp.readyForError redoBranch.valid := redoRequired && iBusRsp.readyForError
redoBranch.payload := decode.input(PC) redoBranch.payload := decode.input(PC)
decode.arbitration.flushAll setWhen(redoBranch.valid)
decode.arbitration.flushIt setWhen(redoBranch.valid)
decode.arbitration.flushNext setWhen(redoBranch.valid)
} }