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
|
inst1.fusel === FuType.bru
|
||||||
).asUInt.orR
|
).asUInt.orR
|
||||||
|
|
||||||
|
val is_mou = VecInit(
|
||||||
|
inst0.fusel === FuType.mou,
|
||||||
|
inst1.fusel === FuType.mou
|
||||||
|
).asUInt.orR
|
||||||
|
|
||||||
// 下面的情况只进行单发射
|
// 下面的情况只进行单发射
|
||||||
val single_issue =
|
val single_issue = is_mou || is_bru
|
||||||
VecInit(FuType.mou).contains(io.decodeInst(1).fusel) ||
|
|
||||||
is_bru
|
|
||||||
|
|
||||||
// 指令1是否允许执行
|
// 指令1是否允许执行
|
||||||
io.inst1.allow_to_go :=
|
io.inst1.allow_to_go :=
|
||||||
|
|
|
@ -230,12 +230,17 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
||||||
val seip = meip
|
val seip = meip
|
||||||
val mip_has_interrupt = WireInit(mip)
|
val mip_has_interrupt = WireInit(mip)
|
||||||
mip_has_interrupt.e.s := mip.e.s | seip
|
mip_has_interrupt.e.s := mip.e.s | seip
|
||||||
val interrupt_enable = Wire(UInt(INT_WID.W)) // 不用考虑ideleg
|
|
||||||
interrupt_enable := Fill(
|
val ideleg = (mideleg & mip_has_interrupt.asUInt)
|
||||||
INT_WID,
|
def priviledgedEnableDetect(x: Bool): Bool = Mux(
|
||||||
(((mode === ModeM) && mstatus.asTypeOf(new Mstatus()).ie.m) || (mode < ModeM))
|
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的信息
|
// 优先使用inst0的信息
|
||||||
val mem_pc = io.memoryUnit.in.pc
|
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 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 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 causeNO = (has_interrupt << (XLEN - 1)) | Mux(has_interrupt, interruptNO, exceptionNO)
|
||||||
val cause = (has_interrupt << (XLEN - 1)) | causeNO
|
|
||||||
|
|
||||||
val has_instrPageFault = mem_ex.exception(instrPageFault)
|
val has_instrPageFault = mem_ex.exception(instrPageFault)
|
||||||
val has_loadPageFault = mem_ex.exception(loadPageFault)
|
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_storeAddrMisaligned = mem_ex.exception(storeAddrMisaligned)
|
||||||
val has_instrAddrMisaligned = mem_ex.exception(instrAddrMisaligned)
|
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 ||
|
val tval_wen = has_interrupt ||
|
||||||
!(has_instrPageFault ||
|
!(has_instrPageFault ||
|
||||||
has_loadPageFault ||
|
has_loadPageFault ||
|
||||||
|
@ -324,28 +331,43 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
||||||
has_loadAddrMisaligned ||
|
has_loadAddrMisaligned ||
|
||||||
has_storeAddrMisaligned
|
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) {
|
when(has_exc_int) {
|
||||||
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||||
val mstatusNew = 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)
|
mepc := SignedExtend(mem_pc, XLEN)
|
||||||
mstatusNew.mpp := mode
|
mstatusNew.mpp := mode
|
||||||
mstatusNew.pie.m := mstatusOld.ie.m
|
mstatusNew.pie.m := mstatusOld.ie.m
|
||||||
mstatusNew.ie.m := false.B
|
mstatusNew.ie.m := false.B
|
||||||
mode := ModeM
|
mode := ModeM
|
||||||
when(tval_wen) { mtval := 0.U }
|
when(tval_wen) { mtval := 0.U }
|
||||||
|
}
|
||||||
mstatus := mstatusNew.asUInt
|
mstatus := mstatusNew.asUInt
|
||||||
}
|
}
|
||||||
|
|
||||||
val ret_target = Wire(UInt(VADDR_WID.W))
|
val ret_target = Wire(UInt(VADDR_WID.W))
|
||||||
ret_target := DontCare
|
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(
|
trap_target := (tvec(VADDR_WID - 1, 2) << 2) + Mux(
|
||||||
tvec(0) && has_interrupt,
|
tvec(0) && has_interrupt,
|
||||||
(causeNO << 2),
|
(causeNO << 2),
|
||||||
|
|
|
@ -128,6 +128,6 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
||||||
io.ctrl.fence_i := mou.out.fence_i
|
io.ctrl.fence_i := mou.out.fence_i
|
||||||
io.ctrl.complete_single_request := lsu.memoryUnit.out.complete_single_request
|
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)
|
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 pc = UInt(XLEN.W)
|
||||||
})
|
})
|
||||||
val out = Output(new Bundle {
|
val out = Output(new Bundle {
|
||||||
|
val flush = Bool()
|
||||||
val fence_i = Bool()
|
val fence_i = Bool()
|
||||||
val target = UInt(XLEN.W)
|
val target = UInt(XLEN.W)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
val valid = io.in.info.valid
|
val valid = io.in.info.valid && io.in.info.fusel === FuType.mou
|
||||||
val fence_i = valid && io.in.info.fusel === FuType.mou && io.in.info.op === MOUOpType.fencei
|
val fence_i = valid && io.in.info.op === MOUOpType.fencei
|
||||||
|
|
||||||
// TODO:增加其他fence指令时只要在后面加就行
|
io.out.flush := valid
|
||||||
io.out.fence_i := fence_i
|
io.out.fence_i := fence_i
|
||||||
io.out.target := MuxCase(
|
io.out.target := io.in.pc + 4.U
|
||||||
io.in.pc + 4.U,
|
|
||||||
Seq(
|
|
||||||
fence_i -> (io.in.pc + 4.U)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue