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){
|
mergeExecuteMemory : Boolean = false){
|
||||||
assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits)))
|
assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits)))
|
||||||
assert(!(earlyDataMux && !earlyWaysHits))
|
assert(!(earlyDataMux && !earlyWaysHits))
|
||||||
|
def withWriteResponse = withExclusive
|
||||||
def burstSize = bytePerLine*8/memDataWidth
|
def burstSize = bytePerLine*8/memDataWidth
|
||||||
val burstLength = bytePerLine/(memDataWidth/8)
|
val burstLength = bytePerLine/(memDataWidth/8)
|
||||||
def catchSomething = catchUnaligned || catchIllegal || catchAccessError
|
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 address = UInt(p.addressWidth bit)
|
||||||
val haltIt = Bool
|
val haltIt = Bool
|
||||||
val args = DataCacheCpuExecuteArgs(p)
|
val args = DataCacheCpuExecuteArgs(p)
|
||||||
|
val fence = Bool()
|
||||||
|
|
||||||
override def asMaster(): Unit = {
|
override def asMaster(): Unit = {
|
||||||
out(isValid, args, address)
|
out(isValid, args, address, fence)
|
||||||
in(haltIt)
|
in(haltIt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,6 +492,12 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
) |<< io.cpu.execute.address(1 downto 0)
|
) |<< io.cpu.execute.address(1 downto 0)
|
||||||
val dataColisions = collisionProcess(io.cpu.execute.address(lineRange.high downto wordRange.low), mask)
|
val dataColisions = collisionProcess(io.cpu.execute.address(lineRange.high downto wordRange.low), mask)
|
||||||
val wayInvalidate = B(0, wayCount bits) //Used if invalidate enabled
|
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{
|
val stageA = new Area{
|
||||||
|
|
|
@ -50,6 +50,8 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
||||||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||||
object MEMORY_LRSC extends Stageable(Bool)
|
object MEMORY_LRSC extends Stageable(Bool)
|
||||||
object MEMORY_AMO 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 IS_DBUS_SHARING extends Stageable(Bool())
|
||||||
object MEMORY_VIRTUAL_ADDRESS extends Stageable(UInt(32 bits))
|
object MEMORY_VIRTUAL_ADDRESS extends Stageable(UInt(32 bits))
|
||||||
|
|
||||||
|
@ -143,7 +145,13 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
||||||
MEMORY_MANAGMENT -> True
|
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)
|
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)
|
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)) {
|
when(mmuBus.busy && arbitration.isValid && input(MEMORY_ENABLE)) {
|
||||||
arbitration.haltItself := True
|
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 {
|
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.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)
|
arbitration.haltItself setWhen(cache.io.cpu.flush.isStall || cache.io.cpu.execute.haltIt)
|
||||||
|
|
||||||
if(withLrSc) {
|
if(withLrSc) {
|
||||||
|
|
Loading…
Reference in a new issue