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 dataBypassValid = p.bypassGen generate Bool()
val dataBypass = p.bypassGen generate Bits(p.cpuDataWidth bits)
val mmuBus = MemoryTranslatorBus(mmuParameter)
val mmuRsp = MemoryTranslatorRsp(mmuParameter)
val physicalAddress = UInt(p.addressWidth bits)
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 = {
out(isValid, isStuck, isRemoved, pc)
inWithNull(error,mmuRefilling,mmuException,data, cacheMiss,physicalAddress, haltIt)
inWithNull(error,mmuRefilling,mmuException,data, cacheMiss,physicalAddress)
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 fire = False
@ -412,7 +410,7 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
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 id = OHToUInt(hits)
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.mmuBus.cmd.last.isValid := io.cpu.fetch.isValid
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
io.cpu.fetch.physicalAddress := io.cpu.fetch.mmuRsp.physicalAddress
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.error := hit.error
@ -449,7 +443,7 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
val decodeStage = ifGen(twoCycleCache) (new Area{
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 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
stages(0).halt setWhen (cache.io.cpu.prefetch.haltIt)
cache.io.cpu.fetch.isRemoved := externalFlush
if(mmuBus != null && mmuBus.p.latency == 1) {
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.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) {
cache.io.cpu.fetch.isUser := privilegeService.isUser()
@ -249,16 +261,15 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
}
if (mmuBus != null) {
cache.io.cpu.fetch.mmuBus <> mmuBus
cache.io.cpu.fetch.mmuRsp <> mmuBus.rsp
} else {
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.last.virtualAddress
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
cache.io.cpu.fetch.mmuBus.rsp.allowRead := True
cache.io.cpu.fetch.mmuBus.rsp.allowWrite := True
cache.io.cpu.fetch.mmuBus.rsp.isIoAccess := False
cache.io.cpu.fetch.mmuBus.rsp.exception := False
cache.io.cpu.fetch.mmuBus.rsp.refilling := False
cache.io.cpu.fetch.mmuBus.busy := False
cache.io.cpu.fetch.mmuRsp.physicalAddress := cache.io.cpu.fetch.pc
cache.io.cpu.fetch.mmuRsp.allowExecute := True
cache.io.cpu.fetch.mmuRsp.allowRead := True
cache.io.cpu.fetch.mmuRsp.allowWrite := True
cache.io.cpu.fetch.mmuRsp.isIoAccess := False
cache.io.cpu.fetch.mmuRsp.exception := False
cache.io.cpu.fetch.mmuRsp.refilling := False
}
val flushStage = decode

View File

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