Restore two cycle instruction cache features

This commit is contained in:
Dolu1990 2018-05-15 23:03:33 +02:00
parent df3d9ccb13
commit 3b54ecf303
3 changed files with 70 additions and 54 deletions

View file

@ -31,32 +31,33 @@ object TestsWorkspace {
SpinalConfig(mergeAsyncProcess = false).generateVerilog {
val configFull = VexRiscvConfig(
plugins = List(
new IBusSimplePlugin(
resetVector = 0x80000000l,
relaxedPcCalculation = false,
prediction = NONE,
catchAccessFault = true,
catchAddressMisaligned = true,
compressedGen = true
),
// new IBusCachedPlugin(
// config = InstructionCacheConfig(
// cacheSize = 1024*16,
// bytePerLine = 32,
// wayCount = 1,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchIllegalAccess = false,
// catchAccessFault = true,
// catchMemoryTranslationMiss = false,
// asyncTagMemory = false,
// twoCycleRam = false
// )//,
//// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
//// portTlbSize = 4
//// )
// new IBusSimplePlugin(
// resetVector = 0x80000000l,
// relaxedPcCalculation = false,
// prediction = NONE,
// catchAccessFault = true,
// catchAddressMisaligned = false,
// compressedGen = true
// ),
new IBusCachedPlugin(
config = InstructionCacheConfig(
cacheSize = 1024*16,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = false,
catchAccessFault = true,
catchMemoryTranslationMiss = false,
asyncTagMemory = false,
twoCycleRam = false,
twoCycleCache = true
)//,
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4
// )
),
// new DBusSimplePlugin(
// catchAddressMisaligned = true,
// catchAccessFault = true,

View file

@ -23,7 +23,6 @@ case class InstructionCacheConfig( cacheSize : Int,
assert(!(twoCycleRam && !twoCycleCache))
def dataOnDecode = twoCycleRam && wayCount > 1
def burstSize = bytePerLine*8/memDataWidth
def catchSomething = catchAccessFault || catchMemoryTranslationMiss || catchIllegalAccess
@ -60,7 +59,15 @@ case class InstructionCacheCpuPrefetch(p : InstructionCacheConfig) extends Bundl
}
}
case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle with IMasterSlave {
trait InstructionCacheCommons{
val isValid : Bool
val isStuck : Bool
val pc : UInt
val data : Bits
val cacheMiss, error, mmuMiss, illegalAccess,isUser : Bool
}
case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle with IMasterSlave with InstructionCacheCommons {
val isValid = Bool
val isStuck = Bool
val pc = UInt(p.addressWidth bits)
@ -77,11 +84,11 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle w
}
case class InstructionCacheCpuDecode(p : InstructionCacheConfig) extends Bundle with IMasterSlave {
case class InstructionCacheCpuDecode(p : InstructionCacheConfig) extends Bundle with IMasterSlave with InstructionCacheCommons {
val isValid = Bool
val isStuck = Bool
val pc = UInt(p.addressWidth bits)
val data = ifGen(p.dataOnDecode) (Bits(p.cpuDataWidth bits))
val data = Bits(p.cpuDataWidth bits)
val cacheMiss, error, mmuMiss, illegalAccess, isUser = ifGen(p.twoCycleCache)(Bool)
override def asMaster(): Unit = {
@ -309,6 +316,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val data = read.waysValues.map(_.data).read(id)
val word = data.subdivideIn(cpuDataWidth bits).read(io.cpu.fetch.pc(memWordToCpuWordRange))
io.cpu.fetch.data := word
if(twoCycleCache){
io.cpu.decode.data := RegNextWhen(io.cpu.fetch.data,!io.cpu.decode.isStuck)
}
} else null
if(twoCycleRam && wayCount == 1){
@ -345,11 +355,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val valid = Cat(hits).orR
val id = OHToUInt(hits)
val error = tags(id).error
if(dataOnDecode) {
val data = fetchStage.read.waysValues.map(way => stage(way.data)).read(id)
val word = data.subdivideIn(cpuDataWidth bits).read(io.cpu.decode.pc(memWordToCpuWordRange))
io.cpu.decode.data := word
}
val data = fetchStage.read.waysValues.map(way => stage(way.data)).read(id)
val word = data.subdivideIn(cpuDataWidth bits).read(io.cpu.decode.pc(memWordToCpuWordRange))
io.cpu.decode.data := word
}
io.cpu.decode.cacheMiss := !hit.valid

View file

@ -13,14 +13,14 @@ class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConf
catchAccessFault = config.catchAccessFault,
resetVector = BigInt(0x80000000l),
keepPcPlus4 = false,
decodePcGen = false,
compressedGen = false,
cmdToRspStageCount = 1,
decodePcGen = true,
compressedGen = true,
cmdToRspStageCount = (if(config.twoCycleCache) 2 else 1),
injectorReadyCutGen = false,
relaxedPcCalculation = false,
prediction = NONE,
catchAddressMisaligned = false,
injectorStage = true){
injectorStage = !config.twoCycleCache){
import config._
var iBus : InstructionCacheMemBus = null
@ -103,6 +103,19 @@ class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConf
cache.io.cpu.fetch.isStuck := !iBusRsp.input.ready
cache.io.cpu.fetch.pc := iBusRsp.inputPipeline(0).payload
if(twoCycleCache){
cache.io.cpu.decode.isValid := iBusRsp.inputPipeline(1).valid
cache.io.cpu.decode.isStuck := !iBusRsp.input.ready
cache.io.cpu.decode.pc := iBusRsp.inputPipeline(1).payload
cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
if((!twoCycleRam || wayCount == 1) && !compressedGen){
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), cache.io.cpu.fetch.data)
}
}
if (mmuBus != null) {
cache.io.cpu.fetch.mmuBus <> mmuBus
} else {
@ -116,40 +129,34 @@ class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConf
}
// val missHalt = cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss
val cacheRsp = if(twoCycleCache) cache.io.cpu.decode else cache.io.cpu.fetch
val cacheRspArbitration = iBusRsp.inputPipeline(if(twoCycleCache) 1 else 0)
var issueDetected = False
val redoFetch = False //RegNext(False) init(False)
when(cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss && !issueDetected){
when(cacheRsp.isValid && cacheRsp.cacheMiss && !issueDetected){
issueDetected \= True
redoFetch := iBusRsp.readyForError
// if(decodePcGen) {
// redoFetch := !flush && iBusRsp.readyForError
// } else {
// redoFetch := !flush && iBusRsp.readyForError
// }
}
cache.io.cpu.fill.valid := redoFetch
redoBranch.valid := redoFetch
assert(decodePcGen == compressedGen)
redoBranch.payload := (if(decodePcGen) decode.input(PC) else cache.io.cpu.fetch.pc)
cache.io.cpu.fill.payload := cache.io.cpu.fetch.pc
redoBranch.payload := (if(decodePcGen) decode.input(PC) else cacheRsp.pc)
cache.io.cpu.fill.payload := cacheRsp.pc
if(catchSomething){
// val missHalt = cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss
decodeExceptionPort.valid := False
decodeExceptionPort.code := 1
decodeExceptionPort.badAddr := cache.io.cpu.fetch.pc
when(cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.error && !issueDetected){
decodeExceptionPort.badAddr := cacheRsp.pc
when(cacheRsp.isValid && cacheRsp.error && !issueDetected){
issueDetected \= True
decodeExceptionPort.valid := iBusRsp.readyForError
}
}
iBusRsp.output.arbitrationFrom(iBusRsp.inputPipeline(0).haltWhen(issueDetected))
iBusRsp.output.rsp.inst := cache.io.cpu.fetch.data
iBusRsp.output.pc := iBusRsp.inputPipeline(0).payload
iBusRsp.output.arbitrationFrom(cacheRspArbitration.haltWhen(issueDetected))
iBusRsp.output.rsp.inst := cacheRsp.data
iBusRsp.output.pc := cacheRspArbitration.payload
// if (dataOnDecode) {