ICache compressed is working

This commit is contained in:
Dolu1990 2018-04-16 10:34:18 +02:00
parent 76352b44fa
commit 4440047fb6
3 changed files with 89 additions and 60 deletions

View File

@ -17,9 +17,12 @@ case class InstructionCacheConfig( cacheSize : Int,
catchAccessFault : Boolean,
catchMemoryTranslationMiss : Boolean,
asyncTagMemory : Boolean,
twoCycleCache : Boolean = false,
twoCycleRam : Boolean = false,
preResetFlush : Boolean = false){
assert(!(twoCycleRam && !twoCycleCache))
def dataOnDecode = twoCycleRam && wayCount > 1
def burstSize = bytePerLine*8/memDataWidth
def catchSomething = catchAccessFault || catchMemoryTranslationMiss || catchIllegalAccess
@ -63,10 +66,12 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle w
val pc = UInt(p.addressWidth bits)
val data = Bits(p.cpuDataWidth bits)
val mmuBus = MemoryTranslatorBus()
val cacheMiss, error, mmuMiss, illegalAccess,isUser = ifGen(!p.twoCycleCache)(Bool)
override def asMaster(): Unit = {
out(isValid, isStuck, pc)
inWithNull(data)
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss)
outWithNull(isUser)
slaveWithNull(mmuBus)
}
}
@ -74,19 +79,15 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle w
case class InstructionCacheCpuDecode(p : InstructionCacheConfig) extends Bundle with IMasterSlave {
val isValid = Bool
val isUser = Bool
val isStuck = Bool
val pc = UInt(p.addressWidth bits)
val cacheMiss = Bool
val data = ifGen(p.dataOnDecode) (Bits(p.cpuDataWidth bits))
val error = Bool
val mmuMiss = Bool
val illegalAccess = Bool
val cacheMiss, error, mmuMiss, illegalAccess, isUser = ifGen(p.twoCycleCache)(Bool)
override def asMaster(): Unit = {
out(isValid, isUser, isStuck, pc)
in(cacheMiss)
inWithNull(error,mmuMiss,illegalAccess,data)
out(isValid, isStuck, pc)
outWithNull(isUser)
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss)
}
}
@ -94,9 +95,10 @@ case class InstructionCacheCpuBus(p : InstructionCacheConfig) extends Bundle wit
val prefetch = InstructionCacheCpuPrefetch(p)
val fetch = InstructionCacheCpuFetch(p)
val decode = InstructionCacheCpuDecode(p)
val fill = Flow(UInt(p.addressWidth bits))
override def asMaster(): Unit = {
master(prefetch, fetch, decode)
master(prefetch, fetch, decode, fill)
}
}
@ -218,6 +220,11 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val address = Reg(UInt(addressWidth bits))
val hadError = RegInit(False) clearWhen(fire)
when(io.cpu.fill.valid){
valid := True
address := io.cpu.fill.payload
}
io.cpu.prefetch.haltIt setWhen(valid)
val flushCounter = Reg(UInt(log2Up(wayLineCount) + 1 bit)) init(if(preResetFlush) wayLineCount else 0)
@ -311,10 +318,21 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
io.cpu.fetch.mmuBus.cmd.isValid := io.cpu.fetch.isValid
io.cpu.fetch.mmuBus.cmd.virtualAddress := io.cpu.fetch.pc
io.cpu.fetch.mmuBus.cmd.bypassTranslation := False
val resolution = ifGen(!twoCycleCache)( new Area{
def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck)
val mmuRsp = stage(io.cpu.fetch.mmuBus.rsp)
io.cpu.fetch.cacheMiss := !hit.valid
io.cpu.fetch.error := hit.error
io.cpu.fetch.mmuMiss := mmuRsp.miss
io.cpu.fetch.illegalAccess := !mmuRsp.allowExecute || (io.cpu.fetch.isUser && !mmuRsp.allowUser)
})
}
val decodeStage = new Area{
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)
@ -335,16 +353,16 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
}
io.cpu.decode.cacheMiss := !hit.valid
when( io.cpu.decode.isValid && io.cpu.decode.cacheMiss){
io.cpu.prefetch.haltIt := True
lineLoader.valid := True
lineLoader.address := mmuRsp.physicalAddress //Could be optimise if mmu not used
}
// when( io.cpu.decode.isValid && io.cpu.decode.cacheMiss){
// io.cpu.prefetch.haltIt := True
// lineLoader.valid := True
// lineLoader.address := mmuRsp.physicalAddress //Could be optimise if mmu not used
// }
// when(io.cpu)
io.cpu.decode.error := hit.error
io.cpu.decode.mmuMiss := mmuRsp.miss
io.cpu.decode.illegalAccess := !mmuRsp.allowExecute || (io.cpu.decode.isUser && !mmuRsp.allowUser)
}
})
}

View File

@ -44,12 +44,12 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
}
var decodeExceptionPort : Flow[ExceptionCause] = null
// var decodeExceptionPort : Flow[ExceptionCause] = null
override def setup(pipeline: VexRiscv): Unit = {
fetcherHalt = False
if(catchAccessFault || catchAddressMisaligned) {
val exceptionService = pipeline.service(classOf[ExceptionService])
decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1).setName("iBusErrorExceptionnPort")
// decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1).setName("iBusErrorExceptionnPort")
}
pipeline(RVC_GEN) = compressedGen
@ -200,8 +200,10 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
// ...
val readyForError = True
val outputBeforeStage = Stream(FetchRsp())
val output = if(rspStageGen) outputBeforeStage.m2sPipeWithFlush(flush) else outputBeforeStage
if(rspStageGen) readyForError.clearWhen(output.valid)
}
val decompressor = ifGen(decodePcGen)(new Area{
@ -209,7 +211,6 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
val output = Stream(FetchRsp())
val bufferValid = RegInit(False)
val bufferError = Reg(Bool)
val bufferData = Reg(Bits(16 bits))
val raw = Mux(
@ -219,11 +220,10 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
)
val isRvc = raw(1 downto 0) =/= 3
val decompressed = RvcDecompressor(raw(15 downto 0))
output.valid := isRvc ? (bufferValid || input.valid) | (input.valid && (bufferValid || !input.pc(1)))
output.valid := (isRvc ? (bufferValid || input.valid) | (input.valid && (bufferValid || !input.pc(1))))
output.pc := input.pc
output.isRvc := isRvc
output.rsp.inst := isRvc ? decompressed | raw
output.rsp.error := (bufferValid && bufferError) || (input.valid && input.rsp.error && (!isRvc || (isRvc && !bufferValid)))
input.ready := (bufferValid ? (!isRvc && output.ready) | (input.pc(1) || output.ready))
@ -231,19 +231,21 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
when(input.ready){
when(input.valid) {
bufferValid := !(!isRvc && !input.pc(1) && !bufferValid) && !(isRvc && input.pc(1))
bufferError := input.rsp.error
bufferData := input.rsp.inst(31 downto 16)
}
}
bufferValid.clearWhen(flush)
iBusRsp.readyForError.clearWhen(bufferValid && isRvc)
})
def condApply[T](that : T, cond : Boolean)(func : (T) => T) = if(cond)func(that) else that
val injector = new Area {
val inputBeforeHalt = condApply(if(decodePcGen) decompressor.output else iBusRsp.output, injectorReadyCutGen)(_.s2mPipe(flush))
if(injectorReadyCutGen) iBusRsp.readyForError.clearWhen(inputBeforeHalt.valid)
val decodeInput = if(injectorStage){
val decodeInput = inputBeforeHalt.m2sPipeWithFlush(killLastStage)
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), inputBeforeHalt.rsp.inst)
iBusRsp.readyForError.clearWhen(decodeInput.valid)
decodeInput
} else {
inputBeforeHalt
@ -273,11 +275,11 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
decode.insert(INSTRUCTION_READY) := True
if(compressedGen) decode.insert(IS_RVC) := decodeInput.isRvc
if(catchAccessFault){
decodeExceptionPort.valid := decode.arbitration.isValid && decodeInput.rsp.error
decodeExceptionPort.code := 1
decodeExceptionPort.badAddr := decode.input(PC)
}
// if(catchAccessFault){
// decodeExceptionPort.valid := decode.arbitration.isValid && decodeInput.rsp.error
// decodeExceptionPort.code := 1
// decodeExceptionPort.badAddr := decode.input(PC)
// }
}
prediction match {

View File

@ -50,10 +50,10 @@ class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConf
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.decode, priority = 1) //Priority 1 will win against branch predictor
if(catchSomething) {
val exceptionService = pipeline.service(classOf[ExceptionService])
decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1)
}
// if(catchSomething) {
// val exceptionService = pipeline.service(classOf[ExceptionService])
// decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1)
// }
// if(pipeline.serviceExist(classOf[MemoryTranslator]))
// ??? //TODO
@ -114,43 +114,52 @@ class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConf
cache.io.cpu.fetch.mmuBus.rsp.miss := False
}
if (dataOnDecode) {
decode.insert(INSTRUCTION) := cache.io.cpu.decode.data
} else {
iBusRsp.outputBeforeStage.arbitrationFrom(iBusRsp.inputPipeline(0))
val missHalt = cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss
iBusRsp.outputBeforeStage.arbitrationFrom(iBusRsp.inputPipeline(0).haltWhen(missHalt))
iBusRsp.outputBeforeStage.rsp.inst := cache.io.cpu.fetch.data
iBusRsp.outputBeforeStage.pc := iBusRsp.inputPipeline(0).payload
}
cache.io.cpu.decode.pc := injector.inputBeforeHalt.pc
val ownDecode = pipeline.plugins.filter(_.isInstanceOf[InstructionInjector]).foldLeft(True)(_ && !_.asInstanceOf[InstructionInjector].isInjecting(decode))
cache.io.cpu.decode.isValid := decode.arbitration.isValid && ownDecode
cache.io.cpu.decode.isStuck := !injector.inputBeforeHalt.ready
cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
// cache.io.cpu.decode.pc := decode.input(PC)
redoBranch.valid := decode.arbitration.isValid && ownDecode && cache.io.cpu.decode.cacheMiss && !cache.io.cpu.decode.mmuMiss && !cache.io.cpu.decode.illegalAccess
cache.io.cpu.fill.valid := missHalt && iBusRsp.readyForError
cache.io.cpu.fill.payload := cache.io.cpu.fetch.pc
redoBranch.valid := (RegNext(cache.io.cpu.fill.valid && !flush) init(False))
redoBranch.payload := decode.input(PC)
when(redoBranch.valid) {
decode.arbitration.redoIt := True
decode.arbitration.flushAll := True
}
// if (dataOnDecode) {
// decode.insert(INSTRUCTION) := cache.io.cpu.decode.data
// } else {
// iBusRsp.outputBeforeStage.arbitrationFrom(iBusRsp.inputPipeline(0))
// iBusRsp.outputBeforeStage.rsp.inst := cache.io.cpu.fetch.data
// iBusRsp.outputBeforeStage.pc := iBusRsp.inputPipeline(0).payload
// }
//
// cache.io.cpu.decode.pc := injector.inputBeforeHalt.pc
//
// val ownDecode = pipeline.plugins.filter(_.isInstanceOf[InstructionInjector]).foldLeft(True)(_ && !_.asInstanceOf[InstructionInjector].isInjecting(decode))
// cache.io.cpu.decode.isValid := decode.arbitration.isValid && ownDecode
// cache.io.cpu.decode.isStuck := !injector.inputBeforeHalt.ready
// cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
// // cache.io.cpu.decode.pc := decode.input(PC)
//
// redoBranch.valid := decode.arbitration.isValid && ownDecode && cache.io.cpu.decode.cacheMiss && !cache.io.cpu.decode.mmuMiss && !cache.io.cpu.decode.illegalAccess
// redoBranch.payload := decode.input(PC)
// when(redoBranch.valid) {
// decode.arbitration.redoIt := True
// decode.arbitration.flushAll := True
// }
// val redo = RegInit(False) clearWhen(decode.arbitration.isValid) setWhen(redoBranch.valid)
// when(redoBranch.valid || redo){
// service(classOf[InterruptionInhibitor]).inhibateInterrupts()
// }
if (catchSomething) {
val accessFault = if (catchAccessFault) cache.io.cpu.decode.error else False
val mmuMiss = if (catchMemoryTranslationMiss) cache.io.cpu.decode.mmuMiss else False
val illegalAccess = if (catchIllegalAccess) cache.io.cpu.decode.illegalAccess else False
// if (catchSomething) {
// val accessFault = if (catchAccessFault) cache.io.cpu.decode.error else False
// val mmuMiss = if (catchMemoryTranslationMiss) cache.io.cpu.decode.mmuMiss else False
// val illegalAccess = if (catchIllegalAccess) cache.io.cpu.decode.illegalAccess else False
decodeExceptionPort.valid := decode.arbitration.isValid && ownDecode && (accessFault || mmuMiss || illegalAccess)
decodeExceptionPort.code := mmuMiss ? U(14) | 1
decodeExceptionPort.badAddr := decode.input(PC)
}
// decodeExceptionPort.valid := decode.arbitration.isValid && ownDecode && (accessFault || mmuMiss || illegalAccess)
// decodeExceptionPort.code := mmuMiss ? U(14) | 1
// decodeExceptionPort.badAddr := decode.input(PC)
// }
memory plug new Area {