提交 e9341afd 编写于 作者: Y Yinan Xu

csr: fix priority of interrupts and exceptions

上级 c4401c32
......@@ -597,58 +597,92 @@ class CSR extends FunctionUnit with HasCSRConst
tlbBundle.priv.imode := priviledgeMode
tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode)
val hasInstrPageFault = csrio.exception.bits.cf.exceptionVec(instrPageFault) && csrio.exception.valid
val hasLoadPageFault = csrio.exception.bits.cf.exceptionVec(loadPageFault) && csrio.exception.valid
val hasStorePageFault = csrio.exception.bits.cf.exceptionVec(storePageFault) && csrio.exception.valid
val hasStoreAddrMisaligned = csrio.exception.bits.cf.exceptionVec(storeAddrMisaligned) && csrio.exception.valid
val hasLoadAddrMisaligned = csrio.exception.bits.cf.exceptionVec(loadAddrMisaligned) && csrio.exception.valid
// Branch control
val retTarget = Wire(UInt(VAddrBits.W))
val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
csrio.redirectOut.valid := valid && func === CSROpType.jmp && !isEcall
csrio.redirectOut.bits := retTarget
flushPipe := resetSatp
XSDebug(csrio.redirectOut.valid, "redirect to %x, pc=%x\n", csrio.redirectOut.bits, cfIn.pc)
// mtval write logic
val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
when(hasInstrPageFault || hasLoadPageFault || hasStorePageFault){
val tval = Mux(
hasInstrPageFault,
Mux(
csrio.exception.bits.cf.crossPageIPFFix,
SignExt(csrio.exception.bits.cf.pc + 2.U, XLEN),
SignExt(csrio.exception.bits.cf.pc, XLEN)
),
memExceptionAddr
)
when(priviledgeMode === ModeM){
mtval := tval
}.otherwise{
stval := tval
}
retTarget := DontCare
// val illegalEret = TODO
when (valid && isMret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
mstatusNew.ie.m := mstatusOld.pie.m
priviledgeMode := mstatusOld.mpp
mstatusNew.pie.m := true.B
mstatusNew.mpp := ModeU
mstatusNew.mprv := 0.U
mstatus := mstatusNew.asUInt
// lr := false.B
retTarget := mepc(VAddrBits-1, 0)
}
when(hasLoadAddrMisaligned || hasStoreAddrMisaligned)
{
mtval := memExceptionAddr
when (valid && isSret && !illegalSModeSret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
mstatusNew.ie.s := mstatusOld.pie.s
priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
mstatusNew.pie.s := true.B
mstatusNew.spp := ModeU
mstatus := mstatusNew.asUInt
mstatusNew.mprv := 0.U
// lr := false.B
retTarget := sepc(VAddrBits-1, 0)
}
// Exception and Intr
when (valid && isUret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
// mstatusNew.mpp.m := ModeU //TODO: add mode U
mstatusNew.ie.u := mstatusOld.pie.u
priviledgeMode := ModeU
mstatusNew.pie.u := true.B
mstatus := mstatusNew.asUInt
retTarget := uepc(VAddrBits-1, 0)
}
// interrupts
XSDebug(csrio.redirectOut.valid,
"Rediret %x isSret:%d retTarget:%x sepc:%x cfInpc:%x valid:%d\n",
csrio.redirectOut.bits, isSret, retTarget, sepc, cfIn.pc, valid
)
io.in.ready := true.B
io.out.valid := valid
/**
* Exception and Intr
*/
val ideleg = (mideleg & mip.asUInt)
def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
// send interrupt information to ROQ
val intrVecEnable = Wire(Vec(12, Bool()))
intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt
val intrBitSet = intrVec.orR()
csrio.interrupt := intrBitSet
val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
val raiseIntr = intrBitSet && csrio.exception.valid && csrio.isInterrupt
XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.cf.pc, intrNO)
mipWire.t.m := csrio.externalInterrupt.mtip
mipWire.s.m := csrio.externalInterrupt.msip
mipWire.e.m := csrio.externalInterrupt.meip
// interrupts
val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
val raiseIntr = csrio.exception.valid && csrio.isInterrupt
XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.cf.pc, intrNO)
// exceptions
val raiseException = csrio.exception.valid && !csrio.isInterrupt
val hasInstrPageFault = csrio.exception.bits.cf.exceptionVec(instrPageFault) && raiseException
val hasLoadPageFault = csrio.exception.bits.cf.exceptionVec(loadPageFault) && raiseException
val hasStorePageFault = csrio.exception.bits.cf.exceptionVec(storePageFault) && raiseException
val hasStoreAddrMisaligned = csrio.exception.bits.cf.exceptionVec(storeAddrMisaligned) && raiseException
val hasLoadAddrMisaligned = csrio.exception.bits.cf.exceptionVec(loadAddrMisaligned) && raiseException
val csrExceptionVec = Wire(Vec(16, Bool()))
csrExceptionVec.map(_ := false.B)
csrExceptionVec(breakPoint) := io.in.valid && isEbreak
......@@ -676,14 +710,6 @@ class CSR extends FunctionUnit with HasCSRConst
// }
val raiseExceptionIntr = csrio.exception.valid
val retTarget = Wire(UInt(VAddrBits.W))
val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
csrio.redirectOut.valid := valid && func === CSROpType.jmp && !isEcall
csrio.redirectOut.bits := retTarget
flushPipe := resetSatp
XSDebug(csrio.redirectOut.valid, "redirect to %x, pc=%x\n", csrio.redirectOut.bits, cfIn.pc)
XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
csrio.exception.bits.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
)
......@@ -696,53 +722,35 @@ class CSR extends FunctionUnit with HasCSRConst
priviledgeMode
)
// Branch control
// mtval write logic
val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
when(hasInstrPageFault || hasLoadPageFault || hasStorePageFault){
val tval = Mux(
hasInstrPageFault,
Mux(
csrio.exception.bits.cf.crossPageIPFFix,
SignExt(csrio.exception.bits.cf.pc + 2.U, XLEN),
SignExt(csrio.exception.bits.cf.pc, XLEN)
),
memExceptionAddr
)
when(priviledgeMode === ModeM){
mtval := tval
}.otherwise{
stval := tval
}
}
when(hasLoadAddrMisaligned || hasStoreAddrMisaligned)
{
mtval := memExceptionAddr
}
val deleg = Mux(raiseIntr, mideleg , medeleg)
// val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
val delegS = (deleg(causeNO(3,0))) && (priviledgeMode < ModeM)
val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check
csrio.trapTarget := Mux(delegS, stvec, mtvec)(VAddrBits-1, 0)
retTarget := DontCare
// val illegalEret = TODO
when (valid && isMret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
mstatusNew.ie.m := mstatusOld.pie.m
priviledgeMode := mstatusOld.mpp
mstatusNew.pie.m := true.B
mstatusNew.mpp := ModeU
mstatusNew.mprv := 0.U
mstatus := mstatusNew.asUInt
// lr := false.B
retTarget := mepc(VAddrBits-1, 0)
}
when (valid && isSret && !illegalSModeSret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
mstatusNew.ie.s := mstatusOld.pie.s
priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
mstatusNew.pie.s := true.B
mstatusNew.spp := ModeU
mstatus := mstatusNew.asUInt
mstatusNew.mprv := 0.U
// lr := false.B
retTarget := sepc(VAddrBits-1, 0)
}
when (valid && isUret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
// mstatusNew.mpp.m := ModeU //TODO: add mode U
mstatusNew.ie.u := mstatusOld.pie.u
priviledgeMode := ModeU
mstatusNew.pie.u := true.B
mstatus := mstatusNew.asUInt
retTarget := uepc(VAddrBits-1, 0)
}
when (raiseExceptionIntr) {
val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
......@@ -771,40 +779,17 @@ class CSR extends FunctionUnit with HasCSRConst
mstatus := mstatusNew.asUInt
}
io.in.ready := true.B
io.out.valid := valid
XSDebug(csrio.redirectOut.valid,
"Rediret %x raiseExcepIntr:%d isSret:%d retTarget:%x sepc:%x delegs:%d deleg:%x cfInpc:%x valid:%d\n",
csrio.redirectOut.bits,
raiseExceptionIntr,
isSret,
retTarget,
sepc,
delegS,
deleg,
cfIn.pc,
valid
)
XSDebug(raiseExceptionIntr && delegS,
"Red(%d, %x) raiseExcepIntr:%d isSret:%d retTarget:%x sepc:%x delegs:%d deleg:%x cfInpc:%x valid:%d\n",
csrio.redirectOut.valid,
csrio.redirectOut.bits,
raiseExceptionIntr,
isSret,
retTarget,
sepc,
delegS,
deleg,
cfIn.pc,
valid
"Red(%d, %x) raiseExcepIntr:%d isSret:%d sepc:%x delegs:%d deleg:%x\n",
csrio.redirectOut.valid, csrio.redirectOut.bits, raiseExceptionIntr,
isSret, sepc, delegS, deleg
)
XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
// perfcnt
/**
* Performance counters
*/
val perfCntList = Map(
// "Mcycle" -> (0xb00, "perfCntCondMcycle" ),
// "Minstret" -> (0xb02, "perfCntCondMinstret" ),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册