This commit is contained in:
Dolu1990 2018-04-13 12:51:27 +02:00
parent 19d5d1ecf1
commit 76352b44fa
7 changed files with 265 additions and 172 deletions

View File

@ -35,28 +35,28 @@ object TestsWorkspace {
// resetVector = 0x80000000l, // resetVector = 0x80000000l,
// relaxedPcCalculation = false // relaxedPcCalculation = false
// ), // ),
new IBusSimplePlugin( // new IBusSimplePlugin(
interfaceKeepData = false, // interfaceKeepData = false,
catchAccessFault = true // catchAccessFault = true
),
// new IBusCachedPlugin(
// config = InstructionCacheConfig(
// cacheSize = 1024*16,
// bytePerLine = 32,
// wayCount = 1,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchIllegalAccess = true,
// catchAccessFault = true,
// catchMemoryTranslationMiss = true,
// asyncTagMemory = false,
// twoCycleRam = false
// ), // ),
new IBusCachedPlugin(
config = InstructionCacheConfig(
cacheSize = 1024*16,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = false,
catchAccessFault = false,
catchMemoryTranslationMiss = false,
asyncTagMemory = false,
twoCycleRam = false
)//,
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig( // memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4 // portTlbSize = 4
// ) // )
// ), ),
// new DBusSimplePlugin( // new DBusSimplePlugin(
// catchAddressMisaligned = true, // catchAddressMisaligned = true,
// catchAccessFault = true, // catchAccessFault = true,

View File

@ -340,6 +340,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
lineLoader.valid := True lineLoader.valid := True
lineLoader.address := mmuRsp.physicalAddress //Could be optimise if mmu not used lineLoader.address := mmuRsp.physicalAddress //Could be optimise if mmu not used
} }
// when(io.cpu)
io.cpu.decode.error := hit.error io.cpu.decode.error := hit.error
io.cpu.decode.mmuMiss := mmuRsp.miss io.cpu.decode.mmuMiss := mmuRsp.miss

View File

@ -189,12 +189,12 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
val iBusRsp = new Area { val iBusRsp = new Area {
val input = Stream(UInt(32 bits)) val input = Stream(UInt(32 bits))
val pipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount) val inputPipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount)
for(i <- 0 until cmdToRspStageCount) { for(i <- 0 until cmdToRspStageCount) {
// val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush // val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush
pipeline(i) << {i match { inputPipeline(i) << {i match {
case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation) case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation)
case _ => pipeline(i-1)/*.haltWhen(fetcherHalt)*/.m2sPipeWithFlush(flush) case _ => inputPipeline(i-1)/*.haltWhen(fetcherHalt)*/.m2sPipeWithFlush(flush)
}} }}
} }
@ -255,7 +255,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
}else { }else {
val lastStageStream = if(injectorStage) inputBeforeHalt val lastStageStream = if(injectorStage) inputBeforeHalt
else if(rspStageGen) iBusRsp.outputBeforeStage else if(rspStageGen) iBusRsp.outputBeforeStage
else if(cmdToRspStageCount > 1)iBusRsp.pipeline(cmdToRspStageCount-2) else if(cmdToRspStageCount > 1)iBusRsp.inputPipeline(cmdToRspStageCount-2)
else throw new Exception("Fetch should at least have two stages") else throw new Exception("Fetch should at least have two stages")
// when(fetcherHalt){ // when(fetcherHalt){

View File

@ -5,149 +5,167 @@ import vexriscv.ip._
import spinal.core._ import spinal.core._
import spinal.lib._ import spinal.lib._
class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] {
var iBus : InstructionCacheMemBus = null
override def build(pipeline: VexRiscv): Unit = ???
}
//class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] { //class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] {
// import config._
//
// var iBus : InstructionCacheMemBus = null // var iBus : InstructionCacheMemBus = null
// var mmuBus : MemoryTranslatorBus = null // override def build(pipeline: VexRiscv): Unit = ???
// var decodeExceptionPort : Flow[ExceptionCause] = null
// var privilegeService : PrivilegeService = null
// var redoBranch : Flow[UInt] = null
//
// object FLUSH_ALL extends Stageable(Bool)
// object IBUS_ACCESS_ERROR extends Stageable(Bool)
// object IBUS_MMU_MISS extends Stageable(Bool)
// object IBUS_ILLEGAL_ACCESS extends Stageable(Bool)
// override def setup(pipeline: VexRiscv): Unit = {
// import Riscv._
// import pipeline.config._
//
// def MANAGEMENT = M"-----------------100-----0001111"
//
// val decoderService = pipeline.service(classOf[DecoderService])
// decoderService.addDefault(FLUSH_ALL, False)
// decoderService.add(MANAGEMENT, List(
// FLUSH_ALL -> True
// ))
//
//
// 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)
//} //}
// class IBusCachedPlugin(config : InstructionCacheConfig, memoryTranslatorPortConfig : Any = null) extends IBusFetcherImpl(
catchAccessFault = config.catchAccessFault,
resetVector = BigInt(0x80000000l),
keepPcPlus4 = false,
decodePcGen = true,
compressedGen = true,
cmdToRspStageCount = 1,
rspStageGen = false,
injectorReadyCutGen = false,
relaxedPcCalculation = false,
prediction = NONE,
catchAddressMisaligned = false,
injectorStage = true){
import config._
var iBus : InstructionCacheMemBus = null
var mmuBus : MemoryTranslatorBus = null
var privilegeService : PrivilegeService = null
var redoBranch : Flow[UInt] = null
object FLUSH_ALL extends Stageable(Bool)
object IBUS_ACCESS_ERROR extends Stageable(Bool)
object IBUS_MMU_MISS extends Stageable(Bool)
object IBUS_ILLEGAL_ACCESS extends Stageable(Bool)
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
super.setup(pipeline)
def MANAGEMENT = M"-----------------100-----0001111"
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(FLUSH_ALL, False)
decoderService.add(MANAGEMENT, List(
FLUSH_ALL -> True
))
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(pipeline.serviceExist(classOf[MemoryTranslator])) // if(pipeline.serviceExist(classOf[MemoryTranslator]))
// ??? //TODO
//mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.fetch, memoryTranslatorPortConfig) //mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.fetch, memoryTranslatorPortConfig)
//
// if(pipeline.serviceExist(classOf[PrivilegeService])) if(pipeline.serviceExist(classOf[PrivilegeService]))
// privilegeService = pipeline.service(classOf[PrivilegeService]) privilegeService = pipeline.service(classOf[PrivilegeService])
//
// if(pipeline.serviceExist(classOf[ReportService])){ if(pipeline.serviceExist(classOf[ReportService])){
// val report = pipeline.service(classOf[ReportService]) val report = pipeline.service(classOf[ReportService])
// report.add("iBus" -> { report.add("iBus" -> {
// val e = new BusReport() val e = new BusReport()
// val c = new CacheReport() val c = new CacheReport()
// e.kind = "cached" e.kind = "cached"
// e.flushInstructions.add(0x400F) //invalid instruction cache e.flushInstructions.add(0x400F) //invalid instruction cache
// e.flushInstructions.add(0x13) e.flushInstructions.add(0x13)
// e.flushInstructions.add(0x13) e.flushInstructions.add(0x13)
// e.flushInstructions.add(0x13) e.flushInstructions.add(0x13)
//
// e.info = c e.info = c
// c.size = cacheSize c.size = cacheSize
// c.bytePerLine = bytePerLine c.bytePerLine = bytePerLine
//
// e e
// }) })
// } }
// } }
//
// override def build(pipeline: VexRiscv): Unit = { override def build(pipeline: VexRiscv): Unit = {
// import pipeline._ import pipeline._
// import pipeline.config._ import pipeline.config._
//// val debugAddressOffset = 28
// val cache = new InstructionCache(this.config) pipeline plug new FetchArea(pipeline) {
// iBus = master(new InstructionCacheMemBus(this.config)).setName("iBus") val cache = new InstructionCache(IBusCachedPlugin.this.config)
// iBus <> cache.io.mem iBus = master(new InstructionCacheMemBus(IBusCachedPlugin.this.config)).setName("iBus")
// iBus.cmd.address.allowOverride := cache.io.mem.cmd.address // - debugAddressOffset iBus <> cache.io.mem
// iBus.cmd.address.allowOverride := cache.io.mem.cmd.address // - debugAddressOffset
// //Connect prefetch cache side
// cache.io.cpu.prefetch.isValid := prefetch.arbitration.isValid //Connect prefetch cache side
// cache.io.cpu.prefetch.pc := prefetch.output(PC)// + debugAddressOffset cache.io.cpu.prefetch.isValid := fetchPc.output.valid
// prefetch.arbitration.haltItself setWhen(cache.io.cpu.prefetch.haltIt) cache.io.cpu.prefetch.pc := fetchPc.output.payload
// iBusRsp.input << fetchPc.output.haltWhen(cache.io.cpu.prefetch.haltIt)
// //Connect fetch cache side
// cache.io.cpu.fetch.isValid := fetch.arbitration.isValid //Connect fetch cache side
// cache.io.cpu.fetch.isStuck := fetch.arbitration.isStuck cache.io.cpu.fetch.isValid := iBusRsp.inputPipeline(0).valid
// cache.io.cpu.fetch.pc := fetch.output(PC) // + debugAddressOffset cache.io.cpu.fetch.isStuck := !iBusRsp.inputPipeline(0).ready
// cache.io.cpu.fetch.pc := iBusRsp.inputPipeline(0).payload
// if (mmuBus != null) {
// cache.io.cpu.fetch.mmuBus <> mmuBus if (mmuBus != null) {
// } else { cache.io.cpu.fetch.mmuBus <> mmuBus
// cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress //- debugAddressOffset } else {
// cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress //- debugAddressOffset
// cache.io.cpu.fetch.mmuBus.rsp.allowRead := True cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
// cache.io.cpu.fetch.mmuBus.rsp.allowWrite := True cache.io.cpu.fetch.mmuBus.rsp.allowRead := True
// cache.io.cpu.fetch.mmuBus.rsp.allowUser := True cache.io.cpu.fetch.mmuBus.rsp.allowWrite := True
// cache.io.cpu.fetch.mmuBus.rsp.isIoAccess := False cache.io.cpu.fetch.mmuBus.rsp.allowUser := True
// cache.io.cpu.fetch.mmuBus.rsp.miss := False cache.io.cpu.fetch.mmuBus.rsp.isIoAccess := False
// } cache.io.cpu.fetch.mmuBus.rsp.miss := False
// }
// if(dataOnDecode){
// decode.insert(INSTRUCTION) := cache.io.cpu.decode.data if (dataOnDecode) {
// }else{ decode.insert(INSTRUCTION) := cache.io.cpu.decode.data
// fetch.insert(INSTRUCTION) := cache.io.cpu.fetch.data } else {
// decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION)) iBusRsp.outputBeforeStage.arbitrationFrom(iBusRsp.inputPipeline(0))
// } iBusRsp.outputBeforeStage.rsp.inst := cache.io.cpu.fetch.data
// decode.insert(INSTRUCTION_READY) := True iBusRsp.outputBeforeStage.pc := iBusRsp.inputPipeline(0).payload
// }
// cache.io.cpu.decode.pc := decode.output(PC)
// 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 val ownDecode = pipeline.plugins.filter(_.isInstanceOf[InstructionInjector]).foldLeft(True)(_ && !_.asInstanceOf[InstructionInjector].isInjecting(decode))
// cache.io.cpu.decode.isStuck := decode.arbitration.isStuck cache.io.cpu.decode.isValid := decode.arbitration.isValid && ownDecode
// cache.io.cpu.decode.isUser := (if(privilegeService != null) privilegeService.isUser(decode) else False) cache.io.cpu.decode.isStuck := !injector.inputBeforeHalt.ready
//// cache.io.cpu.decode.pc := decode.input(PC) 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) redoBranch.valid := decode.arbitration.isValid && ownDecode && cache.io.cpu.decode.cacheMiss && !cache.io.cpu.decode.mmuMiss && !cache.io.cpu.decode.illegalAccess
// when(redoBranch.valid){ redoBranch.payload := decode.input(PC)
// decode.arbitration.redoIt := True when(redoBranch.valid) {
// decode.arbitration.flushAll := True decode.arbitration.redoIt := True
// } decode.arbitration.flushAll := True
// }
//// val redo = RegInit(False) clearWhen(decode.arbitration.isValid) setWhen(redoBranch.valid)
//// when(redoBranch.valid || redo){ // val redo = RegInit(False) clearWhen(decode.arbitration.isValid) setWhen(redoBranch.valid)
//// service(classOf[InterruptionInhibitor]).inhibateInterrupts() // 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
//
// decodeExceptionPort.valid := decode.arbitration.isValid && ownDecode && (accessFault || mmuMiss || illegalAccess)
// decodeExceptionPort.code := mmuMiss ? U(14) | 1
// decodeExceptionPort.badAddr := decode.input(PC)
// }
//
// memory plug new Area{
// import memory._
// cache.io.flush.cmd.valid := False
// when(arbitration.isValid && input(FLUSH_ALL)){
// cache.io.flush.cmd.valid := True
// decode.arbitration.flushAll := True
//
// when(!cache.io.flush.cmd.ready){
// arbitration.haltItself := True
// }
// }
// }
// }
// } // }
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)
}
memory plug new Area {
import memory._
cache.io.flush.cmd.valid := False
when(arbitration.isValid && input(FLUSH_ALL)) {
cache.io.flush.cmd.valid := True
decode.arbitration.flushAll := True
when(!cache.io.flush.cmd.ready) {
arbitration.haltItself := True
}
}
}
}
}
}

View File

@ -163,12 +163,12 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean,
rspBuffer.io.flush := flush rspBuffer.io.flush := flush
val fetchRsp = FetchRsp() val fetchRsp = FetchRsp()
fetchRsp.pc := pipeline.last.payload fetchRsp.pc := inputPipeline.last.payload
fetchRsp.rsp := rspBuffer.io.pop.payload fetchRsp.rsp := rspBuffer.io.pop.payload
fetchRsp.rsp.error.clearWhen(!rspBuffer.io.pop.valid) //Avoid interference with instruction injection from the debug plugin fetchRsp.rsp.error.clearWhen(!rspBuffer.io.pop.valid) //Avoid interference with instruction injection from the debug plugin
val join = StreamJoin(Seq(pipeline.last, rspBuffer.io.pop), fetchRsp) val join = StreamJoin(Seq(inputPipeline.last, rspBuffer.io.pop), fetchRsp)
output << (if(rspStageGen) join.m2sPipeWithFlush(flush) else join) output << (if(rspStageGen) join.m2sPipeWithFlush(flush) else join)
} }
} }

View File

@ -0,0 +1,67 @@
[*]
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
[*] Wed Apr 11 18:53:23 2018
[*]
[dumpfile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/rv32ui-p-lui.vcd"
[dumpfile_mtime] "Wed Apr 11 18:52:18 2018"
[dumpfile_size] 325049
[savefile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/icache.gtkw"
[timestart] 1006
[size] 1784 950
[pos] -383 -155
*-5.000000 1046 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] TOP.
[treeopen] TOP.VexRiscv.
[sst_width] 370
[signals_width] 349
[sst_expanded] 1
[sst_vpaned_height] 271
@28
TOP.VexRiscv.decode_arbitration_isValid
TOP.VexRiscv.decode_arbitration_redoIt
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_haltIt
@22
TOP.VexRiscv.iBus_cmd_payload_address[31:0]
@28
TOP.VexRiscv.iBus_cmd_payload_size[2:0]
TOP.VexRiscv.iBus_cmd_ready
@29
TOP.VexRiscv.iBus_cmd_valid
@22
TOP.VexRiscv.iBus_rsp_payload_data[31:0]
@28
TOP.VexRiscv.iBus_rsp_payload_error
TOP.VexRiscv.iBus_rsp_valid
[color] 2
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_isValid
[color] 2
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_haltIt
@22
[color] 2
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_pc[31:0]
@28
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_isValid
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_isStuck
@22
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_data[31:0]
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_pc[31:0]
@28
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_isValid
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_cacheMiss
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_error
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_illegalAccess
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_isStuck
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_isUser
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_mmuMiss
@22
[color] 6
TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_pc[31:0]
[pattern_trace] 1
[pattern_trace] 0

View File

@ -387,10 +387,17 @@ public:
if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc; if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc;
#else #else
if(bootPc != -1) { if(bootPc != -1) {
#ifdef IBUS_SIMPLE
top->VexRiscv->IBusSimplePlugin_fetchPc_pcReg = bootPc; top->VexRiscv->IBusSimplePlugin_fetchPc_pcReg = bootPc;
#ifdef COMPRESSED #ifdef COMPRESSED
top->VexRiscv->IBusSimplePlugin_decodePc_pcReg = bootPc; top->VexRiscv->IBusSimplePlugin_decodePc_pcReg = bootPc;
#endif #endif
#else
top->VexRiscv->IBusCachedPlugin_fetchPc_pcReg = bootPc;
#ifdef COMPRESSED
top->VexRiscv->IBusCachedPlugin_decodePc_pcReg = bootPc;
#endif
#endif
} }
#endif #endif