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