rework csr exception/interrupt handeling wip

This commit is contained in:
Dolu1990 2018-06-24 00:14:55 +02:00
parent dd47db9ad0
commit d73aa9ce00
9 changed files with 60 additions and 49 deletions

View File

@ -122,7 +122,7 @@ trait Pipeline {
} }
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){ for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){
stage.arbitration.isStuckByOthers := stage.arbitration.haltByOther || stages.takeRight(stages.length - stageIndex - 1).map(s => s.arbitration.haltItself/* && !s.arbitration.removeIt*/).foldLeft(False)(_ || _) stage.arbitration.isStuckByOthers := stage.arbitration.haltByOther || stages.takeRight(stages.length - stageIndex - 1).map(s => s.arbitration.isStuck/* && !s.arbitration.removeIt*/).foldLeft(False)(_ || _)
stage.arbitration.isStuck := stage.arbitration.haltItself || stage.arbitration.isStuckByOthers stage.arbitration.isStuck := stage.arbitration.haltItself || stage.arbitration.isStuckByOthers
stage.arbitration.isMoving := !stage.arbitration.isStuck && !stage.arbitration.removeIt stage.arbitration.isMoving := !stage.arbitration.isStuck && !stage.arbitration.removeIt
stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt

View File

@ -14,7 +14,7 @@ trait JumpService{
trait IBusFetcher{ trait IBusFetcher{
def haltIt() : Unit def haltIt() : Unit
def incoming() : Bool def incoming() : Bool
def nextPc() : (Bool, UInt) def pcValid(stage : Stage) : Bool
def getInjectionPort() : Stream[Bits] def getInjectionPort() : Stream[Bits]
} }

View File

@ -33,14 +33,14 @@ object TestsWorkspace {
plugins = List( plugins = List(
new IBusSimplePlugin( new IBusSimplePlugin(
resetVector = 0x80000000l, resetVector = 0x80000000l,
relaxedPcCalculation = true, relaxedPcCalculation = false,
relaxedBusCmdValid = false, relaxedBusCmdValid = false,
prediction = NONE, prediction = NONE,
historyRamSizeLog2 = 10, historyRamSizeLog2 = 10,
catchAccessFault = true, catchAccessFault = true,
compressedGen = false, compressedGen = false,
busLatencyMin = 3, busLatencyMin = 1,
injectorStage = false injectorStage = true
), ),
// new IBusCachedPlugin( // new IBusCachedPlugin(
// resetVector = 0x80000000l, // resetVector = 0x80000000l,

View File

@ -101,8 +101,8 @@ object VexRiscvSynthesisBench {
} }
val rtls = List(smallestNoCsr, smallest, smallAndProductive, smallAndProductiveWithICache, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full) // val rtls = List(smallestNoCsr, smallest, smallAndProductive, smallAndProductiveWithICache, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full)
// val rtls = List(noCacheNoMmuMaxPerf, fullNoMmuMaxPerf) val rtls = List(smallestNoCsr, smallest, smallAndProductive)
// val rtls = List(smallAndProductive, smallAndProductiveWithICache, fullNoMmuMaxPerf, fullNoMmu, full) // val rtls = List(smallAndProductive, smallAndProductiveWithICache, fullNoMmuMaxPerf, fullNoMmu, full)
// val rtls = List(smallAndProductive, full) // val rtls = List(smallAndProductive, full)

View File

@ -260,7 +260,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
if(ecallGen) decoderService.add(ECALL, defaultEnv ++ List(ENV_CTRL -> EnvCtrlEnum.ECALL)) if(ecallGen) decoderService.add(ECALL, defaultEnv ++ List(ENV_CTRL -> EnvCtrlEnum.ECALL))
val pcManagerService = pipeline.service(classOf[JumpService]) val pcManagerService = pipeline.service(classOf[JumpService])
jumpInterface = pcManagerService.createJumpInterface(pipeline.execute) jumpInterface = pcManagerService.createJumpInterface(pipeline.writeBack)
jumpInterface.valid := False jumpInterface.valid := False
jumpInterface.payload.assignDontCare() jumpInterface.payload.assignDontCare()
@ -372,15 +372,15 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
minstret := minstret + 1 minstret := minstret + 1
} }
val mepcCaptureStage = if(exceptionPortsInfos.nonEmpty) writeBack else decode
//Used to make the pipeline empty softly (for interrupts) //Used to make the pipeline empty softly (for interrupts)
val pipelineLiberator = new Area{ val pipelineLiberator = new Area{
val enable = False.noBackendCombMerge //Verilator Perf val enable = False.noBackendCombMerge //Verilator Perf
when(enable){ when(enable && decode.arbitration.isValid){
decode.arbitration.haltByOther := True decode.arbitration.haltByOther := True
} }
val done = ! List(execute, memory, writeBack).map(_.arbitration.isValid).orR && !fetcher.nextPc()._1 val done = !List(execute, memory, writeBack).map(_.arbitration.isValid).orR && fetcher.pcValid(mepcCaptureStage)
} }
@ -392,11 +392,6 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
val exceptionValidsRegs = Vec(stages.map(s => Reg(Bool).init(False).setPartialName(s.getName()))).allowUnsetRegToAvoidLatch val exceptionValidsRegs = Vec(stages.map(s => Reg(Bool).init(False).setPartialName(s.getName()))).allowUnsetRegToAvoidLatch
val exceptionContext = Reg(ExceptionCause()) val exceptionContext = Reg(ExceptionCause())
//Assume 2 stages before decode
when(exceptionValidsRegs.drop(1).orR) {
decode.arbitration.haltByOther := True
}
val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => { val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => {
val stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority) val stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority)
val stagePort = stagePortsInfos.length match{ val stagePort = stagePortsInfos.length match{
@ -418,14 +413,15 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
exceptionValids := exceptionValidsRegs exceptionValids := exceptionValidsRegs
for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage; stageId = indexOf(portInfo.stage)) { for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage; stageId = indexOf(portInfo.stage)) {
when(port.valid) { when(port.valid) {
if(indexOf(stage) != 0) stages(indexOf(stage) - 1).arbitration.flushAll := True // if(indexOf(stage) != 0) stages(indexOf(stage) - 1).arbitration.flushAll := True
stage.arbitration.removeIt := True stage.arbitration.removeIt := True
exceptionValids(stageId) := True exceptionValids(stageId) := True
// when(!exceptionValidsRegs.takeRight(stages.length-stageId-1).fold(False)(_ || _)) { when(!exceptionValidsRegs.takeRight(stages.length-stageId-1).fold(False)(_ || _)) {
exceptionContext := port.payload exceptionContext := port.payload
// } }
} }
} }
for(stageId <- firstStageIndexWithExceptionPort until stages.length; stage = stages(stageId) ){ for(stageId <- firstStageIndexWithExceptionPort until stages.length; stage = stages(stageId) ){
when(stage.arbitration.isFlushed){ when(stage.arbitration.isFlushed){
exceptionValids(stageId) := False exceptionValids(stageId) := False
@ -436,6 +432,12 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
}otherwise{ }otherwise{
exceptionValidsRegs(stageId) := exceptionValids(stageId) exceptionValidsRegs(stageId) := exceptionValids(stageId)
} }
if(stageId != 0){
when(exceptionValidsRegs(stageId)){
stages(stageId-1).arbitration.haltByOther := True
}
}
} }
} else null } else null
@ -489,23 +491,15 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Interrupt/Exception entry logic //Interrupt/Exception entry logic
pipelineLiberator.enable setWhen(interrupt) pipelineLiberator.enable setWhen(interrupt)
// if(exceptionPortCtrl != null) {
// when(exception) {
// exceptionPortCtrl.exceptionValidsRegs.foreach(_ := False)
// }
// }
when(exception || (interrupt && pipelineLiberator.done)){ when(exception || (interrupt && pipelineLiberator.done)){
jumpInterface.valid := True jumpInterface.valid := True
jumpInterface.payload := mtvec jumpInterface.payload := mtvec
memory.arbitration.flushAll := True //Mouai memory.arbitration.flushAll := True
if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionValidsRegs.last := False
mstatus.MIE := False mstatus.MIE := False
mstatus.MPIE := mstatus.MIE mstatus.MPIE := mstatus.MIE
mstatus.MPP := privilege mstatus.MPP := privilege
mepc := exception mux( mepc := mepcCaptureStage.input(PC)
True -> writeBack.input(PC),
False -> fetcher.nextPc()._2
)
mcause.interrupt := interrupt mcause.interrupt := interrupt
mcause.exceptionCode := ((mip.MEIP && mie.MEIE) ? U(11) | ((mip.MSIP && mie.MSIE) ? U(3) | U(7))) mcause.exceptionCode := ((mip.MEIP && mie.MEIE) ? U(11) | ((mip.MSIP && mie.MSIE) ? U(3) | U(7)))
} }
@ -517,12 +511,13 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Manage MRET instructions //Manage MRET instructions
when(memory.input(ENV_CTRL) === EnvCtrlEnum.MRET) { when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.MRET) {
memory.arbitration.haltItself := writeBack.arbitration.isValid when(memory.arbitration.isValid || writeBack.arbitration.isValid){
when(memory.arbitration.isFiring) { execute.arbitration.haltItself := True
} otherwise {
jumpInterface.valid := True jumpInterface.valid := True
jumpInterface.payload := mepc jumpInterface.payload := mepc
execute.arbitration.flushAll := True decode.arbitration.flushAll := True
mstatus.MIE := mstatus.MPIE mstatus.MIE := mstatus.MPIE
privilege := mstatus.MPP privilege := mstatus.MPP
} }

View File

@ -8,6 +8,9 @@ import StreamVexPimper._
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
//TODO val killLastStage = jump.pcLoad.valid || decode.arbitration.isRemoved
// DBUSSimple check memory halt execute optimization
abstract class IBusFetcherImpl(val catchAccessFault : Boolean, abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
val resetVector : BigInt, val resetVector : BigInt,
val keepPcPlus4 : Boolean, val keepPcPlus4 : Boolean,
@ -28,9 +31,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
assert(!(cmdToRspStageCount == 1 && !injectorStage)) assert(!(cmdToRspStageCount == 1 && !injectorStage))
assert(!(compressedGen && !decodePcGen)) assert(!(compressedGen && !decodePcGen))
var fetcherHalt : Bool = null var fetcherHalt : Bool = null
lazy val decodeNextPcValid = Bool //TODO remove me ? lazy val pcValids = Vec(Bool, 4)
lazy val decodeNextPc = UInt(32 bits) def pcValid(stage : Stage) = pcValids(pipeline.indexOf(stage))
def nextPc() = (False, decodeNextPc)
var incomingInstruction : Bool = null var incomingInstruction : Bool = null
override def incoming() = incomingInstruction override def incoming() = incomingInstruction
@ -303,16 +305,29 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
inputBeforeStage inputBeforeStage
}) })
if (decodePcGen) {
decodeNextPcValid := True
decodeNextPc := decodePc.pcReg
} else {
val lastStageStream = if (injectorStage) inputBeforeStage
else if (cmdToRspStageCount > 1) iBusRsp.inputPipeline(cmdToRspStageCount - 2)
else throw new Exception("Fetch should at least have two stages")
decodeNextPcValid := RegNext(lastStageStream.isStall) def pcUpdatedGen(input : Bool, stucks : Seq[Bool], relaxedInput : Boolean) : Seq[Bool] = {
decodeNextPc := decode.input(PC) stucks.scanLeft(input)((i, stuck) => {
val reg = RegInit(False)
if(!relaxedInput) when(flush) {
reg := False
}
when(!stuck) {
reg := i
}
if(relaxedInput || i != input) when(flush) {
reg := False
}
reg
}).tail
}
val nextPcCalc = if (decodePcGen) {
val valids = pcUpdatedGen(True, List(execute, memory, writeBack).map(_.arbitration.isStuck), true)
pcValids := Vec(valids.takeRight(4))
} else new Area{
val valids = pcUpdatedGen(True, iBusRsp.inputPipeline.map(!_.ready) ++ (if (injectorStage) List(!decodeInput.ready) else Nil) ++ List(execute, memory, writeBack).map(_.arbitration.isStuck), relaxedPcCalculation)
pcValids := Vec(valids.takeRight(4))
} }
decodeInput.ready := !decode.arbitration.isStuck decodeInput.ready := !decode.arbitration.isStuck

View File

@ -1 +1,2 @@
*.regTraceRef *.regTraceRef
/freertos.gtkw

View File

@ -1734,7 +1734,7 @@ string riscvTestDiv[] = {
}; };
string freeRtosTests[] = { string freeRtosTests[] = {
"AltBlock", "AltQTest", "AltPollQ", "blocktim", "countsem", "dead", "EventGroupsDemo", "flop", "integer", "QPeek", "AltQTest", "AltBlock", "AltPollQ", "blocktim", "countsem", "dead", "EventGroupsDemo", "flop", "integer", "QPeek",
"QueueSet", "recmutex", "semtest", "TaskNotify", "BlockQ", "crhook", "dynamic", "QueueSet", "recmutex", "semtest", "TaskNotify", "BlockQ", "crhook", "dynamic",
"GenQTest", "PollQ", "QueueOverwrite", "QueueSetPolling", "sp_flop", "test1" "GenQTest", "PollQ", "QueueOverwrite", "QueueSetPolling", "sp_flop", "test1"
//"flop", "sp_flop" // <- Simple test //"flop", "sp_flop" // <- Simple test

View File

@ -1 +1 @@
.word 0x3c12083 .word 0x34129073