diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index a2e43aa..17766c2 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -207,12 +207,14 @@ case class DataCacheCpuBus(p : DataCacheConfig, mmu : MemoryTranslatorBusParamet val redo = Bool() val flush = Stream(DataCacheFlush(p.lineCount)) + val writesPending = Bool() + override def asMaster(): Unit = { master(execute) master(memory) master(writeBack) master(flush) - in(redo) + in(redo, writesPending) } } @@ -717,6 +719,8 @@ class DataCache(val p : DataCacheConfig, mmuParameter : MemoryTranslatorBusParam } val uncached = history.readAsync(rPtr.resized) val full = RegNext(wPtr - rPtr >= pendingMax-1) + val empty = wPtr === rPtr + io.cpu.writesPending := !empty io.cpu.execute.haltIt setWhen(full) } diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 8733901..2204a65 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -497,7 +497,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep object ENV_CTRL extends Stageable(EnvCtrlEnum()) object IS_CSR extends Stageable(Bool) - object IS_SFENCE_VMA extends Stageable(Bool) + object RESCHEDULE_NEXT extends Stageable(Bool) object CSR_WRITE_OPCODE extends Stageable(Bool) object CSR_READ_OPCODE extends Stageable(Bool) object PIPELINED_CSR_READ extends Stageable(Bits(32 bits)) @@ -639,8 +639,9 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep if(utimeAccess != CsrAccess.NONE) utime = in UInt(64 bits) setName("utime") if(supervisorGen) { - decoderService.addDefault(IS_SFENCE_VMA, False) - decoderService.add(SFENCE_VMA, List(IS_SFENCE_VMA -> True)) + decoderService.addDefault(RESCHEDULE_NEXT, False) + decoderService.add(SFENCE_VMA, List(RESCHEDULE_NEXT -> True)) + decoderService.add(FENCE_I, List(RESCHEDULE_NEXT -> True)) } xretAwayFromMachine = False @@ -1143,7 +1144,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep redoInterface.payload := decode.input(PC) val rescheduleNext = False - when(execute.arbitration.isValid && execute.input(IS_SFENCE_VMA)) { rescheduleNext := True } + when(execute.arbitration.isValid && execute.input(RESCHEDULE_NEXT)) { rescheduleNext := True } duringWrite(CSR.SATP) { rescheduleNext := True } when(rescheduleNext){ @@ -1581,7 +1582,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep if(!pipelineCsrRead) output(REGFILE_WRITE_DATA) := readData } - when(arbitration.isValid && (input(IS_CSR) || (if(supervisorGen) input(IS_SFENCE_VMA) else False))) { + when(arbitration.isValid && (input(IS_CSR) || (if(supervisorGen) input(RESCHEDULE_NEXT) else False))) { arbitration.haltItself setWhen(blockedBySideEffects) } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index ea34213..623add8 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -160,6 +160,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, object MEMORY_LRSC extends Stageable(Bool) object MEMORY_AMO extends Stageable(Bool) object MEMORY_FENCE extends Stageable(Bool) + object MEMORY_FENCE_WR extends Stageable(Bool) object MEMORY_FORCE_CONSTISTENCY extends Stageable(Bool) object IS_DBUS_SHARING extends Stageable(Bool()) object MEMORY_VIRTUAL_ADDRESS extends Stageable(UInt(32 bits)) @@ -267,6 +268,8 @@ class DBusCachedPlugin(val config : DataCacheConfig, case true => { decoderService.addDefault(MEMORY_FENCE, False) decoderService.add(FENCE, List(MEMORY_FENCE -> True)) + decoderService.addDefault(MEMORY_FENCE_WR, False) + decoderService.add(FENCE_I, List(MEMORY_FENCE_WR -> True)) } } @@ -405,6 +408,12 @@ class DBusCachedPlugin(val config : DataCacheConfig, ) } + if(withWriteResponse){ + when(arbitration.isValid && input(MEMORY_FENCE_WR) && cache.io.cpu.writesPending){ + arbitration.haltItself := True + } + } + if(tightlyGen){ tightlyCoupledAddressStage match { case false =>