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 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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue