IBusFetcher now support proper iBusRsp.redo/flush

This commit is contained in:
Charles Papon 2020-02-17 12:50:12 +01:00
parent ebfa9e6577
commit 8be50b8e3d
5 changed files with 24 additions and 24 deletions

View File

@ -272,7 +272,7 @@ object LinuxGen {
// wfiGenAsNop = true, // wfiGenAsNop = true,
// ucycleAccess = CsrAccess.NONE // ucycleAccess = CsrAccess.NONE
// )), // )),
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))), new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin( new BranchPlugin(
earlyBranch = false, earlyBranch = false,
catchAddressMisaligned = true, catchAddressMisaligned = true,
@ -310,7 +310,7 @@ object LinuxGen {
// } // }
// } // }
SpinalConfig(mergeAsyncProcess = true, anonymSignalPrefix = "_zz").generateVerilog { SpinalConfig(mergeAsyncProcess = false, anonymSignalPrefix = "_zz").generateVerilog {
val toplevel = new VexRiscv(configFull( val toplevel = new VexRiscv(configFull(

View File

@ -21,7 +21,8 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val prediction : BranchPrediction, val prediction : BranchPrediction,
val historyRamSizeLog2 : Int, val historyRamSizeLog2 : Int,
val injectorStage : Boolean, val injectorStage : Boolean,
val relaxPredictorAddress : Boolean) extends Plugin[VexRiscv] with JumpService with IBusFetcher{ val relaxPredictorAddress : Boolean,
val fetchRedoGen : Boolean) extends Plugin[VexRiscv] with JumpService with IBusFetcher{
var prefetchExceptionPort : Flow[ExceptionCause] = null var prefetchExceptionPort : Flow[ExceptionCause] = null
var decodePrediction : DecodePredictionBus = null var decodePrediction : DecodePredictionBus = null
var fetchPrediction : FetchPredictionBus = null var fetchPrediction : FetchPredictionBus = null
@ -131,11 +132,16 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val inc = RegInit(False) clearWhen(corrected || pcRegPropagate) setWhen(output.fire) clearWhen(!output.valid && output.ready) val inc = RegInit(False) clearWhen(corrected || pcRegPropagate) setWhen(output.fire) clearWhen(!output.valid && output.ready)
val pc = pcReg + (inc ## B"00").asUInt val pc = pcReg + (inc ## B"00").asUInt
// val predictionPcLoad = ifGen(prediction == DYNAMIC_TARGET) (Flow(UInt(32 bits))) // val predictionPcLoad = ifGen(prediction == DYNAMIC_TARGET) (Flow(UInt(32 bits)))
val redo = fetchRedoGen generate Flow(UInt(32 bits))
if(compressedGen) when(inc) { if(compressedGen) when(inc) {
pc(1) := False pc(1) := False
} }
if(fetchRedoGen) when(redo.valid){
corrected := True
pc := redo.payload
}
// if(predictionPcLoad != null) { // if(predictionPcLoad != null) {
// when(predictionPcLoad.valid) { // when(predictionPcLoad.valid) {
// corrected := True // corrected := True
@ -147,7 +153,6 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
pc := jump.pcLoad.payload pc := jump.pcLoad.payload
} }
when(booted && (output.ready || corrected || pcRegPropagate)){ when(booted && (output.ready || corrected || pcRegPropagate)){
pcReg := pc pcReg := pc
} }
@ -231,6 +236,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val decompressor = ifGen(decodePcGen)(new Area{ val decompressor = ifGen(decodePcGen)(new Area{
def input = iBusRsp.output def input = iBusRsp.output
val output = Stream(FetchRsp()) val output = Stream(FetchRsp())
val flush = getFlushAt(DECOMPRESSOR)
val bufferValid = RegInit(False) val bufferValid = RegInit(False)
val bufferData = Reg(Bits(16 bits)) val bufferData = Reg(Bits(16 bits))
@ -248,7 +254,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
output.rsp.inst := isRvc ? decompressed | raw output.rsp.inst := isRvc ? decompressed | raw
input.ready := !output.valid || !(!output.ready || (isRvc && !input.pc(1) && input.rsp.inst(16, 2 bits) =/= 3) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3)) input.ready := !output.valid || !(!output.ready || (isRvc && !input.pc(1) && input.rsp.inst(16, 2 bits) =/= 3) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3))
addPrePopTask(() => { addPrePopTask(() => {
when(!input.ready && output.fire && !fetcherflushIt /* && ((isRvc && !bufferValid && !input.pc(1)) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3))*/) { when(!input.ready && output.fire && !flush /* && ((isRvc && !bufferValid && !input.pc(1)) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3))*/) {
input.pc.getDrivingReg(1) := True input.pc.getDrivingReg(1) := True
} }
}) })
@ -264,7 +270,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
} }
bufferData := input.rsp.inst(31 downto 16) bufferData := input.rsp.inst(31 downto 16)
} }
bufferValid.clearWhen(fetcherflushIt) bufferValid.clearWhen(flush)
iBusRsp.readyForError.clearWhen(bufferValid && isRvc) //Can't emit error, as there is a earlier instruction pending iBusRsp.readyForError.clearWhen(bufferValid && isRvc) //Can't emit error, as there is a earlier instruction pending
incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3) incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3)
}) })

View File

@ -46,7 +46,8 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
prediction = prediction, prediction = prediction,
historyRamSizeLog2 = historyRamSizeLog2, historyRamSizeLog2 = historyRamSizeLog2,
injectorStage = (!config.twoCycleCache && !withoutInjectorStage) || injectorStage, injectorStage = (!config.twoCycleCache && !withoutInjectorStage) || injectorStage,
relaxPredictorAddress = relaxPredictorAddress){ relaxPredictorAddress = relaxPredictorAddress,
fetchRedoGen = true){
import config._ import config._
assert(isPow2(cacheSize)) assert(isPow2(cacheSize))
@ -86,9 +87,6 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
FLUSH_ALL -> True FLUSH_ALL -> True
)) ))
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.decode, priority = 1) //Priority 1 will win against branch predictor
if(catchSomething) { if(catchSomething) {
val exceptionService = pipeline.service(classOf[ExceptionService]) val exceptionService = pipeline.service(classOf[ExceptionService])
decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1) decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1)
@ -238,9 +236,9 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
} }
redoBranch.valid := redoFetch fetchPc.redo.valid := redoFetch
redoBranch.payload := (if (decodePcGen) decode.input(PC) else cacheRsp.pc) fetchPc.redo.payload := iBusRsp.stages.last.input.payload
iBusRsp.fetchFlush setWhen(redoBranch.valid) iBusRsp.fetchFlush setWhen(redoFetch)
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt) cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)

View File

@ -245,13 +245,13 @@ class IBusSimplePlugin( resetVector : BigInt,
prediction = prediction, prediction = prediction,
historyRamSizeLog2 = historyRamSizeLog2, historyRamSizeLog2 = historyRamSizeLog2,
injectorStage = injectorStage, injectorStage = injectorStage,
relaxPredictorAddress = relaxPredictorAddress){ relaxPredictorAddress = relaxPredictorAddress,
fetchRedoGen = memoryTranslatorPortConfig != null){
var iBus : IBusSimpleBus = null var iBus : IBusSimpleBus = null
var decodeExceptionPort : Flow[ExceptionCause] = null var decodeExceptionPort : Flow[ExceptionCause] = null
val catchSomething = memoryTranslatorPortConfig != null || catchAccessFault val catchSomething = memoryTranslatorPortConfig != null || catchAccessFault
var mmuBus : MemoryTranslatorBus = null var mmuBus : MemoryTranslatorBus = null
var redoBranch : Flow[UInt] = null
if(rspHoldValue) assert(busLatencyMin <= 1) if(rspHoldValue) assert(busLatencyMin <= 1)
@ -268,7 +268,6 @@ class IBusSimplePlugin( resetVector : BigInt,
if(memoryTranslatorPortConfig != null) { if(memoryTranslatorPortConfig != null) {
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig) mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig)
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.decode, priority = 1) //Priority 1 will win against branch predictor
} }
} }
@ -379,12 +378,9 @@ class IBusSimplePlugin( resetVector : BigInt,
if(memoryTranslatorPortConfig != null){ if(memoryTranslatorPortConfig != null){
redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling) redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling)
redoBranch.valid := redoRequired && iBusRsp.readyForError fetchPc.redo.valid := redoRequired && iBusRsp.readyForError
redoBranch.payload := decode.input(PC) fetchPc.redo.payload := decode.input(PC)
iBusRsp.fetchFlush setWhen(fetchPc.redo.valid)
decode.arbitration.flushIt setWhen(redoBranch.valid)
decode.arbitration.flushNext setWhen(redoBranch.valid)
???
} }

View File

@ -102,9 +102,9 @@ class DhrystoneBench extends FunSuite{
getDmips( getDmips(
name = "GenLinuxBalenced", name = "GenLinuxBalenced",
gen = LinuxGen.main(Array.fill[String](0)("")), gen = LinuxGen.main(Array.fill[String](0)("")),
testCmd = "make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes MMU=no CSR=yes CSR_SKIP_TEST=yes DEBUG_PLUGIN=no COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=10 TRACE=no COREMARK=yes LINUX_REGRESSION=no" testCmd = "make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes MMU=no CSR=yes CSR_SKIP_TEST=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=10 TRACE=no COREMARK=yes LINUX_REGRESSION=no"
) )
//make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yess SUPERVISOR=yes CSR=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=1 TRACE=no LINUX_REGRESSION=yes SEED=42
test("final_report") { test("final_report") {