diff --git a/README.md b/README.md index 1a8864b..a02c52b 100644 --- a/README.md +++ b/README.md @@ -1038,6 +1038,8 @@ There is at least one cycle latency between a cmd and the corresponding rsp. The Multi way cache implementation with writh-through and allocate on read strategy. (Documentation is WIP) +You can invalidate the whole cache via the 0x500F instruction, and you can invalidate a address range of one line via the instruction 0x500F | RS1 << 15 where RS1 should not be X0. + #### MulPlugin Implements the multiplication instruction from the RISC-V M extension. Its implementation was done in a FPGA friendly way by using 4 17*17 bit multiplications. diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index b3cf4dc..2b70400 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -40,6 +40,7 @@ case class DataCacheConfig(cacheSize : Int, assert(isPow2(pendingMax)) assert(rfDataWidth <= memDataWidth) + def lineCount = cacheSize/bytePerLine/wayCount def sizeMax = log2Up(bytePerLine) def sizeWidth = log2Up(sizeMax + 1) val aggregationWidth = if(withWriteAggregation) log2Up(memDataBytes+1) else 0 @@ -193,13 +194,18 @@ case class DataCacheCpuWriteBack(p : DataCacheConfig) extends Bundle with IMaste } } +case class DataCacheFlush(lineCount : Int) extends Bundle{ + val singleLine = Bool() + val lineId = UInt(log2Up(lineCount) bits) +} + case class DataCacheCpuBus(p : DataCacheConfig, mmu : MemoryTranslatorBusParameter) extends Bundle with IMasterSlave{ val execute = DataCacheCpuExecute(p) val memory = DataCacheCpuMemory(p, mmu) val writeBack = DataCacheCpuWriteBack(p) val redo = Bool() - val flush = Event + val flush = Stream(DataCacheFlush(p.lineCount)) override def asMaster(): Unit = { master(execute) @@ -849,6 +855,9 @@ class DataCache(val p : DataCacheConfig, mmuParameter : MemoryTranslatorBusParam io.cpu.execute.haltIt := True when(!hold) { counter := counter + 1 + when(io.cpu.flush.singleLine){ + counter.msb := True + } } } @@ -860,6 +869,9 @@ class DataCache(val p : DataCacheConfig, mmuParameter : MemoryTranslatorBusParam when(start){ waitDone := True counter := 0 + when(io.cpu.flush.singleLine){ + counter := U"0" @@ io.cpu.flush.lineId + } } } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 381f2e0..80d4409 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -228,7 +228,8 @@ class DBusCachedPlugin(val config : DataCacheConfig, decoderService.addDefault(MEMORY_MANAGMENT, False) decoderService.add(MANAGEMENT, List( - MEMORY_MANAGMENT -> True + MEMORY_MANAGMENT -> True, + RS1_USE -> True )) withWriteResponse match { @@ -343,6 +344,8 @@ class DBusCachedPlugin(val config : DataCacheConfig, } cache.io.cpu.flush.valid := arbitration.isValid && input(MEMORY_MANAGMENT) + cache.io.cpu.flush.singleLine := input(INSTRUCTION)(Riscv.rs1Range) =/= 0 + cache.io.cpu.flush.lineId := U(input(RS1) >> log2Up(bytePerLine)).resized cache.io.cpu.execute.args.totalyConsistent := input(MEMORY_FORCE_CONSTISTENCY) arbitration.haltItself setWhen(cache.io.cpu.flush.isStall || cache.io.cpu.execute.haltIt)