rework csr exception/interrupt handeling wip
This commit is contained in:
parent
dd47db9ad0
commit
d73aa9ce00
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
*.regTraceRef
|
||||
/freertos.gtkw
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
.word 0x3c12083
|
||||
.word 0x34129073
|
||||
|
|
Loading…
Reference in New Issue