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,
// ucycleAccess = CsrAccess.NONE
// )),
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin(
earlyBranch = false,
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(

View File

@ -21,7 +21,8 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val prediction : BranchPrediction,
val historyRamSizeLog2 : Int,
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 decodePrediction : DecodePredictionBus = 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 pc = pcReg + (inc ## B"00").asUInt
// val predictionPcLoad = ifGen(prediction == DYNAMIC_TARGET) (Flow(UInt(32 bits)))
val redo = fetchRedoGen generate Flow(UInt(32 bits))
if(compressedGen) when(inc) {
pc(1) := False
}
if(fetchRedoGen) when(redo.valid){
corrected := True
pc := redo.payload
}
// if(predictionPcLoad != null) {
// when(predictionPcLoad.valid) {
// corrected := True
@ -147,7 +153,6 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
pc := jump.pcLoad.payload
}
when(booted && (output.ready || corrected || pcRegPropagate)){
pcReg := pc
}
@ -231,6 +236,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val decompressor = ifGen(decodePcGen)(new Area{
def input = iBusRsp.output
val output = Stream(FetchRsp())
val flush = getFlushAt(DECOMPRESSOR)
val bufferValid = RegInit(False)
val bufferData = Reg(Bits(16 bits))
@ -248,7 +254,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
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))
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
}
})
@ -264,7 +270,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
}
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
incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3)
})

View File

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

View File

@ -245,13 +245,13 @@ class IBusSimplePlugin( resetVector : BigInt,
prediction = prediction,
historyRamSizeLog2 = historyRamSizeLog2,
injectorStage = injectorStage,
relaxPredictorAddress = relaxPredictorAddress){
relaxPredictorAddress = relaxPredictorAddress,
fetchRedoGen = memoryTranslatorPortConfig != null){
var iBus : IBusSimpleBus = null
var decodeExceptionPort : Flow[ExceptionCause] = null
val catchSomething = memoryTranslatorPortConfig != null || catchAccessFault
var mmuBus : MemoryTranslatorBus = null
var redoBranch : Flow[UInt] = null
if(rspHoldValue) assert(busLatencyMin <= 1)
@ -268,7 +268,6 @@ class IBusSimplePlugin( resetVector : BigInt,
if(memoryTranslatorPortConfig != null) {
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){
redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling)
redoBranch.valid := redoRequired && iBusRsp.readyForError
redoBranch.payload := decode.input(PC)
decode.arbitration.flushIt setWhen(redoBranch.valid)
decode.arbitration.flushNext setWhen(redoBranch.valid)
???
fetchPc.redo.valid := redoRequired && iBusRsp.readyForError
fetchPc.redo.payload := decode.input(PC)
iBusRsp.fetchFlush setWhen(fetchPc.redo.valid)
}

View File

@ -102,9 +102,9 @@ class DhrystoneBench extends FunSuite{
getDmips(
name = "GenLinuxBalenced",
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") {