Implement external LrSc

This commit is contained in:
Dolu1990 2020-04-05 11:38:57 +02:00
parent ff074459ad
commit f2ef8e95ab
2 changed files with 34 additions and 16 deletions

View File

@ -26,6 +26,7 @@ case class DataCacheConfig(cacheSize : Int,
withLrSc : Boolean = false, withLrSc : Boolean = false,
withAmo : Boolean = false, withAmo : Boolean = false,
withSmp : Boolean = false, withSmp : Boolean = false,
pendingMax : Int = 64,
mergeExecuteMemory : Boolean = false){ mergeExecuteMemory : Boolean = false){
assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits))) assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits)))
assert(!(earlyDataMux && !earlyWaysHits)) assert(!(earlyDataMux && !earlyWaysHits))
@ -91,12 +92,12 @@ object DataCacheCpuExecute{
case class DataCacheCpuExecute(p : DataCacheConfig) extends Bundle with IMasterSlave{ case class DataCacheCpuExecute(p : DataCacheConfig) extends Bundle with IMasterSlave{
val isValid = Bool val isValid = Bool
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)
override def asMaster(): Unit = { override def asMaster(): Unit = {
out(isValid, args, address) out(isValid, args, address)
// in(haltIt) in(haltIt)
} }
} }
@ -441,6 +442,22 @@ class DataCache(p : DataCacheConfig) extends Component{
ret ret
} }
io.cpu.execute.haltIt := False
val rspSync = True
val pending = withSmp generate new Area{
val counter = Reg(UInt(log2Up(pendingMax) + 1 bits)) init(0)
counter := counter + U(io.mem.cmd.fire && io.mem.cmd.last) - U(io.mem.rsp.valid)
val full = RegNext(counter.msb)
val last = counter === 1
io.cpu.execute.haltIt setWhen(full)
rspSync clearWhen(!last)
}
val stage0 = new Area{ val stage0 = new Area{
val mask = io.cpu.execute.size.mux ( val mask = io.cpu.execute.size.mux (
U(0) -> B"0001", U(0) -> B"0001",
@ -566,11 +583,14 @@ class DataCache(p : DataCacheConfig) extends Component{
io.mem.cmd.wr := request.wr io.mem.cmd.wr := request.wr
io.mem.cmd.mask := mask io.mem.cmd.mask := mask
io.mem.cmd.data := requestDataBypass io.mem.cmd.data := requestDataBypass
if(withExternalLrSc) io.mem.cmd.exclusive := request.isLrsc || request.isAmo if(withExternalLrSc) io.mem.cmd.exclusive := request.isLrsc || (if(withAmo) request.isAmo else False)
when(io.cpu.writeBack.isValid) { when(io.cpu.writeBack.isValid) {
when(mmuRsp.isIoAccess || (if(withExternalLrSc) request.isLrsc else False)) { when(mmuRsp.isIoAccess || (if(withExternalLrSc) request.isLrsc else False)) {
io.cpu.writeBack.haltIt.clearWhen(request.wr ? io.mem.cmd.ready | io.mem.rsp.valid) val waitResponse = !request.wr
if(withExternalLrSc) waitResponse setWhen(request.isLrsc)
io.cpu.writeBack.haltIt.clearWhen(waitResponse ? (io.mem.rsp.valid && rspSync) | io.mem.cmd.ready)
io.mem.cmd.valid := !memCmdSent io.mem.cmd.valid := !memCmdSent
io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto wordRange.low) @@ U(0, wordRange.low bit) io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto wordRange.low) @@ U(0, wordRange.low bit)
@ -636,6 +656,12 @@ class DataCache(p : DataCacheConfig) extends Component{
io.cpu.writeBack.data := dataMux io.cpu.writeBack.data := dataMux
if(catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0 if(catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0
} }
if(withLrSc) when(request.isLrsc && request.wr){
io.cpu.writeBack.data := B(!lrSc.reserved || !io.mem.rsp.exclusive).resized
}
if(withAmo) when(request.isAmo){
requestDataBypass := internalAmo.resultReg
}
//remove side effects on exceptions //remove side effects on exceptions
when(mmuRsp.refilling || io.cpu.writeBack.accessError || io.cpu.writeBack.mmuException || io.cpu.writeBack.unalignedAccess){ when(mmuRsp.refilling || io.cpu.writeBack.accessError || io.cpu.writeBack.mmuException || io.cpu.writeBack.unalignedAccess){
@ -649,16 +675,8 @@ class DataCache(p : DataCacheConfig) extends Component{
assert(!(io.cpu.writeBack.isValid && !io.cpu.writeBack.haltIt && io.cpu.writeBack.isStuck), "writeBack stuck by another plugin is not allowed") assert(!(io.cpu.writeBack.isValid && !io.cpu.writeBack.haltIt && io.cpu.writeBack.isStuck), "writeBack stuck by another plugin is not allowed")
if(withLrSc){
when(request.isLrsc && request.wr){
io.cpu.writeBack.data := (!lrSc.reserved).asBits.resized
}
}
if(withAmo){
when(request.isAmo){
requestDataBypass := internalAmo.resultReg
}
}
} }
val loader = new Area{ val loader = new Area{
@ -669,7 +687,7 @@ class DataCache(p : DataCacheConfig) extends Component{
val waysAllocator = Reg(Bits(wayCount bits)) init(1) val waysAllocator = Reg(Bits(wayCount bits)) init(1)
val error = RegInit(False) val error = RegInit(False)
when(valid && io.mem.rsp.valid){ when(valid && io.mem.rsp.valid && rspSync){
dataWriteCmd.valid := True dataWriteCmd.valid := True
dataWriteCmd.address := baseAddress(lineRange) @@ counter dataWriteCmd.address := baseAddress(lineRange) @@ counter
dataWriteCmd.data := io.mem.rsp.data dataWriteCmd.data := io.mem.rsp.data

View File

@ -204,7 +204,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)
arbitration.haltItself setWhen(cache.io.cpu.flush.isStall) arbitration.haltItself setWhen(cache.io.cpu.flush.isStall || cache.io.cpu.execute.haltIt)
if(withLrSc) { if(withLrSc) {
cache.io.cpu.execute.args.isLrsc := False cache.io.cpu.execute.args.isLrsc := False