diff --git a/chisel/playground/src/pipeline/decoder/Issue.scala b/chisel/playground/src/pipeline/decoder/Issue.scala index 7a0d55e..8c17cb0 100644 --- a/chisel/playground/src/pipeline/decoder/Issue.scala +++ b/chisel/playground/src/pipeline/decoder/Issue.scala @@ -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 := diff --git a/chisel/playground/src/pipeline/execute/fu/Csr.scala b/chisel/playground/src/pipeline/execute/fu/Csr.scala index b3870ff..6f176c3 100644 --- a/chisel/playground/src/pipeline/execute/fu/Csr.scala +++ b/chisel/playground/src/pipeline/execute/fu/Csr.scala @@ -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 - 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 } + + 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), diff --git a/chisel/playground/src/pipeline/memory/MemoryUnit.scala b/chisel/playground/src/pipeline/memory/MemoryUnit.scala index 8153b98..23832db 100644 --- a/chisel/playground/src/pipeline/memory/MemoryUnit.scala +++ b/chisel/playground/src/pipeline/memory/MemoryUnit.scala @@ -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) } diff --git a/chisel/playground/src/pipeline/memory/Mou.scala b/chisel/playground/src/pipeline/memory/Mou.scala index bc90680..0e09b2f 100644 --- a/chisel/playground/src/pipeline/memory/Mou.scala +++ b/chisel/playground/src/pipeline/memory/Mou.scala @@ -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 + }