From 955e70206c646fc1a19f4605dd3363aa8eeee17e Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 26 Apr 2019 18:01:35 +0800 Subject: [PATCH 01/10] MmuPlugin: fix generation without writeBack stage If there is no writeBack stage, the elaboration step would hit a NullPointerException when trying to insert into the writeBack stage. Instead, pull from the most recent stage, which is where MMU access should reside. Signed-off-by: Sean Cross --- src/main/scala/vexriscv/plugin/MmuPlugin.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index ebf46c4..9dedde5 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -250,8 +250,9 @@ class MmuPlugin(ioRange : UInt => Bool, } } - writeBack plug new Area{ - import writeBack._ + val fenceStage = stages.last + fenceStage plug new Area{ + import fenceStage._ when(arbitration.isValid && input(IS_SFENCE_VMA)){ // || csrService.isWriting(CSR.SATP) for(port <- core.ports; line <- port.cache) line.valid := False //Assume that the instruction already fetched into the pipeline are ok } From b0199297fdc1d58793fa18fd0f81af03c6a8252d Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 26 Apr 2019 18:02:43 +0800 Subject: [PATCH 02/10] caches: work without writeBack stage In the case of an MMU miss, the data caches will create a retry branch port. These currently implicitly go into the memory/writeBack stage, however not all CPUs have this stage. Place the retry branch port into the correct stage. Signed-off-by: Sean Cross --- src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala | 2 +- src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 78af84f..b8f2ba1 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -143,7 +143,7 @@ class DBusCachedPlugin(config : DataCacheConfig, decoderService.add(FENCE, Nil) mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_DATA ,memoryTranslatorPortConfig) - redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.writeBack) + redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(if(pipeline.writeBack != null) pipeline.writeBack else pipeline.execute) if(catchSomething) exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.writeBack) diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index aba2e88..8d23548 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -309,7 +309,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, if(memoryTranslatorPortConfig != null) { mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_DATA, memoryTranslatorPortConfig) - redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.memory) + redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(if(pipeline.memory != null) pipeline.memory else pipeline.execute) } } From 0b79c637b672af5e0ff77b4dd7fe04859b34f419 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 20 Sep 2019 08:35:23 +0800 Subject: [PATCH 03/10] mulsimpleplugin: fix build for short pipelines Signed-off-by: Sean Cross --- src/main/scala/vexriscv/plugin/MulSimplePlugin.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala b/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala index 41ed391..1be6da7 100644 --- a/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala @@ -66,14 +66,16 @@ class MulSimplePlugin extends Plugin[VexRiscv]{ insert(MUL_OPB) := ((bSigned ? b.msb | False) ## b).asSInt } - memory plug new Area { - import memory._ + val injectionStage = if(pipeline.memory != null) pipeline.memory else pipeline.execute + injectionStage plug new Area { + import injectionStage._ insert(MUL) := (input(MUL_OPA) * input(MUL_OPB))(63 downto 0).asBits } - writeBack plug new Area { - import writeBack._ + val memStage = stages.last + memStage plug new Area { + import memStage._ when(arbitration.isValid && input(IS_MUL)){ switch(input(INSTRUCTION)(13 downto 12)){ From fdc95debef1e898e419d435cc73448073f86a547 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 20 Sep 2019 08:35:49 +0800 Subject: [PATCH 04/10] dbuscached: fix build for short pipelines Signed-off-by: Sean Cross --- .../vexriscv/plugin/DBusCachedPlugin.scala | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 10e4550..8b1ceb4 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -226,8 +226,10 @@ class DBusCachedPlugin(val config : DataCacheConfig, if(relaxedMemoryTranslationRegister) insert(MEMORY_VIRTUAL_ADDRESS) := cache.io.cpu.execute.address } - memory plug new Area{ - import memory._ + val flushStage = if(memory != null) memory else execute + flushStage plug new Area { + import flushStage._ + cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.memory.isStuck := arbitration.isStuck cache.io.cpu.memory.isRemoved := arbitration.removeIt @@ -237,8 +239,9 @@ class DBusCachedPlugin(val config : DataCacheConfig, cache.io.cpu.memory.mmuBus.rsp.isIoAccess setWhen(pipeline(DEBUG_BYPASS_CACHE) && !cache.io.cpu.memory.isWrite) } - writeBack plug new Area{ - import writeBack._ + val fenceStage = stages.last + fenceStage plug new Area{ + import fenceStage._ cache.io.cpu.writeBack.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.writeBack.isStuck := arbitration.isStuck cache.io.cpu.writeBack.isUser := (if(privilegeService != null) privilegeService.isUser() else False) @@ -323,10 +326,10 @@ class DBusCachedPlugin(val config : DataCacheConfig, execute.insert(IS_DBUS_SHARING) := dBusAccess.cmd.fire - mmuBus.cmd.bypassTranslation setWhen(memory.input(IS_DBUS_SHARING)) - cache.io.cpu.memory.isValid setWhen(memory.input(IS_DBUS_SHARING)) - cache.io.cpu.writeBack.isValid setWhen(writeBack.input(IS_DBUS_SHARING)) - dBusAccess.rsp.valid := writeBack.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt) + mmuBus.cmd.bypassTranslation setWhen(flushStage.input(IS_DBUS_SHARING)) + cache.io.cpu.memory.isValid setWhen(flushStage.input(IS_DBUS_SHARING)) + cache.io.cpu.writeBack.isValid setWhen(fenceStage.input(IS_DBUS_SHARING)) + dBusAccess.rsp.valid := fenceStage.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt) dBusAccess.rsp.data := cache.io.cpu.writeBack.data dBusAccess.rsp.error := cache.io.cpu.writeBack.unalignedAccess || cache.io.cpu.writeBack.accessError dBusAccess.rsp.redo := cache.io.cpu.redo @@ -334,10 +337,10 @@ class DBusCachedPlugin(val config : DataCacheConfig, when(forceDatapath){ execute.output(REGFILE_WRITE_DATA) := dBusAccess.cmd.address.asBits } - memory.input(IS_DBUS_SHARING) init(False) - writeBack.input(IS_DBUS_SHARING) init(False) + flushStage.input(IS_DBUS_SHARING) init(False) + fenceStage.input(IS_DBUS_SHARING) init(False) when(dBusAccess.rsp.valid){ - writeBack.input(IS_DBUS_SHARING).getDrivingReg := False + fenceStage.input(IS_DBUS_SHARING).getDrivingReg := False } } } From b8b053e706a66d4baf936d42104db43eab4fbf21 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 20 Sep 2019 08:36:01 +0800 Subject: [PATCH 05/10] muldiviterative: fix build for short pipelines Signed-off-by: Sean Cross --- src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala b/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala index f366854..11af4ab 100644 --- a/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala +++ b/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala @@ -69,8 +69,9 @@ class MulDivIterativePlugin(genMul : Boolean = true, import pipeline.config._ if(!genMul && !genDiv) return - memory plug new Area { - import memory._ + val flushStage = if(memory != null) memory else execute + flushStage plug new Area { + import flushStage._ //Shared ressources val rs1 = Reg(UInt(33 bits)) From e8236dfebed0a55a955f87223cf1ffffabee009d Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sat, 21 Sep 2019 12:49:46 +0200 Subject: [PATCH 06/10] Add MulSimplePlugin regressions --- .../scala/vexriscv/TestIndividualFeatures.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 33e4aa6..7c11b14 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -99,6 +99,22 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") { val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK) var l = List[VexRiscvPosition]() + + + + new VexRiscvPosition("MulDivFpgaSimple") { + override def testParam = "MUL=yes DIV=yes" + override def applyOn(config: VexRiscvConfig): Unit = { + config.plugins += new MulSimplePlugin + config.plugins += new MulDivIterativePlugin( + genMul = false, + genDiv = true, + mulUnrollFactor = 32, + divUnrollFactor = 1 + ) + } + } :: l + if(!noMemory) { l = new VexRiscvPosition("MulDivAsic") { override def testParam = "MUL=yes DIV=yes" From e1795e59d5660f627bfde5d13a1622866de8495f Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sat, 21 Sep 2019 13:00:54 +0200 Subject: [PATCH 07/10] Enable RF bypass on MUL DIV with pipeline wihout writeback/memory stages --- src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala | 2 +- src/main/scala/vexriscv/plugin/MulSimplePlugin.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala b/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala index 11af4ab..1bd8fb4 100644 --- a/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala +++ b/src/main/scala/vexriscv/plugin/MulDivIterativePlugin.scala @@ -31,7 +31,7 @@ class MulDivIterativePlugin(genMul : Boolean = true, SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.RS, REGFILE_WRITE_VALID -> True, - BYPASSABLE_EXECUTE_STAGE -> False, + BYPASSABLE_EXECUTE_STAGE -> Bool(pipeline.stages.last == pipeline.execute), BYPASSABLE_MEMORY_STAGE -> True, RS1_USE -> True, RS2_USE -> True diff --git a/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala b/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala index 1be6da7..3b407e1 100644 --- a/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala @@ -19,8 +19,8 @@ class MulSimplePlugin extends Plugin[VexRiscv]{ SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.RS, REGFILE_WRITE_VALID -> True, - BYPASSABLE_EXECUTE_STAGE -> False, - BYPASSABLE_MEMORY_STAGE -> False, + BYPASSABLE_EXECUTE_STAGE -> Bool(pipeline.stages.last == pipeline.execute), + BYPASSABLE_MEMORY_STAGE -> Bool(pipeline.stages.last == pipeline.memory), RS1_USE -> True, RS2_USE -> True, IS_MUL -> True From ace963b542b773584f45158339b3e48e355bee7a Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sat, 21 Sep 2019 14:13:28 +0200 Subject: [PATCH 08/10] Hazard on memory stage do not need to know if that's bypassable if the memory stage is the last one --- src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala b/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala index f674ae8..1ed1d83 100644 --- a/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala @@ -95,7 +95,7 @@ class HazardSimplePlugin(bypassExecute : Boolean = false, } if(withWriteBackStage) trackHazardWithStage(writeBack,bypassWriteBack,null) - if(withMemoryStage) trackHazardWithStage(memory ,bypassMemory ,BYPASSABLE_MEMORY_STAGE) + if(withMemoryStage) trackHazardWithStage(memory ,bypassMemory, if(stages.last == memory) null else BYPASSABLE_MEMORY_STAGE) if(readStage != execute) trackHazardWithStage(execute ,bypassExecute , if(stages.last == execute) null else BYPASSABLE_EXECUTE_STAGE) From bf82829e9edeb68545036bfbd8667bb8280bd465 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Mon, 23 Sep 2019 15:20:20 +0200 Subject: [PATCH 09/10] Data cache can now be used without writeback stage --- src/main/scala/vexriscv/ip/DataCache.scala | 19 +++++++---- .../vexriscv/plugin/DBusCachedPlugin.scala | 34 ++++++++++--------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index f692680..17c4bf6 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -24,8 +24,9 @@ case class DataCacheConfig(cacheSize : Int, earlyDataMux : Boolean = false, tagSizeShift : Int = 0, //Used to force infering ram withLrSc : Boolean = false, - withAmo : Boolean = false){ - + withAmo : Boolean = false, + mergeExecuteMemory : Boolean = false){ + assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits))) assert(!(earlyDataMux && !earlyWaysHits)) def burstSize = bytePerLine*8/memDataWidth val burstLength = bytePerLine/(memDataWidth/8) @@ -446,7 +447,7 @@ class DataCache(p : DataCacheConfig) extends Component{ } val stageA = new Area{ - def stagePipe[T <: Data](that : T) = RegNextWhen(that, !io.cpu.memory.isStuck) + def stagePipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.memory.isStuck) val request = stagePipe(io.cpu.execute.args) val mask = stagePipe(stage0.mask) io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid @@ -457,16 +458,22 @@ class DataCache(p : DataCacheConfig) extends Component{ val wayHits = earlyWaysHits generate ways.map(way => (io.cpu.memory.mmuBus.rsp.physicalAddress(tagRange) === way.tagsReadRsp.address && way.tagsReadRsp.valid)) val dataMux = earlyDataMux generate MuxOH(wayHits, ways.map(_.dataReadRsp)) - val colisions = stagePipe(stage0.colisions) | collisionProcess(io.cpu.memory.address(lineRange.high downto wordRange.low), mask) //Assume the writeback stage will never be unstall memory acces while memory stage is stalled + val colisions = if(mergeExecuteMemory){ + stagePipe(stage0.colisions) + } else { + //Assume the writeback stage will never be unstall memory acces while memory stage is stalled + stagePipe(stage0.colisions) | collisionProcess(io.cpu.memory.address(lineRange.high downto wordRange.low), mask) + } } val stageB = new Area { def stagePipe[T <: Data](that : T) = RegNextWhen(that, !io.cpu.writeBack.isStuck) + def ramPipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.writeBack.isStuck) val request = RegNextWhen(stageA.request, !io.cpu.writeBack.isStuck) val mmuRspFreeze = False val mmuRsp = RegNextWhen(io.cpu.memory.mmuBus.rsp, !io.cpu.writeBack.isStuck && !mmuRspFreeze) - val tagsReadRsp = ways.map(w => stagePipe(w.tagsReadRsp)) - val dataReadRsp = !earlyDataMux generate ways.map(w => stagePipe(w.dataReadRsp)) + val tagsReadRsp = ways.map(w => ramPipe(w.tagsReadRsp)) + val dataReadRsp = !earlyDataMux generate ways.map(w => ramPipe(w.dataReadRsp)) val waysHits = if(earlyWaysHits) stagePipe(B(stageA.wayHits)) else B(tagsReadRsp.map(tag => mmuRsp.physicalAddress(tagRange) === tag.address && tag.valid).asBits()) val waysHit = waysHits.orR val dataMux = if(earlyDataMux) stagePipe(stageA.dataMux) else MuxOH(waysHits, dataReadRsp) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 8b1ceb4..9102a72 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -148,7 +148,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(if(pipeline.writeBack != null) pipeline.writeBack else pipeline.execute) if(catchSomething) - exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.writeBack) + exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(if(pipeline.writeBack == null) pipeline.memory else pipeline.writeBack) if(pipeline.serviceExist(classOf[PrivilegeService])) privilegeService = pipeline.service(classOf[PrivilegeService]) @@ -162,7 +162,9 @@ class DBusCachedPlugin(val config : DataCacheConfig, dBus = master(DataCacheMemBus(this.config)).setName("dBus") - val cache = new DataCache(this.config) + val cache = new DataCache(this.config.copy( + mergeExecuteMemory = writeBack == null + )) //Interconnect the plugin dBus with the cache dBus with some optional pipelining def optionPipe[T](cond : Boolean, on : T)(f : T => T) : T = if(cond) f(on) else on @@ -226,22 +228,22 @@ class DBusCachedPlugin(val config : DataCacheConfig, if(relaxedMemoryTranslationRegister) insert(MEMORY_VIRTUAL_ADDRESS) := cache.io.cpu.execute.address } - val flushStage = if(memory != null) memory else execute - flushStage plug new Area { - import flushStage._ + val mmuAndBufferStage = if(writeBack != null) memory else execute + mmuAndBufferStage plug new Area { + import mmuAndBufferStage._ cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.memory.isStuck := arbitration.isStuck cache.io.cpu.memory.isRemoved := arbitration.removeIt - cache.io.cpu.memory.address := (if(relaxedMemoryTranslationRegister) input(MEMORY_VIRTUAL_ADDRESS) else U(input(REGFILE_WRITE_DATA))) + cache.io.cpu.memory.address := (if(relaxedMemoryTranslationRegister) input(MEMORY_VIRTUAL_ADDRESS) else if(mmuAndBufferStage == execute) cache.io.cpu.execute.address else U(input(REGFILE_WRITE_DATA))) cache.io.cpu.memory.mmuBus <> mmuBus cache.io.cpu.memory.mmuBus.rsp.isIoAccess setWhen(pipeline(DEBUG_BYPASS_CACHE) && !cache.io.cpu.memory.isWrite) } - val fenceStage = stages.last - fenceStage plug new Area{ - import fenceStage._ + val managementStage = stages.last + managementStage plug new Area{ + import managementStage._ cache.io.cpu.writeBack.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.writeBack.isStuck := arbitration.isStuck cache.io.cpu.writeBack.isUser := (if(privilegeService != null) privilegeService.isUser() else False) @@ -326,10 +328,10 @@ class DBusCachedPlugin(val config : DataCacheConfig, execute.insert(IS_DBUS_SHARING) := dBusAccess.cmd.fire - mmuBus.cmd.bypassTranslation setWhen(flushStage.input(IS_DBUS_SHARING)) - cache.io.cpu.memory.isValid setWhen(flushStage.input(IS_DBUS_SHARING)) - cache.io.cpu.writeBack.isValid setWhen(fenceStage.input(IS_DBUS_SHARING)) - dBusAccess.rsp.valid := fenceStage.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt) + mmuBus.cmd.bypassTranslation setWhen(mmuAndBufferStage.input(IS_DBUS_SHARING)) + if(mmuAndBufferStage != execute) (cache.io.cpu.memory.isValid setWhen(mmuAndBufferStage.input(IS_DBUS_SHARING))) + cache.io.cpu.writeBack.isValid setWhen(managementStage.input(IS_DBUS_SHARING)) + dBusAccess.rsp.valid := managementStage.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt) dBusAccess.rsp.data := cache.io.cpu.writeBack.data dBusAccess.rsp.error := cache.io.cpu.writeBack.unalignedAccess || cache.io.cpu.writeBack.accessError dBusAccess.rsp.redo := cache.io.cpu.redo @@ -337,10 +339,10 @@ class DBusCachedPlugin(val config : DataCacheConfig, when(forceDatapath){ execute.output(REGFILE_WRITE_DATA) := dBusAccess.cmd.address.asBits } - flushStage.input(IS_DBUS_SHARING) init(False) - fenceStage.input(IS_DBUS_SHARING) init(False) + if(mmuAndBufferStage != execute) mmuAndBufferStage.input(IS_DBUS_SHARING) init(False) + managementStage.input(IS_DBUS_SHARING) init(False) when(dBusAccess.rsp.valid){ - fenceStage.input(IS_DBUS_SHARING).getDrivingReg := False + managementStage.input(IS_DBUS_SHARING).getDrivingReg := False } } } From 49944643d222fc72b800bb2fa1880f6ef91618c6 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Mon, 23 Sep 2019 15:20:51 +0200 Subject: [PATCH 10/10] Add regression for data cache without writeback stage, seem to pass tests, including linux ones --- .../vexriscv/TestIndividualFeatures.scala | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 7c11b14..efa975c 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -392,7 +392,7 @@ class DBusDimension extends VexRiscvDimension("DBus") { - if(r.nextDouble() < 0.4 || noMemory || noWriteBack){ + if(r.nextDouble() < 0.4 || noMemory){ val withLrSc = catchAll val earlyInjection = r.nextBoolean() && !universes.contains(VexRiscvUniverse.NO_WRITEBACK) new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) { @@ -412,7 +412,8 @@ class DBusDimension extends VexRiscvDimension("DBus") { var wayCount = 0 val withLrSc = catchAll val withAmo = catchAll && r.nextBoolean() - val dBusRspSlavePipe, relaxedMemoryTranslationRegister, earlyWaysHits = r.nextBoolean() + val dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean() + val earlyWaysHits = r.nextBoolean() && !noWriteBack val dBusCmdMasterPipe, dBusCmdSlavePipe = false //As it create test bench issues do{ @@ -616,11 +617,11 @@ class TestIndividualFeatures extends FunSuite { val testId : Option[mutable.HashSet[Int]] = None val seed = sys.env.getOrElse("VEXRISCV_REGRESSION_SEED", Random.nextLong().toString).toLong - +// // val testId = Some(mutable.HashSet(3,4,9,11,13,16,18,19,20,21)) -// val testId = Some(mutable.HashSet(24, 43, 49)) -// val testId = Some(mutable.HashSet(11)) -// val seed = -8309068850561113754l +// val testId = Some(mutable.HashSet(22)) +// val testId = Some(mutable.HashSet(22, 33 , 38, 47, 48)) +// val seed = 5426556825163943143l val rand = new Random(seed) @@ -638,11 +639,16 @@ class TestIndividualFeatures extends FunSuite { universe += VexRiscvUniverse.MMU universe += VexRiscvUniverse.FORCE_MULDIV universe += VexRiscvUniverse.SUPERVISOR + if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble < rand.nextDouble()){ + universe += VexRiscvUniverse.NO_WRITEBACK + } } else { if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble > rand.nextDouble()) { universe += VexRiscvUniverse.CATCH_ALL + if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble < rand.nextDouble()){ + universe += VexRiscvUniverse.NO_WRITEBACK + } } - var tmp = rand.nextDouble() if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble > rand.nextDouble()){ }else if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEM_RATE", "0.5").toDouble > rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK