feat(csr): 增加delegation
This commit is contained in:
parent
895f1e2697
commit
526450efd9
|
@ -57,10 +57,13 @@ class Issue(implicit val config: CpuConfig) extends Module {
|
|||
inst1.fusel === FuType.bru
|
||||
).asUInt.orR
|
||||
|
||||
val is_mou = VecInit(
|
||||
inst0.fusel === FuType.mou,
|
||||
inst1.fusel === FuType.mou
|
||||
).asUInt.orR
|
||||
|
||||
// 下面的情况只进行单发射
|
||||
val single_issue =
|
||||
VecInit(FuType.mou).contains(io.decodeInst(1).fusel) ||
|
||||
is_bru
|
||||
val single_issue = is_mou || is_bru
|
||||
|
||||
// 指令1是否允许执行
|
||||
io.inst1.allow_to_go :=
|
||||
|
|
|
@ -230,12 +230,17 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
|||
val seip = meip
|
||||
val mip_has_interrupt = WireInit(mip)
|
||||
mip_has_interrupt.e.s := mip.e.s | seip
|
||||
val interrupt_enable = Wire(UInt(INT_WID.W)) // 不用考虑ideleg
|
||||
interrupt_enable := Fill(
|
||||
INT_WID,
|
||||
(((mode === ModeM) && mstatus.asTypeOf(new Mstatus()).ie.m) || (mode < ModeM))
|
||||
|
||||
val ideleg = (mideleg & mip_has_interrupt.asUInt)
|
||||
def priviledgedEnableDetect(x: Bool): Bool = Mux(
|
||||
x,
|
||||
((mode === ModeS) && mstatus.asTypeOf(new Mstatus()).ie.s) || (mode < ModeS),
|
||||
((mode === ModeM) && mstatus.asTypeOf(new Mstatus()).ie.m) || (mode < ModeM)
|
||||
)
|
||||
io.decoderUnit.interrupt := mie(11, 0) & mip_has_interrupt.asUInt & interrupt_enable.asUInt
|
||||
|
||||
val interrupt_enable = Wire(Vec(INT_WID, Bool()))
|
||||
interrupt_enable.zip(ideleg.asBools).map { case (x, y) => x := priviledgedEnableDetect(y) }
|
||||
io.decoderUnit.interrupt := mie(INT_WID - 1, 0) & mip_has_interrupt.asUInt & interrupt_enable.asUInt
|
||||
|
||||
// 优先使用inst0的信息
|
||||
val mem_pc = io.memoryUnit.in.pc
|
||||
|
@ -298,8 +303,7 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
|||
|
||||
val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(mem_ex.exception(i), i.U, sum))
|
||||
val interruptNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(mem_ex.interrupt(i), i.U, sum))
|
||||
val causeNO = Mux(has_interrupt, interruptNO, exceptionNO)
|
||||
val cause = (has_interrupt << (XLEN - 1)) | causeNO
|
||||
val causeNO = (has_interrupt << (XLEN - 1)) | Mux(has_interrupt, interruptNO, exceptionNO)
|
||||
|
||||
val has_instrPageFault = mem_ex.exception(instrPageFault)
|
||||
val has_loadPageFault = mem_ex.exception(loadPageFault)
|
||||
|
@ -308,6 +312,9 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
|||
val has_storeAddrMisaligned = mem_ex.exception(storeAddrMisaligned)
|
||||
val has_instrAddrMisaligned = mem_ex.exception(instrAddrMisaligned)
|
||||
|
||||
val deleg = Mux(has_interrupt, mideleg, medeleg)
|
||||
val delegS = (deleg(causeNO(log2Ceil(EXC_WID) - 1, 0))) && (mode < ModeM)
|
||||
|
||||
val tval_wen = has_interrupt ||
|
||||
!(has_instrPageFault ||
|
||||
has_loadPageFault ||
|
||||
|
@ -324,28 +331,43 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
|||
has_loadAddrMisaligned ||
|
||||
has_storeAddrMisaligned
|
||||
) {
|
||||
mtval := SignedExtend(mem_ex.tval, XLEN)
|
||||
val tval = SignedExtend(mem_ex.tval, XLEN)
|
||||
when(mode === ModeM) {
|
||||
mtval := tval
|
||||
}.otherwise {
|
||||
stval := tval
|
||||
}
|
||||
}
|
||||
|
||||
when(has_exc_int) {
|
||||
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
val mstatusNew = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
mcause := cause
|
||||
|
||||
when(delegS) {
|
||||
scause := causeNO
|
||||
sepc := SignedExtend(mem_pc, XLEN)
|
||||
mstatusNew.spp := mode
|
||||
mstatusNew.pie.s := mstatusOld.ie.s
|
||||
mstatusNew.ie.s := false.B
|
||||
mode := ModeS
|
||||
when(tval_wen) { stval := 0.U }
|
||||
}.otherwise {
|
||||
mcause := causeNO
|
||||
mepc := SignedExtend(mem_pc, XLEN)
|
||||
mstatusNew.mpp := mode
|
||||
mstatusNew.pie.m := mstatusOld.ie.m
|
||||
mstatusNew.ie.m := false.B
|
||||
mode := ModeM
|
||||
when(tval_wen) { mtval := 0.U }
|
||||
}
|
||||
mstatus := mstatusNew.asUInt
|
||||
}
|
||||
|
||||
val ret_target = Wire(UInt(VADDR_WID.W))
|
||||
ret_target := DontCare
|
||||
val trap_target = Wire(UInt(VADDR_WID.W))
|
||||
val tvec = mtvec
|
||||
trap_target := tvec(VADDR_WID - 1, 0)
|
||||
|
||||
val trap_target = Wire(UInt(VADDR_WID.W))
|
||||
val tvec = Mux(delegS, stvec, mtvec)
|
||||
trap_target := (tvec(VADDR_WID - 1, 2) << 2) + Mux(
|
||||
tvec(0) && has_interrupt,
|
||||
(causeNO << 2),
|
||||
|
|
|
@ -128,6 +128,6 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
|||
io.ctrl.fence_i := mou.out.fence_i
|
||||
io.ctrl.complete_single_request := lsu.memoryUnit.out.complete_single_request
|
||||
|
||||
io.fetchUnit.flush := io.ctrl.allow_to_go && (io.csr.out.flush || mou.out.fence_i)
|
||||
io.fetchUnit.flush := io.ctrl.allow_to_go && (io.csr.out.flush || mou.out.flush)
|
||||
io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.flush_pc, mou.out.target)
|
||||
}
|
||||
|
|
|
@ -12,20 +12,17 @@ class Mou extends Module {
|
|||
val pc = UInt(XLEN.W)
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val flush = Bool()
|
||||
val fence_i = Bool()
|
||||
val target = UInt(XLEN.W)
|
||||
})
|
||||
})
|
||||
|
||||
val valid = io.in.info.valid
|
||||
val fence_i = valid && io.in.info.fusel === FuType.mou && io.in.info.op === MOUOpType.fencei
|
||||
val valid = io.in.info.valid && io.in.info.fusel === FuType.mou
|
||||
val fence_i = valid && io.in.info.op === MOUOpType.fencei
|
||||
|
||||
// TODO:增加其他fence指令时只要在后面加就行
|
||||
io.out.flush := valid
|
||||
io.out.fence_i := fence_i
|
||||
io.out.target := MuxCase(
|
||||
io.in.pc + 4.U,
|
||||
Seq(
|
||||
fence_i -> (io.in.pc + 4.U)
|
||||
)
|
||||
)
|
||||
io.out.target := io.in.pc + 4.U
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue