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 services = ArrayBuffer[Any]()
def stageBefore(stage : Stage) = stages(indexOf(stage)-1)
def indexOf(stage : Stage) = stages.indexOf(stage)
def service[T](clazz : Class[T]) = {
@ -127,7 +129,7 @@ trait Pipeline {
//Arbitration
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))
stage.arbitration.removeIt setWhen stage.arbitration.isFlushed
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 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 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 isStuck = Bool //Inform if the instruction is stuck (haltItself || haltByOther)
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){
memory.arbitration.removeIt.noBackendCombMerge
}
execute.arbitration.flushAll.noBackendCombMerge
execute.arbitration.flushNext.noBackendCombMerge
this(RVC_GEN) = false
}

View File

@ -200,11 +200,11 @@ class BranchPlugin(earlyBranch : Boolean,
//Apply branchs (JAL,JALR, Bxx)
branchStage plug new Area {
import branchStage._
jumpInterface.valid := arbitration.isValid && !arbitration.isStuckByOthers && input(BRANCH_DO)
jumpInterface.valid := arbitration.isValid && input(BRANCH_DO)
jumpInterface.payload := input(BRANCH_CALC)
when(jumpInterface.valid) {
stages(indexOf(branchStage) - 1).arbitration.flushAll := True
when(jumpInterface.valid && !arbitration.isStuckByOthers) {
arbitration.flushNext := True
}
if(catchAddressMisalignedForReal) {
@ -282,11 +282,11 @@ class BranchPlugin(earlyBranch : Boolean,
val branchStage = if(earlyBranch) execute else memory
branchStage plug new Area {
import branchStage._
jumpInterface.valid := arbitration.isValid && !arbitration.isStuckByOthers && input(BRANCH_DO)
jumpInterface.valid := arbitration.isValid && input(BRANCH_DO)
jumpInterface.payload := input(BRANCH_CALC)
when(jumpInterface.valid) {
stages(indexOf(branchStage) - 1).arbitration.flushAll := True
when(jumpInterface.valid && !arbitration.isStuckByOthers) {
arbitration.flushNext := True
}
if(catchAddressMisalignedForReal) {
@ -361,12 +361,12 @@ class BranchPlugin(earlyBranch : Boolean,
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))
when(jumpInterface.valid) {
stages(indexOf(branchStage) - 1).arbitration.flushAll := True
when(jumpInterface.valid && !arbitration.isStuckByOthers) {
arbitration.flushNext := True
}
if(catchAddressMisalignedForReal) {

View File

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

View File

@ -239,7 +239,8 @@ class DBusCachedPlugin(config : DataCacheConfig,
redoBranch.valid := False
redoBranch.payload := input(PC)
arbitration.flushAll setWhen(redoBranch.valid)
arbitration.flushIt setWhen(redoBranch.valid)
arbitration.flushNext setWhen(redoBranch.valid)
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

View File

@ -476,7 +476,8 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
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))){

View File

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

View File

@ -103,7 +103,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
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{
val preOutput = Stream(UInt(32 bits))
@ -499,10 +499,15 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
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
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){
// decodePrediction.cmd.hadBranch := False
// }

View File

@ -237,6 +237,9 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
redoBranch.valid := redoFetch
redoBranch.payload := (if (decodePcGen) decode.input(PC) else cacheRsp.pc)
when(redoBranch.valid) {
decode.arbitration.flushNext := True
}
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)
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)
redoBranch.valid := redoRequired && iBusRsp.readyForError
redoBranch.payload := decode.input(PC)
decode.arbitration.flushAll setWhen(redoBranch.valid)
decode.arbitration.flushIt setWhen(redoBranch.valid)
decode.arbitration.flushNext setWhen(redoBranch.valid)
}