i$ now support multi cycle MMU

This commit is contained in:
Dolu1990 2020-05-07 22:50:25 +02:00
parent 41ee8fd226
commit 0e76cf9ac8
3 changed files with 37 additions and 26 deletions

View File

@ -112,16 +112,15 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig, mmuParameter : M
val data = Bits(p.cpuDataWidth bits) val data = Bits(p.cpuDataWidth bits)
val dataBypassValid = p.bypassGen generate Bool() val dataBypassValid = p.bypassGen generate Bool()
val dataBypass = p.bypassGen generate Bits(p.cpuDataWidth bits) val dataBypass = p.bypassGen generate Bits(p.cpuDataWidth bits)
val mmuBus = MemoryTranslatorBus(mmuParameter) val mmuRsp = MemoryTranslatorRsp(mmuParameter)
val physicalAddress = UInt(p.addressWidth bits) val physicalAddress = UInt(p.addressWidth bits)
val cacheMiss, error, mmuRefilling, mmuException, isUser = ifGen(!p.twoCycleCache)(Bool) val cacheMiss, error, mmuRefilling, mmuException, isUser = ifGen(!p.twoCycleCache)(Bool)
val haltIt = Bool() //Used to wait on the MMU rsp busy
override def asMaster(): Unit = { override def asMaster(): Unit = {
out(isValid, isStuck, isRemoved, pc) out(isValid, isStuck, isRemoved, pc)
inWithNull(error,mmuRefilling,mmuException,data, cacheMiss,physicalAddress, haltIt) inWithNull(error,mmuRefilling,mmuException,data, cacheMiss,physicalAddress)
outWithNull(isUser, dataBypass, dataBypassValid) outWithNull(isUser, dataBypass, dataBypassValid)
slaveWithNull(mmuBus) out(mmuRsp)
} }
} }
@ -321,7 +320,6 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
} }
}) })
io.cpu.fetch.haltIt := io.cpu.fetch.mmuBus.busy
val lineLoader = new Area{ val lineLoader = new Area{
val fire = False val fire = False
@ -412,7 +410,7 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
val hit = (!twoCycleRam) generate new Area{ val hit = (!twoCycleRam) generate new Area{
val hits = read.waysValues.map(way => way.tag.valid && way.tag.address === io.cpu.fetch.mmuBus.rsp.physicalAddress(tagRange)) val hits = read.waysValues.map(way => way.tag.valid && way.tag.address === io.cpu.fetch.mmuRsp.physicalAddress(tagRange))
val valid = Cat(hits).orR val valid = Cat(hits).orR
val id = OHToUInt(hits) val id = OHToUInt(hits)
val error = read.waysValues.map(_.tag.error).read(id) val error = read.waysValues.map(_.tag.error).read(id)
@ -429,14 +427,10 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
io.cpu.fetch.data := (if(p.bypassGen) (io.cpu.fetch.dataBypassValid ? io.cpu.fetch.dataBypass | cacheData) else cacheData) io.cpu.fetch.data := (if(p.bypassGen) (io.cpu.fetch.dataBypassValid ? io.cpu.fetch.dataBypass | cacheData) else cacheData)
} }
io.cpu.fetch.mmuBus.cmd.last.isValid := io.cpu.fetch.isValid io.cpu.fetch.physicalAddress := io.cpu.fetch.mmuRsp.physicalAddress
io.cpu.fetch.mmuBus.cmd.last.virtualAddress := io.cpu.fetch.pc
io.cpu.fetch.mmuBus.cmd.last.bypassTranslation := False
io.cpu.fetch.mmuBus.end := !io.cpu.fetch.isStuck || io.cpu.fetch.isRemoved
io.cpu.fetch.physicalAddress := io.cpu.fetch.mmuBus.rsp.physicalAddress
val resolution = ifGen(!twoCycleCache)( new Area{ val resolution = ifGen(!twoCycleCache)( new Area{
val mmuRsp = io.cpu.fetch.mmuBus.rsp val mmuRsp = io.cpu.fetch.mmuRsp
io.cpu.fetch.cacheMiss := !hit.valid io.cpu.fetch.cacheMiss := !hit.valid
io.cpu.fetch.error := hit.error io.cpu.fetch.error := hit.error
@ -449,7 +443,7 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
val decodeStage = ifGen(twoCycleCache) (new Area{ val decodeStage = ifGen(twoCycleCache) (new Area{
def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck) def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck)
val mmuRsp = stage(io.cpu.fetch.mmuBus.rsp) val mmuRsp = stage(io.cpu.fetch.mmuRsp)
val hit = if(!twoCycleRam) new Area{ val hit = if(!twoCycleRam) new Area{
val valid = stage(fetchStage.hit.valid) val valid = stage(fetchStage.hit.valid)

View File

@ -155,8 +155,13 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
cache.io.cpu.prefetch.pc := stages(0).input.payload cache.io.cpu.prefetch.pc := stages(0).input.payload
stages(0).halt setWhen (cache.io.cpu.prefetch.haltIt) stages(0).halt setWhen (cache.io.cpu.prefetch.haltIt)
if(mmuBus != null && mmuBus.p.latency == 1) {
cache.io.cpu.fetch.isRemoved := externalFlush stages(0).halt setWhen(mmuBus.busy)
mmuBus.cmd(0).isValid := cache.io.cpu.prefetch.isValid
mmuBus.cmd(0).isStuck := !stages(0).input.ready
mmuBus.cmd(0).virtualAddress := cache.io.cpu.prefetch.pc
mmuBus.cmd(0).bypassTranslation := False
}
} }
@ -172,8 +177,15 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
cache.io.cpu.fetch.isStuck := !stages(1).input.ready cache.io.cpu.fetch.isStuck := !stages(1).input.ready
cache.io.cpu.fetch.pc := stages(1).input.payload cache.io.cpu.fetch.pc := stages(1).input.payload
if(mmuBus != null) {
mmuBus.cmd.last.isValid := cache.io.cpu.fetch.isValid
mmuBus.cmd.last.isStuck := !stages(1).input.ready
mmuBus.cmd.last.virtualAddress := cache.io.cpu.fetch.pc
mmuBus.cmd.last.bypassTranslation := False
mmuBus.end := stages(1).input.ready || externalFlush
if (mmuBus.p.latency == 0) stages(1).halt setWhen (mmuBus.busy)
}
stages(1).halt setWhen(cache.io.cpu.fetch.haltIt)
if (!twoCycleCache) { if (!twoCycleCache) {
cache.io.cpu.fetch.isUser := privilegeService.isUser() cache.io.cpu.fetch.isUser := privilegeService.isUser()
@ -249,16 +261,15 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
} }
if (mmuBus != null) { if (mmuBus != null) {
cache.io.cpu.fetch.mmuBus <> mmuBus cache.io.cpu.fetch.mmuRsp <> mmuBus.rsp
} else { } else {
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.last.virtualAddress cache.io.cpu.fetch.mmuRsp.physicalAddress := cache.io.cpu.fetch.pc
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True cache.io.cpu.fetch.mmuRsp.allowExecute := True
cache.io.cpu.fetch.mmuBus.rsp.allowRead := True cache.io.cpu.fetch.mmuRsp.allowRead := True
cache.io.cpu.fetch.mmuBus.rsp.allowWrite := True cache.io.cpu.fetch.mmuRsp.allowWrite := True
cache.io.cpu.fetch.mmuBus.rsp.isIoAccess := False cache.io.cpu.fetch.mmuRsp.isIoAccess := False
cache.io.cpu.fetch.mmuBus.rsp.exception := False cache.io.cpu.fetch.mmuRsp.exception := False
cache.io.cpu.fetch.mmuBus.rsp.refilling := False cache.io.cpu.fetch.mmuRsp.refilling := False
cache.io.cpu.fetch.mmuBus.busy := False
} }
val flushStage = decode val flushStage = decode

View File

@ -321,9 +321,12 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY)
val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
if(r.nextDouble() < 0.5){ if(r.nextDouble() < 0.5){
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null
val latency = r.nextInt(5) + 1 val latency = r.nextInt(5) + 1
val compressed = r.nextDouble() < rvcRate val compressed = r.nextDouble() < rvcRate
val injectorStage = r.nextBoolean() || latency == 1 val injectorStage = r.nextBoolean() || latency == 1
@ -347,6 +350,9 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") {
override def instructionAnticipatedOk() = injectorStage override def instructionAnticipatedOk() = injectorStage
} }
} else { } else {
val twoStageMmu = r.nextBoolean()
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig(portTlbSize = 4, latency = if(twoStageMmu) 1 else 0, earlyRequireMmuLockup = Random.nextBoolean() && twoStageMmu, earlyCacheHits = Random.nextBoolean() && twoStageMmu) else null
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
val compressed = r.nextDouble() < rvcRate val compressed = r.nextDouble() < rvcRate
val tighlyCoupled = r.nextBoolean() && !catchAll val tighlyCoupled = r.nextBoolean() && !catchAll