dataCache now implement invalidation sync
This commit is contained in:
parent
467a2bc488
commit
46207abbc4
|
@ -80,11 +80,16 @@ case class DataCacheConfig(cacheSize : Int,
|
|||
dataWidth = 32,
|
||||
lengthWidth = log2Up(this.bytePerLine),
|
||||
sourceWidth = 0,
|
||||
contextWidth = 1,
|
||||
contextWidth = if(!withWriteResponse) 1 else 0,
|
||||
canRead = true,
|
||||
canWrite = true,
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
maximumPendingTransactionPerId = Int.MaxValue
|
||||
maximumPendingTransactionPerId = Int.MaxValue,
|
||||
canInvalidate = withInvalidate,
|
||||
canSync = withInvalidate,
|
||||
canExclusive = withExclusive,
|
||||
invalidateLength = log2Up(this.bytePerLine),
|
||||
invalidateAlignment = BmbParameter.BurstAlignement.LENGTH
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -193,12 +198,17 @@ case class DataCacheAck(p : DataCacheConfig) extends Bundle{
|
|||
val hit = Bool()
|
||||
}
|
||||
|
||||
case class DataCacheSync(p : DataCacheConfig) extends Bundle{
|
||||
|
||||
}
|
||||
|
||||
case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave{
|
||||
val cmd = Stream (DataCacheMemCmd(p))
|
||||
val rsp = Flow (DataCacheMemRsp(p))
|
||||
|
||||
val inv = p.withInvalidate generate Stream(DataCacheInv(p))
|
||||
val ack = p.withInvalidate generate Stream(DataCacheAck(p))
|
||||
val sync = p.withInvalidate generate Stream(DataCacheSync(p))
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
master(cmd)
|
||||
|
@ -207,6 +217,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
if(p.withInvalidate) {
|
||||
slave(inv)
|
||||
master(ack)
|
||||
slave(sync)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,11 +353,11 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
|
||||
def toBmb() : Bmb = {
|
||||
val pipelinedMemoryBusConfig = p.getBmbParameter()
|
||||
val bus = Bmb(pipelinedMemoryBusConfig)
|
||||
val bus = Bmb(pipelinedMemoryBusConfig).setCompositeName(this,"toBmb", true)
|
||||
|
||||
bus.cmd.valid := cmd.valid
|
||||
bus.cmd.last := cmd.last
|
||||
bus.cmd.context(0) := cmd.wr
|
||||
if(!p.withWriteResponse) bus.cmd.context(0) := cmd.wr
|
||||
bus.cmd.opcode := (cmd.wr ? B(Bmb.Cmd.Opcode.WRITE) | B(Bmb.Cmd.Opcode.READ))
|
||||
bus.cmd.address := cmd.address.resized
|
||||
bus.cmd.data := cmd.data
|
||||
|
@ -356,22 +367,33 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
|
||||
cmd.ready := bus.cmd.ready
|
||||
|
||||
rsp.valid := bus.rsp.valid && !bus.rsp.context(0)
|
||||
rsp.valid := bus.rsp.valid
|
||||
if(!p.withWriteResponse) rsp.valid clearWhen(bus.rsp.context(0))
|
||||
rsp.data := bus.rsp.data
|
||||
rsp.error := bus.rsp.isError
|
||||
rsp.last := bus.rsp.last
|
||||
if(p.withExclusive) rsp.exclusive := bus.rsp.exclusive
|
||||
bus.rsp.ready := True
|
||||
|
||||
if(p.withInvalidate){
|
||||
bus.ack.arbitrationFrom(ack)
|
||||
//TODO manage lenght ?
|
||||
inv.arbitrationFrom(bus.inv)
|
||||
inv.address := bus.inv.address
|
||||
// inv.opcode := bus.inv.opcode
|
||||
???
|
||||
inv.enable := bus.inv.all
|
||||
|
||||
bus.ack.arbitrationFrom(ack)
|
||||
|
||||
sync.arbitrationFrom(bus.sync)
|
||||
|
||||
// bus.ack.arbitrationFrom(ack)
|
||||
// //TODO manage lenght ?
|
||||
// inv.address := bus.inv.address
|
||||
//// inv.opcode := bus.inv.opcode
|
||||
// ???
|
||||
//
|
||||
// bus.ack.arbitrationFrom(ack)
|
||||
}
|
||||
|
||||
|
||||
bus
|
||||
}
|
||||
|
||||
|
@ -440,9 +462,10 @@ class DataCache(val p : DataCacheConfig) extends Component{
|
|||
|
||||
//Reads
|
||||
val tagsReadRsp = tags.readSync(tagsReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck)
|
||||
val tagsInvReadRsp = withInvalidate generate tags.readSync(tagsInvReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck)
|
||||
val dataReadRsp = data.readSync(dataReadCmd.payload, dataReadCmd.valid && !io.cpu.memory.isStuck)
|
||||
|
||||
val tagsInvReadRsp = withInvalidate generate tags.readSync(tagsInvReadCmd.payload, tagsInvReadCmd.valid)
|
||||
|
||||
//Writes
|
||||
when(tagsWriteCmd.valid && tagsWriteCmd.way(i)){
|
||||
tags.write(tagsWriteCmd.address, tagsWriteCmd.data)
|
||||
|
@ -494,11 +517,24 @@ class DataCache(val p : DataCacheConfig) extends Component{
|
|||
val full = RegNext(counter.msb)
|
||||
val last = counter === 1
|
||||
|
||||
if(!withInvalidate) {
|
||||
io.cpu.execute.haltIt setWhen(full)
|
||||
}
|
||||
|
||||
rspSync clearWhen (!last || !memCmdSent)
|
||||
rspLast clearWhen (!last)
|
||||
}
|
||||
|
||||
val sync = withInvalidate generate new Area{
|
||||
io.mem.sync.ready := True
|
||||
|
||||
val counter = Reg(UInt(log2Up(pendingMax) + 1 bits)) init(0)
|
||||
counter := counter + U(io.mem.cmd.fire && io.mem.cmd.wr) - U(io.mem.sync.fire)
|
||||
|
||||
val full = RegNext(counter.msb)
|
||||
io.cpu.execute.haltIt setWhen(full)
|
||||
}
|
||||
|
||||
|
||||
val stage0 = new Area{
|
||||
val mask = io.cpu.execute.size.mux (
|
||||
|
@ -509,12 +545,15 @@ class DataCache(val p : DataCacheConfig) extends Component{
|
|||
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){
|
||||
when(io.cpu.execute.fence){
|
||||
val counter = if(withInvalidate) sync.counter else if(withWriteResponse) pending.counter else null
|
||||
if(counter != null){
|
||||
when(counter =/= 0 || io.cpu.memory.isValid || io.cpu.writeBack.isValid){
|
||||
io.cpu.execute.haltIt := True
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val stageA = new Area{
|
||||
def stagePipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.memory.isStuck)
|
||||
|
@ -563,18 +602,21 @@ class DataCache(val p : DataCacheConfig) extends Component{
|
|||
//Evict the cache after reset logics
|
||||
val flusher = new Area {
|
||||
val valid = RegInit(False)
|
||||
val hold = False
|
||||
when(valid) {
|
||||
tagsWriteCmd.valid := valid
|
||||
tagsWriteCmd.address := mmuRsp.physicalAddress(lineRange)
|
||||
tagsWriteCmd.way.setAll()
|
||||
tagsWriteCmd.data.valid := False
|
||||
io.cpu.writeBack.haltIt := True
|
||||
when(!hold) {
|
||||
when(mmuRsp.physicalAddress(lineRange) =/= wayLineCount - 1) {
|
||||
mmuRsp.physicalAddress.getDrivingReg(lineRange) := mmuRsp.physicalAddress(lineRange) + 1
|
||||
} otherwise {
|
||||
valid := False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
io.cpu.flush.ready := False
|
||||
val start = RegInit(True) //Used to relax timings
|
||||
|
@ -867,6 +909,7 @@ class DataCache(val p : DataCacheConfig) extends Component{
|
|||
//Invalidate cache tag
|
||||
when(wayHit) {
|
||||
tagsWriteCmd.valid := True
|
||||
stageB.flusher.hold := True
|
||||
tagsWriteCmd.address := input.address(lineRange)
|
||||
tagsWriteCmd.data.valid := False
|
||||
tagsWriteCmd.way := wayHits
|
||||
|
|
|
@ -184,7 +184,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
|||
case true if !withExternalAmo => dBus.rsp.m2sPipe()
|
||||
case true if withExternalAmo => {
|
||||
val rsp = Flow (DataCacheMemRsp(cache.p))
|
||||
rsp.valid := RegNext(dBus.rsp.valid)
|
||||
rsp.valid := RegNext(dBus.rsp.valid) init(False)
|
||||
rsp.exclusive := RegNext(dBus.rsp.exclusive)
|
||||
rsp.error := RegNext(dBus.rsp.error)
|
||||
rsp.last := RegNext(dBus.rsp.last)
|
||||
|
@ -196,6 +196,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
|||
if(withInvalidate) {
|
||||
cache.io.mem.inv << dBus.inv
|
||||
cache.io.mem.ack >> dBus.ack
|
||||
cache.io.mem.sync << dBus.sync
|
||||
}
|
||||
|
||||
pipeline plug new Area{
|
||||
|
|
Loading…
Reference in New Issue