diff --git a/src/main/scala/vexriscv/demo/Linux.scala b/src/main/scala/vexriscv/demo/Linux.scala index 906b5b2..c13ef12 100644 --- a/src/main/scala/vexriscv/demo/Linux.scala +++ b/src/main/scala/vexriscv/demo/Linux.scala @@ -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( diff --git a/src/main/scala/vexriscv/plugin/Fetcher.scala b/src/main/scala/vexriscv/plugin/Fetcher.scala index 1fefe1a..79b8b07 100644 --- a/src/main/scala/vexriscv/plugin/Fetcher.scala +++ b/src/main/scala/vexriscv/plugin/Fetcher.scala @@ -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) }) diff --git a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala index 06ffa0a..537cb0f 100644 --- a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala @@ -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) diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index 0be4275..aa4fcb6 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -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) } diff --git a/src/test/scala/vexriscv/DhrystoneBench.scala b/src/test/scala/vexriscv/DhrystoneBench.scala index 1034aed..d23c4e1 100644 --- a/src/test/scala/vexriscv/DhrystoneBench.scala +++ b/src/test/scala/vexriscv/DhrystoneBench.scala @@ -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") {