diff --git a/src/main/scala/vexriscv/Services.scala b/src/main/scala/vexriscv/Services.scala index e764b3b..2b9bc00 100644 --- a/src/main/scala/vexriscv/Services.scala +++ b/src/main/scala/vexriscv/Services.scala @@ -13,6 +13,7 @@ trait JumpService{ trait IBusFetcher{ def haltIt() : Unit + def incoming() : Bool def nextPc() : (Bool, UInt) def getInjectionPort() : Stream[Bits] } diff --git a/src/main/scala/vexriscv/TestsWorkspace.scala b/src/main/scala/vexriscv/TestsWorkspace.scala index 8dd1085..bcd5b7b 100644 --- a/src/main/scala/vexriscv/TestsWorkspace.scala +++ b/src/main/scala/vexriscv/TestsWorkspace.scala @@ -53,9 +53,9 @@ object TestsWorkspace { // asyncTagMemory = false, // twoCycleRam = false // )//, -// memoryTranslatorPortConfig = MemoryTranslatorPortConfig( -// portTlbSize = 4 -// ) +//// memoryTranslatorPortConfig = MemoryTranslatorPortConfig( +//// portTlbSize = 4 +//// ) // ), // new DBusSimplePlugin( // catchAddressMisaligned = true, diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 82d1f88..96abb1e 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -377,10 +377,9 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio val pipelineLiberator = new Area{ val enable = False.noBackendCombMerge //Verilator Perf when(enable){ - fetcher.haltIt() + decode.arbitration.haltByOther := True } val done = ! List(execute, memory, writeBack).map(_.arbitration.isValid).orR && !fetcher.nextPc()._1 -// val done = History(doneAsync, 0 to 0).andR } @@ -392,7 +391,10 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio val exceptionValidsRegs = Vec(Reg(Bool) init(False), stages.length).allowUnsetRegToAvoidLatch val exceptionContext = Reg(ExceptionCause()) - pipelineLiberator.enable setWhen(exceptionValidsRegs.orR) + //Assume 2 stages before decode + when(exceptionValidsRegs.drop(1).orR) { + decode.arbitration.haltByOther := True + } val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => { val stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority) @@ -418,9 +420,9 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio if(indexOf(stage) != 0) stages(indexOf(stage) - 1).arbitration.flushAll := True stage.arbitration.removeIt := True exceptionValids(stageId) := True - when(!exceptionValidsRegs.takeRight(stages.length-stageId-1).fold(False)(_ || _)) { - exceptionContext := port.payload - } +// when(!exceptionValidsRegs.takeRight(stages.length-stageId-1).fold(False)(_ || _)) { + exceptionContext := port.payload +// } } } for(stageId <- firstStageIndexWithExceptionPort until stages.length; stage = stages(stageId) ){ @@ -487,11 +489,11 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio //Interrupt/Exception entry logic pipelineLiberator.enable setWhen(interrupt) - if(exceptionPortCtrl != null) { - when(exception) { - exceptionPortCtrl.exceptionValidsRegs.foreach(_ := False) - } - } +// if(exceptionPortCtrl != null) { +// when(exception) { +// exceptionPortCtrl.exceptionValidsRegs.foreach(_ := False) +// } +// } when(exception || (interrupt && pipelineLiberator.done)){ jumpInterface.valid := True jumpInterface.payload := mtvec diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index bef8fbc..450b745 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -210,11 +210,15 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w // }) // - when(execute.arbitration.isFiring && execute.input(IS_EBREAK)) { - decode.arbitration.haltByOther := True - decode.arbitration.flushAll := True - haltIt := True - haltedByBreak := True + when(execute.input(IS_EBREAK)){ + when(execute.arbitration.isValid ) { + iBusFetcher.haltIt() + decode.arbitration.flushAll := True + } + when(execute.arbitration.isFiring) { + haltIt := True + haltedByBreak := True + } } when(haltIt) { @@ -222,8 +226,11 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w // decode.arbitration.haltByOther := True } - when(stepIt && decode.arbitration.isFiring) { - haltIt := True + when(stepIt && iBusFetcher.incoming()) { + iBusFetcher.haltIt() + when(decode.arbitration.isValid) { + haltIt := True + } } when(stepIt && Cat(pipeline.stages.map(_.arbitration.redoIt)).asBits.orR) { haltIt := False diff --git a/src/main/scala/vexriscv/plugin/Fetcher.scala b/src/main/scala/vexriscv/plugin/Fetcher.scala index 2a50962..1b91a62 100644 --- a/src/main/scala/vexriscv/plugin/Fetcher.scala +++ b/src/main/scala/vexriscv/plugin/Fetcher.scala @@ -30,6 +30,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, lazy val decodeNextPcValid = Bool //TODO remove me ? lazy val decodeNextPc = UInt(32 bits) def nextPc() = (False, decodeNextPc) + var incomingInstruction : Bool = null + override def incoming() = incomingInstruction var injectionPort : Stream[Bits] = null override def getInjectionPort() = { @@ -53,6 +55,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, // var decodeExceptionPort : Flow[ExceptionCause] = null override def setup(pipeline: VexRiscv): Unit = { fetcherHalt = False + incomingInstruction = False if(catchAccessFault || catchAddressMisaligned) { val exceptionService = pipeline.service(classOf[ExceptionService]) // decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1).setName("iBusErrorExceptionnPort") @@ -94,7 +97,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, def flush = killLastStage class PcFetch extends Area{ - val output = Stream(UInt(32 bits)) + val preOutput = Stream(UInt(32 bits)) + val output = preOutput.haltWhen(fetcherHalt) } val fetchPc = if(relaxedPcCalculation) new PcFetch { @@ -102,13 +106,13 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, val pcReg = Reg(UInt(32 bits)) init (resetVector) addAttribute (Verilator.public) val pcPlus4 = pcReg + 4 if (keepPcPlus4) KeepAttribute(pcPlus4) - when(output.fire) { + when(preOutput.fire) { pcReg := pcPlus4 } //Realign if(compressedGen){ - when(output.fire){ + when(preOutput.fire){ pcReg(1 downto 0) := 0 } } @@ -118,8 +122,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, pcReg := jump.pcLoad.payload } - output.valid := RegNext(True) init (False) // && !jump.pcLoad.valid - output.payload := pcReg + preOutput.valid := RegNext(True) init (False) // && !jump.pcLoad.valid + preOutput.payload := pcReg } else new PcFetch{ //PC calculation without Jump val pcReg = Reg(UInt(32 bits)) init(resetVector) addAttribute(Verilator.public) @@ -135,7 +139,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, } - when(output.fire){ + when(preOutput.fire){ inc := True samplePcNext := True } @@ -146,7 +150,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, } if(compressedGen) { - when(output.fire) { + when(preOutput.fire) { pcReg(1 downto 0) := 0 when(pc(1)){ inc := True @@ -154,8 +158,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, } } - output.valid := RegNext(True) init (False) - output.payload := pc + preOutput.valid := RegNext(True) init (False) + preOutput.payload := pc } val decodePc = ifGen(decodePcGen)(new Area { @@ -199,8 +203,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, for(i <- 0 until cmdToRspStageCount) { // val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush inputPipeline(i) << {i match { - case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation) - case _ => inputPipeline(i-1)/*.haltWhen(fetcherHalt)*/.m2sPipeWithFlush(flush) + case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation, collapsBubble = false) + case _ => inputPipeline(i-1)/*.haltWhen(fetcherHalt)*/.m2sPipeWithFlush(flush,collapsBubble = false) }} } @@ -208,8 +212,9 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, val readyForError = True val outputBeforeStage = Stream(FetchRsp()) - val output = if(rspStageGen) outputBeforeStage.m2sPipeWithFlush(flush) else outputBeforeStage + val output = if(rspStageGen) outputBeforeStage.m2sPipeWithFlush(flush, collapsBubble = false) else outputBeforeStage if(rspStageGen) readyForError.clearWhen(output.valid) + incomingInstruction setWhen(inputPipeline.map(_.valid).orR) } val decompressor = ifGen(decodePcGen)(new Area{ @@ -242,21 +247,26 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean, } bufferValid.clearWhen(flush) iBusRsp.readyForError.clearWhen(bufferValid && isRvc) + incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3) }) //TODO never colalpse buble of the last stage def condApply[T](that : T, cond : Boolean)(func : (T) => T) = if(cond)func(that) else that val injector = new Area { val inputBeforeHalt = condApply(if(decodePcGen) decompressor.output else iBusRsp.output, injectorReadyCutGen)(_.s2mPipe(flush)) - if(injectorReadyCutGen) iBusRsp.readyForError.clearWhen(inputBeforeHalt.valid) + if(injectorReadyCutGen) { + iBusRsp.readyForError.clearWhen(inputBeforeHalt.valid) + incomingInstruction setWhen(inputBeforeHalt.valid) + } val decodeInput = (if(injectorStage){ val decodeInput = inputBeforeHalt.m2sPipeWithFlush(killLastStage, collapsBubble = false) decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), inputBeforeHalt.rsp.inst) iBusRsp.readyForError.clearWhen(decodeInput.valid) + incomingInstruction setWhen(decodeInput.valid) decodeInput } else { inputBeforeHalt - }).haltWhen(fetcherHalt) + }) if(decodePcGen){ decodeNextPcValid := True diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index b965819..d149bf7 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -169,6 +169,7 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean, val join = StreamJoin(Seq(inputPipeline.last, rspBuffer.io.pop), fetchRsp) + inputPipeline.last.ready setWhen(!inputPipeline.last.valid) output << (if(rspStageGen) join.m2sPipeWithFlush(flush) else join) } } diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index ceb88b2..f89393b 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -1502,25 +1502,25 @@ public: while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);} if((readValue = readCmd(2,debugAddress + 4)) != 0x8000000C){ - printf("wrong break PC %x\n",readValue); + printf("wrong breakA PC %x\n",readValue); clientFail = true; return; } writeCmd(2, debugAddress + 4, 0x13 + (1 << 15)); //Read regfile if((readValue = readCmd(2,debugAddress + 4)) != 10){ - printf("wrong break PC %x\n",readValue); + printf("wrong breakB PC %x\n",readValue); clientFail = true; return; } writeCmd(2, debugAddress + 4, 0x13 + (2 << 15)); //Read regfile if((readValue = readCmd(2,debugAddress + 4)) != 20){ - printf("wrong break PC %x\n",readValue); + printf("wrong breakC PC %x\n",readValue); clientFail = true; return; } writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read regfile if((readValue = readCmd(2,debugAddress + 4)) != 30){ - printf("wrong break PC %x\n",readValue); + printf("wrong breakD PC %x\n",readValue); clientFail = true; return; } @@ -1532,7 +1532,7 @@ public: while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);} if((readValue = readCmd(2,debugAddress + 4)) != 0x80000014){ - printf("wrong break PC 3 %x\n",readValue); + printf("wrong breakE PC 3 %x\n",readValue); clientFail = true; return; } @@ -1553,7 +1553,7 @@ public: while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);} if((readValue = readCmd(2,debugAddress + 4)) != 0x80000024){ - printf("wrong break PC 3 %x\n",readValue); + printf("wrong breakF PC 3 %x\n",readValue); clientFail = true; return; } diff --git a/src/test/python/tool/disasm.s b/src/test/python/tool/disasm.s index 2e7ea78..4e1f43f 100644 --- a/src/test/python/tool/disasm.s +++ b/src/test/python/tool/disasm.s @@ -1 +1 @@ -.word 0xc12083 +.word 0x8067