diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 78f9607..f712606 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -30,6 +30,7 @@ case class DataCacheConfig(cacheSize : Int, pendingMax : Int = 32, directTlbHit : Boolean = false, mergeExecuteMemory : Boolean = false, + asyncTagMemory : Boolean = false, aggregationWidth : Int = 0){ assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits))) assert(!(earlyDataMux && !earlyWaysHits)) @@ -591,12 +592,18 @@ class DataCache(val p : DataCacheConfig, mmuParameter : MemoryTranslatorBusParam val data = Mem(Bits(memDataWidth bit), wayMemWordCount) //Reads - val tagsReadRsp = tags.readSync(tagsReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck) + val tagsReadRsp = asyncTagMemory match { + case false => tags.readSync(tagsReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck) + case true => tags.readAsync(RegNextWhen(tagsReadCmd.payload, io.cpu.execute.isValid && !io.cpu.memory.isStuck)) + } val dataReadRspMem = data.readSync(dataReadCmd.payload, dataReadCmd.valid && !io.cpu.memory.isStuck) val dataReadRspSel = if(mergeExecuteMemory) io.cpu.writeBack.address else io.cpu.memory.address val dataReadRsp = dataReadRspMem.subdivideIn(cpuDataWidth bits).read(dataReadRspSel(memWordToCpuWordRange)) - val tagsInvReadRsp = withInvalidate generate tags.readSync(tagsInvReadCmd.payload, tagsInvReadCmd.valid) + val tagsInvReadRsp = withInvalidate generate(asyncTagMemory match { + case false => tags.readSync(tagsInvReadCmd.payload, tagsInvReadCmd.valid) + case true => tags.readAsync(RegNextWhen(tagsInvReadCmd.payload, tagsInvReadCmd.valid)) + }) //Writes when(tagsWriteCmd.valid && tagsWriteCmd.way(i)){ diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 6139bad..628e057 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -351,6 +351,7 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") { } } else { val twoStageMmu = r.nextBoolean() + val asyncTagMemory = r.nextBoolean() val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig(portTlbSize = 4, latency = if(twoStageMmu) 1 else 0, earlyRequireMmuLockup = Random.nextBoolean() && twoStageMmu, earlyCacheHits = Random.nextBoolean() && twoStageMmu) else null val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) @@ -371,7 +372,7 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") { wayCount = 1 << r.nextInt(3) }while(cacheSize/wayCount < 512 || (catchAll && cacheSize/wayCount > 4096)) - new VexRiscvPosition(s"Cached${memDataWidth}d" + (if(twoCycleCache) "2cc" else "") + (if(injectorStage) "Injstage" else "") + (if(twoCycleRam) "2cr" else "") + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(relaxedPcCalculation) "Relax" else "") + (if(compressed) "Rvc" else "") + prediction.getClass.getTypeName().replace("$","")+ (if(tighlyCoupled)"Tc" else "")) with InstructionAnticipatedPosition{ + new VexRiscvPosition(s"Cached${memDataWidth}d" + (if(twoCycleCache) "2cc" else "") + (if(injectorStage) "Injstage" else "") + (if(twoCycleRam) "2cr" else "") + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(relaxedPcCalculation) "Relax" else "") + (if(compressed) "Rvc" else "") + prediction.getClass.getTypeName().replace("$","")+ (if(tighlyCoupled)"Tc" else "") + (if(asyncTagMemory) "Atm" else "")) with InstructionAnticipatedPosition{ override def testParam = s"IBUS=CACHED IBUS_DATA_WIDTH=$memDataWidth" + (if(compressed) " COMPRESSED=yes" else "") + (if(tighlyCoupled)" IBUS_TC=yes" else "") override def applyOn(config: VexRiscvConfig): Unit = { val p = new IBusCachedPlugin( @@ -390,7 +391,7 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") { memDataWidth = memDataWidth, catchIllegalAccess = catchAll, catchAccessFault = catchAll, - asyncTagMemory = false, + asyncTagMemory = asyncTagMemory, twoCycleRam = twoCycleRam, twoCycleCache = twoCycleCache, twoCycleRamInnerMux = twoCycleRamInnerMux, @@ -447,12 +448,13 @@ class DBusDimension extends VexRiscvDimension("DBus") { val earlyWaysHits = r.nextBoolean() && !noWriteBack val directTlbHit = r.nextBoolean() && mmuConfig.isInstanceOf[MmuPortConfig] val dBusCmdMasterPipe, dBusCmdSlavePipe = false //As it create test bench issues + val asyncTagMemory = r.nextBoolean() do{ cacheSize = 512 << r.nextInt(5) wayCount = 1 << r.nextInt(3) }while(cacheSize/wayCount < 512 || (catchAll && cacheSize/wayCount > 4096)) - new VexRiscvPosition(s"Cached${memDataWidth}d" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(dBusCmdMasterPipe) "Cmp " else "") + (if(dBusCmdSlavePipe) "Csp " else "") + (if(dBusRspSlavePipe) "Rsp " else "") + (if(relaxedMemoryTranslationRegister) "Rmtr " else "") + (if(earlyWaysHits) "Ewh " else "") + (if(withAmo) "Amo " else "") + (if(withSmp) "Smp " else "") + (if(directTlbHit) "Dtlb " else "") + (if(twoStageMmu) "Tsmmu " else "")) { + new VexRiscvPosition(s"Cached${memDataWidth}d" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(dBusCmdMasterPipe) "Cmp " else "") + (if(dBusCmdSlavePipe) "Csp " else "") + (if(dBusRspSlavePipe) "Rsp " else "") + (if(relaxedMemoryTranslationRegister) "Rmtr " else "") + (if(earlyWaysHits) "Ewh " else "") + (if(withAmo) "Amo " else "") + (if(withSmp) "Smp " else "") + (if(directTlbHit) "Dtlb " else "") + (if(twoStageMmu) "Tsmmu " else "") + (if(asyncTagMemory) "Atm" else "")) { override def testParam = s"DBUS=CACHED DBUS_DATA_WIDTH=$memDataWidth " + (if(withLrSc) "LRSC=yes " else "") + (if(withAmo) "AMO=yes " else "") + (if(withSmp) "DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes " else "") override def applyOn(config: VexRiscvConfig): Unit = { @@ -472,7 +474,8 @@ class DBusDimension extends VexRiscvDimension("DBus") { earlyWaysHits = earlyWaysHits, withExclusive = withSmp, withInvalidate = withSmp, - directTlbHit = directTlbHit + directTlbHit = directTlbHit, + asyncTagMemory = asyncTagMemory ), dBusCmdMasterPipe = dBusCmdMasterPipe, dBusCmdSlavePipe = dBusCmdSlavePipe,