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)){
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.isMoving := !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{
def haltIt() : Unit
def incoming() : Bool
def nextPc() : (Bool, UInt)
def pcValid(stage : Stage) : Bool
def getInjectionPort() : Stream[Bits]
}

View File

@ -33,14 +33,14 @@ object TestsWorkspace {
plugins = List(
new IBusSimplePlugin(
resetVector = 0x80000000l,
relaxedPcCalculation = true,
relaxedPcCalculation = false,
relaxedBusCmdValid = false,
prediction = NONE,
historyRamSizeLog2 = 10,
catchAccessFault = true,
compressedGen = false,
busLatencyMin = 3,
injectorStage = false
busLatencyMin = 1,
injectorStage = true
),
// new IBusCachedPlugin(
// 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(noCacheNoMmuMaxPerf, fullNoMmuMaxPerf)
// val rtls = List(smallestNoCsr, smallest, smallAndProductive, smallAndProductiveWithICache, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full)
val rtls = List(smallestNoCsr, smallest, smallAndProductive)
// val rtls = List(smallAndProductive, smallAndProductiveWithICache, fullNoMmuMaxPerf, fullNoMmu, 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))
val pcManagerService = pipeline.service(classOf[JumpService])
jumpInterface = pcManagerService.createJumpInterface(pipeline.execute)
jumpInterface = pcManagerService.createJumpInterface(pipeline.writeBack)
jumpInterface.valid := False
jumpInterface.payload.assignDontCare()
@ -372,15 +372,15 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
minstret := minstret + 1
}
val mepcCaptureStage = if(exceptionPortsInfos.nonEmpty) writeBack else decode
//Used to make the pipeline empty softly (for interrupts)
val pipelineLiberator = new Area{
val enable = False.noBackendCombMerge //Verilator Perf
when(enable){
when(enable && decode.arbitration.isValid){
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 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 stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority)
val stagePort = stagePortsInfos.length match{
@ -418,14 +413,15 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
exceptionValids := exceptionValidsRegs
for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage; stageId = indexOf(portInfo.stage)) {
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
exceptionValids(stageId) := True
// when(!exceptionValidsRegs.takeRight(stages.length-stageId-1).fold(False)(_ || _)) {
when(!exceptionValidsRegs.takeRight(stages.length-stageId-1).fold(False)(_ || _)) {
exceptionContext := port.payload
// }
}
}
}
for(stageId <- firstStageIndexWithExceptionPort until stages.length; stage = stages(stageId) ){
when(stage.arbitration.isFlushed){
exceptionValids(stageId) := False
@ -436,6 +432,12 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
}otherwise{
exceptionValidsRegs(stageId) := exceptionValids(stageId)
}
if(stageId != 0){
when(exceptionValidsRegs(stageId)){
stages(stageId-1).arbitration.haltByOther := True
}
}
}
} else null
@ -489,23 +491,15 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Interrupt/Exception entry logic
pipelineLiberator.enable setWhen(interrupt)
// if(exceptionPortCtrl != null) {
// when(exception) {
// exceptionPortCtrl.exceptionValidsRegs.foreach(_ := False)
// }
// }
when(exception || (interrupt && pipelineLiberator.done)){
jumpInterface.valid := True
jumpInterface.payload := mtvec
memory.arbitration.flushAll := True //Mouai
memory.arbitration.flushAll := True
if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionValidsRegs.last := False
mstatus.MIE := False
mstatus.MPIE := mstatus.MIE
mstatus.MPP := privilege
mepc := exception mux(
True -> writeBack.input(PC),
False -> fetcher.nextPc()._2
)
mepc := mepcCaptureStage.input(PC)
mcause.interrupt := interrupt
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
when(memory.input(ENV_CTRL) === EnvCtrlEnum.MRET) {
memory.arbitration.haltItself := writeBack.arbitration.isValid
when(memory.arbitration.isFiring) {
when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.MRET) {
when(memory.arbitration.isValid || writeBack.arbitration.isValid){
execute.arbitration.haltItself := True
} otherwise {
jumpInterface.valid := True
jumpInterface.payload := mepc
execute.arbitration.flushAll := True
decode.arbitration.flushAll := True
mstatus.MIE := mstatus.MPIE
privilege := mstatus.MPP
}

View File

@ -8,6 +8,9 @@ import StreamVexPimper._
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,
val resetVector : BigInt,
val keepPcPlus4 : Boolean,
@ -28,9 +31,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
assert(!(cmdToRspStageCount == 1 && !injectorStage))
assert(!(compressedGen && !decodePcGen))
var fetcherHalt : Bool = null
lazy val decodeNextPcValid = Bool //TODO remove me ?
lazy val decodeNextPc = UInt(32 bits)
def nextPc() = (False, decodeNextPc)
lazy val pcValids = Vec(Bool, 4)
def pcValid(stage : Stage) = pcValids(pipeline.indexOf(stage))
var incomingInstruction : Bool = null
override def incoming() = incomingInstruction
@ -303,16 +305,29 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
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)
decodeNextPc := decode.input(PC)
def pcUpdatedGen(input : Bool, stucks : Seq[Bool], relaxedInput : Boolean) : Seq[Bool] = {
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

View File

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

View File

@ -1734,7 +1734,7 @@ string riscvTestDiv[] = {
};
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",
"GenQTest", "PollQ", "QueueOverwrite", "QueueSetPolling", "sp_flop", "test1"
//"flop", "sp_flop" // <- Simple test

View File

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