ICache compressed is working
This commit is contained in:
parent
76352b44fa
commit
4440047fb6
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
iBusRsp.outputBeforeStage.rsp.inst := cache.io.cpu.fetch.data
|
||||
iBusRsp.outputBeforeStage.pc := iBusRsp.inputPipeline(0).payload
|
||||
}
|
||||
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 {
|
||||
|
||||
|
|
Loading…
Reference in New Issue