i$ now support multi cycle MMU
This commit is contained in:
parent
41ee8fd226
commit
0e76cf9ac8
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue