diff --git a/src/main/scala/vexriscv/plugin/Fetcher.scala b/src/main/scala/vexriscv/plugin/Fetcher.scala index 986502e..8e9fbdc 100644 --- a/src/main/scala/vexriscv/plugin/Fetcher.scala +++ b/src/main/scala/vexriscv/plugin/Fetcher.scala @@ -114,10 +114,22 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, //PC calculation without Jump val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public) val inc = RegInit(False) + val propagatePc = False val pc = pcReg + (inc ## B"00").asUInt val samplePcNext = False + if(compressedGen) { + when(inc) { + pc(1) := False + } + } + + when(propagatePc){ + samplePcNext := True + inc := False + } + if(predictionPcLoad != null) { when(predictionPcLoad.valid) { inc := False @@ -142,14 +154,6 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, pcReg := pc } - if(compressedGen) { - when(preOutput.fire) { - pcReg(1 downto 0) := 0 - when(pc(1)){ - inc := True - } - } - } preOutput.valid := RegNext(True) init (False) preOutput.payload := pc @@ -217,7 +221,13 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, } for((s,sNext) <- (stages, stages.tail).zipped) { - sNext.input << s.output.m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false) + if(s == stages.head) { + sNext.input.arbitrationFrom(s.output.toEvent().m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false)) + sNext.input.payload := fetchPc.pcReg + fetchPc.propagatePc setWhen(sNext.input.fire) + } else { + sNext.input << s.output.m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false) + } } // @@ -310,7 +320,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, }).tail } - val nextPcCalc = if (decodePcGen) { + val nextPcCalc = if (decodePcGen) new Area{ val valids = pcUpdatedGen(True, False :: List(execute, memory, writeBack).map(_.arbitration.isStuck), true) pcValids := Vec(valids.takeRight(4)) } else new Area{ diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index 6e415c0..e63ec98 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -151,8 +151,7 @@ class IBusSimplePlugin(resetVector : BigInt, compressedGen : Boolean = false, busLatencyMin : Int = 1, pendingMax : Int = 7, - injectorStage : Boolean = true, - relaxedBusCmdValid : Boolean = false + injectorStage : Boolean = true ) extends IBusFetcherImpl( catchAccessFault = catchAccessFault, resetVector = resetVector, @@ -164,8 +163,6 @@ class IBusSimplePlugin(resetVector : BigInt, prediction = prediction, historyRamSizeLog2 = historyRamSizeLog2, injectorStage = injectorStage){ - assert(!(prediction == DYNAMIC_TARGET && relaxedBusCmdValid), "IBusSimplePlugin doesn't allow dynamic_target prediction and relaxedBusCmdValid together") - assert(!relaxedBusCmdValid) var iBus : IBusSimpleBus = null var decodeExceptionPort : Flow[ExceptionCause] = null @@ -185,44 +182,23 @@ class IBusSimplePlugin(resetVector : BigInt, import pipeline.config._ pipeline plug new FetchArea(pipeline) { - - - //Avoid sending to many iBus cmd val pendingCmd = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0) val pendingCmdNext = pendingCmd + iBus.cmd.fire.asUInt - iBus.rsp.fire.asUInt pendingCmd := pendingCmdNext - val cmd = if(relaxedBusCmdValid) new Area { - ??? - /* def inputStage = iBusRsp.stages(0) - val busFork = Stream(UInt(32 bits)) - val busForkedReg = RegInit(False) - if(!relaxedPcCalculation) busForkedReg clearWhen(flush) - busForkedReg setWhen(iBus.cmd.fire) - busForkedReg clearWhen(inputStage.output.ready) - if(relaxedPcCalculation) busForkedReg clearWhen(flush) - val busForked = Bool - busForked := (if(!relaxedPcCalculation) (busForkedReg && !flush) else (busForkedReg)) - - - busFork.valid := inputStage.input.valid && !busForkedReg - busFork.payload := inputStage.input.payload - - inputStage.halt setWhen() - output.valid := (inputStage.input.valid && iBus.cmd.fire) || busForked - output.payload := input.payload - input.ready := output.fire - - - val okBus = pendingCmd =/= pendingMax - iBus.cmd.valid := busFork.valid && okBus - iBus.cmd.pc := busFork.payload(31 downto 2) @@ "00" - busFork.ready := iBus.cmd.ready && okBus*/ - } else new Area { + val cmd = /*if(relaxedPcCalculation) new Area { + //This implementation keep the iBus.cmd on the bus until it's executed, even if the pipeline is flushed + def stage = iBusRsp.stages(1) + stage.halt setWhen(iBus.cmd.isStall) + val cmdKeep = RegInit(False) setWhen(iBus.cmd.valid) clearWhen(iBus.cmd.ready) + val cmdFired = RegInit(False) setWhen(iBus.cmd.fire) clearWhen(stage.input.ready) + iBus.cmd.valid := (stage.input.valid || cmdKeep) && pendingCmd =/= pendingMax && !cmdFired + iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00" + } else */new Area { + //This implementation keep the iBus.cmd on the bus until it's executed or the the pipeline is flushed (not "safe") def stage = iBusRsp.stages(if(relaxedPcCalculation) 1 else 0) stage.halt setWhen(stage.input.valid && (!iBus.cmd.valid || !iBus.cmd.ready)) - iBus.cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00" } @@ -235,10 +211,11 @@ class IBusSimplePlugin(resetVector : BigInt, val discardCounter = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0) discardCounter := discardCounter - (iBus.rsp.fire && discardCounter =/= 0).asUInt when(flush) { +// discardCounter := (if(relaxedPcCalculation) pendingCmd + iBus.cmd.valid.asUInt - iBus.rsp.fire.asUInt else pendingCmd - iBus.rsp.fire.asUInt) discardCounter := (if(relaxedPcCalculation) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt) } - val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), cmdToRspStageCount - (if(relaxedPcCalculation) 0 else 0)) + val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), busLatencyMin) rspBuffer.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream rspBuffer.io.flush := flush @@ -249,8 +226,11 @@ class IBusSimplePlugin(resetVector : BigInt, var issueDetected = False - val join = StreamJoin(Seq(stages.last.output, rspBuffer.io.pop), fetchRsp) - stages.last.output.ready setWhen(!stages.last.output.valid) + val join = Stream(FetchRsp()) + join.valid := stages.last.output.valid && rspBuffer.io.pop.valid + join.payload := fetchRsp + stages.last.output.ready := stages.last.output.valid ? join.fire | join.ready + rspBuffer.io.pop.ready := join.fire output << join.haltWhen(issueDetected) if(catchAccessFault){ diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 721c588..012680c 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -718,11 +718,6 @@ public: logTraces.open (name + ".logTrace"); fillSimELements(); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); - - //Sync register file initial content - for(int i = 1;i < 32;i++){ - riscvRef.regs[i] = top->VexRiscv->RegFilePlugin_regFile[i]; - } } virtual ~Workspace(){ @@ -921,6 +916,10 @@ public: postReset(); + //Sync register file initial content + for(int i = 1;i < 32;i++){ + riscvRef.regs[i] = top->VexRiscv->RegFilePlugin_regFile[i]; + } resetDone = true; #ifdef REF