From a5364ad00146899187e5be493652a4d5283a6871 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Fri, 19 May 2017 11:20:33 +0200 Subject: [PATCH] Add flush support instruction into the instruction cache --- .../scala/SpinalRiscv/Plugin/CsrPlugin.scala | 3 +- .../SpinalRiscv/Plugin/IBusCachedPlugin.scala | 30 +++++++++++++++++-- .../SpinalRiscv/Plugin/IBusSimplePlugin.scala | 2 -- .../SpinalRiscv/ip/InstructionCache.scala | 2 +- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/scala/SpinalRiscv/Plugin/CsrPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/CsrPlugin.scala index 82bf628..5110634 100644 --- a/src/main/scala/SpinalRiscv/Plugin/CsrPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/CsrPlugin.scala @@ -382,10 +382,11 @@ class CsrPlugin(config : MachineCsrConfig) extends Plugin[VexRiscv] with Excepti val imm = IMM(input(INSTRUCTION)) val writeSrc = input(INSTRUCTION)(14) ? imm.z.asBits.resized | input(SRC1) val readData = B(0, 32 bits) + def readDataReg = memory.input(REGFILE_WRITE_DATA) //PIPE OPT val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid && !memory.arbitration.isStuck) clearWhen(!arbitration.isStuck) val writeData = input(INSTRUCTION)(13).mux( False -> writeSrc, - True -> Mux(input(INSTRUCTION)(12), memory.input(REGFILE_WRITE_DATA) & ~writeSrc, memory.input(REGFILE_WRITE_DATA) | writeSrc) + True -> Mux(input(INSTRUCTION)(12), readDataReg & ~writeSrc, readDataReg | writeSrc) ) val writeOpcode = (!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0) || (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0))) diff --git a/src/main/scala/SpinalRiscv/Plugin/IBusCachedPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/IBusCachedPlugin.scala index af8da2c..ff061a1 100644 --- a/src/main/scala/SpinalRiscv/Plugin/IBusCachedPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/IBusCachedPlugin.scala @@ -15,10 +15,19 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B var decodeExceptionPort : Flow[ExceptionCause] = null var privilegeService : PrivilegeService = null - + object FLUSH_ALL extends Stageable(Bool) object IBUS_ACCESS_ERROR extends Stageable(Bool) override def setup(pipeline: VexRiscv): Unit = { - pipeline.unremovableStages += pipeline.prefetch + import Riscv._ + import pipeline.config._ + + def MANAGEMENT = M"-----------------100-----0001111" + + val decoderService = pipeline.service(classOf[DecoderService]) + decoderService.addDefault(FLUSH_ALL, False) + decoderService.add(MANAGEMENT, List( + FLUSH_ALL -> True + )) if(catchSomething) { val exceptionService = pipeline.service(classOf[ExceptionService]) @@ -68,7 +77,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B } } - cache.io.flush.cmd.valid := False + if(twoStageLogic){ cache.io.cpu.decode.isValid := decode.arbitration.isValid @@ -96,5 +105,20 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B decodeExceptionPort.code := mmuMiss ? U(14) | 1 decodeExceptionPort.badAddr := decode.input(PC) } + + memory plug new Area{ + import memory._ + + cache.io.flush.cmd.valid := False + when(arbitration.isValid && input(FLUSH_ALL)){ + cache.io.flush.cmd.valid := True + + when(!cache.io.flush.cmd.ready){ + arbitration.haltIt := True + } otherwise { + decode.arbitration.flushAll := True + } + } + } } } diff --git a/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala index ec0f4d1..4b4beca 100644 --- a/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala @@ -36,8 +36,6 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean) object IBUS_ACCESS_ERROR extends Stageable(Bool) var decodeExceptionPort : Flow[ExceptionCause] = null override def setup(pipeline: VexRiscv): Unit = { - pipeline.unremovableStages += pipeline.prefetch - if(catchAccessFault) { val exceptionService = pipeline.service(classOf[ExceptionService]) decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1) diff --git a/src/main/scala/SpinalRiscv/ip/InstructionCache.scala b/src/main/scala/SpinalRiscv/ip/InstructionCache.scala index dee517b..c8d149f 100644 --- a/src/main/scala/SpinalRiscv/ip/InstructionCache.scala +++ b/src/main/scala/SpinalRiscv/ip/InstructionCache.scala @@ -393,6 +393,6 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ lineLoader.requestIn.addr := mmuRsp.physicalAddress } - io.flush.cmd.ready := !(lineLoader.request.valid || io.cpu.fetch.isValid) + io.flush.cmd.ready := !(lineLoader.request.valid || io.cpu.fetch.isValid || (if(twoStageLogic) io.cpu.decode.isValid else False)) }