Merge remote-tracking branch 'origin/pipelinedInterrupt'

This commit is contained in:
Charles Papon 2019-06-09 12:29:20 +02:00
commit 0e2d40c37f
2 changed files with 32 additions and 26 deletions

View File

@ -68,6 +68,7 @@ case class CsrPluginConfig(
medelegAccess : CsrAccess = CsrAccess.NONE,
midelegAccess : CsrAccess = CsrAccess.NONE,
pipelineCsrRead : Boolean = false,
pipelinedInterrupt : Boolean = true,
deterministicInteruptionEntry : Boolean = false //Only used for simulatation purposes
){
assert(!ucycleAccess.canWrite)
@ -729,32 +730,37 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
//Process interrupt request, code and privilege
val interrupt = False
val interruptCode = UInt(4 bits).assignDontCare().addTag(Verilator.public)
var interruptPrivilegs = if (supervisorGen) List(1, 3) else List(3)
val interruptTargetPrivilege = UInt(2 bits).assignDontCare()
val privilegeAllowInterrupts = mutable.HashMap[Int, Bool]()
if(supervisorGen) privilegeAllowInterrupts += 1 -> ((sstatus.SIE && privilege === "01") || privilege < "01")
privilegeAllowInterrupts += 3 -> (mstatus.MIE || privilege < "11")
while(interruptPrivilegs.nonEmpty){
val p = interruptPrivilegs.head
when(privilegeAllowInterrupts(p)){
for(i <- interruptSpecs
if i.privilege <= p //EX : Machine timer interrupt can't go into supervisor mode
if interruptPrivilegs.tail.forall(e => i.delegators.exists(_.privilege == e))){ // EX : Supervisor timer need to have machine mode delegator
val delegUpOn = i.delegators.filter(_.privilege > p).map(_.enable).fold(True)(_ && _)
val delegDownOff = !i.delegators.filter(_.privilege <= p).map(_.enable).orR
when(i.cond && delegUpOn && delegDownOff){
interrupt := True
interruptCode := i.id
interruptTargetPrivilege := p
val interrupt = new Area {
val valid = if(pipelinedInterrupt) RegNext(False) init(False) else False
val code = if(pipelinedInterrupt) Reg(UInt(4 bits)) else UInt(4 bits).assignDontCare()
var privilegs = if (supervisorGen) List(1, 3) else List(3)
val targetPrivilege = if(pipelinedInterrupt) Reg(UInt(2 bits)) else UInt(2 bits).assignDontCare()
val privilegeAllowInterrupts = mutable.HashMap[Int, Bool]()
if (supervisorGen) privilegeAllowInterrupts += 1 -> ((sstatus.SIE && privilege === "01") || privilege < "01")
privilegeAllowInterrupts += 3 -> (mstatus.MIE || privilege < "11")
while (privilegs.nonEmpty) {
val p = privilegs.head
when(privilegeAllowInterrupts(p)) {
for (i <- interruptSpecs
if i.privilege <= p //EX : Machine timer interrupt can't go into supervisor mode
if privilegs.tail.forall(e => i.delegators.exists(_.privilege == e))) { // EX : Supervisor timer need to have machine mode delegator
val delegUpOn = i.delegators.filter(_.privilege > p).map(_.enable).fold(True)(_ && _)
val delegDownOff = !i.delegators.filter(_.privilege <= p).map(_.enable).orR
when(i.cond && delegUpOn && delegDownOff) {
valid := True
code := i.id
targetPrivilege := p
}
}
}
privilegs = privilegs.tail
}
interruptPrivilegs = interruptPrivilegs.tail
code.addTag(Verilator.public)
}
interrupt.clearWhen(!allowInterrupts)
val exception = if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionValids.last && allowException else False
val lastStageWasWfi = if(wfiGenAsWait) RegNext(lastStage.arbitration.isFiring && lastStage.input(ENV_CTRL) === EnvCtrlEnum.WFI) init(False) else False
@ -763,7 +769,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
//Used to make the pipeline empty softly (for interrupts)
val pipelineLiberator = new Area{
when(interrupt){
when(interrupt.valid && allowInterrupts){
decode.arbitration.haltByOther := decode.arbitration.isValid
}
@ -773,18 +779,18 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
//Interrupt/Exception entry logic
val interruptJump = Bool.addTag(Verilator.public)
interruptJump := interrupt && pipelineLiberator.done
interruptJump := interrupt.valid && pipelineLiberator.done && allowInterrupts
val hadException = RegNext(exception) init(False)
pipelineLiberator.done.clearWhen(hadException)
val targetPrivilege = CombInit(interruptTargetPrivilege)
val targetPrivilege = CombInit(interrupt.targetPrivilege)
if(exceptionPortCtrl != null) when(hadException) {
targetPrivilege := exceptionPortCtrl.exceptionTargetPrivilege
}
val trapCause = CombInit(interruptCode)
val trapCause = CombInit(interrupt.code)
if(exceptionPortCtrl != null) when( hadException){
trapCause := exceptionPortCtrl.exceptionContext.code
}

View File

@ -1550,7 +1550,7 @@ public:
riscvRef.liveness(top->VexRiscv->execute_CsrPlugin_inWfi);
if(top->VexRiscv->CsrPlugin_interruptJump){
if(riscvRefEnable) riscvRef.trap(true, top->VexRiscv->CsrPlugin_interruptCode);
if(riscvRefEnable) riscvRef.trap(true, top->VexRiscv->CsrPlugin_interrupt_code);
}
}
#endif