Merge remote-tracking branch 'origin/pipelinedInterrupt'
This commit is contained in:
commit
0e2d40c37f
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue