mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-01-03 03:43:39 -05:00
DataCache now implement fence operations
This commit is contained in:
parent
9e1817a280
commit
6922f80a87
2 changed files with 43 additions and 2 deletions
|
@ -31,6 +31,7 @@ case class DataCacheConfig(cacheSize : Int,
|
|||
mergeExecuteMemory : Boolean = false){
|
||||
assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits)))
|
||||
assert(!(earlyDataMux && !earlyWaysHits))
|
||||
def withWriteResponse = withExclusive
|
||||
def burstSize = bytePerLine*8/memDataWidth
|
||||
val burstLength = bytePerLine/(memDataWidth/8)
|
||||
def catchSomething = catchUnaligned || catchIllegal || catchAccessError
|
||||
|
@ -95,9 +96,10 @@ case class DataCacheCpuExecute(p : DataCacheConfig) extends Bundle with IMasterS
|
|||
val address = UInt(p.addressWidth bit)
|
||||
val haltIt = Bool
|
||||
val args = DataCacheCpuExecuteArgs(p)
|
||||
val fence = Bool()
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
out(isValid, args, address)
|
||||
out(isValid, args, address, fence)
|
||||
in(haltIt)
|
||||
}
|
||||
}
|
||||
|
@ -490,6 +492,12 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
) |<< io.cpu.execute.address(1 downto 0)
|
||||
val dataColisions = collisionProcess(io.cpu.execute.address(lineRange.high downto wordRange.low), mask)
|
||||
val wayInvalidate = B(0, wayCount bits) //Used if invalidate enabled
|
||||
|
||||
if(withWriteResponse) when(io.cpu.execute.fence){
|
||||
when(pending.counter =/= 0 || io.cpu.memory.isValid || io.cpu.writeBack.isValid){
|
||||
io.cpu.execute.haltIt := True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val stageA = new Area{
|
||||
|
|
|
@ -50,6 +50,8 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
|||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||
object MEMORY_LRSC extends Stageable(Bool)
|
||||
object MEMORY_AMO extends Stageable(Bool)
|
||||
object MEMORY_FENCE extends Stageable(Bool)
|
||||
object MEMORY_FENCE_DECODED extends Stageable(Bool)
|
||||
object IS_DBUS_SHARING extends Stageable(Bool())
|
||||
object MEMORY_VIRTUAL_ADDRESS extends Stageable(UInt(32 bits))
|
||||
|
||||
|
@ -143,7 +145,13 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
|||
MEMORY_MANAGMENT -> True
|
||||
))
|
||||
|
||||
decoderService.add(FENCE, Nil)
|
||||
withWriteResponse match {
|
||||
case false => decoderService.add(FENCE, Nil)
|
||||
case true => {
|
||||
decoderService.addDefault(MEMORY_FENCE, False)
|
||||
decoderService.add(FENCE, List(MEMORY_FENCE -> True))
|
||||
}
|
||||
}
|
||||
|
||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_DATA ,memoryTranslatorPortConfig)
|
||||
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(if(pipeline.writeBack != null) pipeline.writeBack else pipeline.memory)
|
||||
|
@ -189,6 +197,30 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
|||
when(mmuBus.busy && arbitration.isValid && input(MEMORY_ENABLE)) {
|
||||
arbitration.haltItself := True
|
||||
}
|
||||
|
||||
case class FenceFlags() extends Bundle {
|
||||
val SW,SR,SO,SI,PW,PR,PO,PI = Bool()
|
||||
val FM = Bits(4 bits)
|
||||
|
||||
def SL = SR || SI
|
||||
def SS = SW || SO
|
||||
def PL = PR || PI
|
||||
def PS = PW || PO
|
||||
}
|
||||
|
||||
val fence = new Area{
|
||||
val hazard = False
|
||||
val ff = input(INSTRUCTION)(31 downto 20).as(FenceFlags())
|
||||
if(withWriteResponse){
|
||||
hazard setWhen(input(MEMORY_FENCE) && (ff.PS && ff.SL)) //Manage write to read hit ordering (ensure invalidation timings)
|
||||
// Not required as LR SC AMO naturaly enforce ordering
|
||||
// when(input(INSTRUCTION)(26 downto 25) =/= 0){
|
||||
// if(withLrSc) hazard setWhen(input(MEMORY_LRSC))
|
||||
// if(withAmo) hazard setWhen(input(MEMORY_AMO))
|
||||
// }
|
||||
}
|
||||
insert(MEMORY_FENCE_DECODED) := hazard
|
||||
}
|
||||
}
|
||||
|
||||
execute plug new Area {
|
||||
|
@ -207,6 +239,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
|||
|
||||
|
||||
cache.io.cpu.flush.valid := arbitration.isValid && input(MEMORY_MANAGMENT)
|
||||
cache.io.cpu.execute.fence := arbitration.isValid && input(MEMORY_FENCE_DECODED)
|
||||
arbitration.haltItself setWhen(cache.io.cpu.flush.isStall || cache.io.cpu.execute.haltIt)
|
||||
|
||||
if(withLrSc) {
|
||||
|
|
Loading…
Reference in a new issue