From d6b780df0f86b62468097589a1ac88e4eb4a6b9a Mon Sep 17 00:00:00 2001 From: handsomezhuzhu <2658601135@qq.com> Date: Sun, 12 Oct 2025 00:26:44 +0800 Subject: [PATCH] =?UTF-8?q?lab2=E7=A6=BB=E6=88=90=E5=8A=9F=E5=8F=88?= =?UTF-8?q?=E8=BF=91=E4=BA=86=E4=B8=80=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab2/src/main/scala/riscv/core/CLINT.scala | 80 +++++++++++++--------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/lab2/src/main/scala/riscv/core/CLINT.scala b/lab2/src/main/scala/riscv/core/CLINT.scala index 519102d..d62757d 100644 --- a/lab2/src/main/scala/riscv/core/CLINT.scala +++ b/lab2/src/main/scala/riscv/core/CLINT.scala @@ -69,46 +69,62 @@ class CLINT extends Module { val mstatus = io.csr_bundle.mstatus val mie = mstatus(3) val mpie = mstatus(7) - // 默认输出 - io.interrupt_assert := false.B - io.interrupt_handler_address := 0.U - io.csr_bundle.mstatus_write_data := 0.U - io.csr_bundle.mepc_write_data := 0.U - io.csr_bundle.mcause_write_data := 0.U - io.csr_bundle.direct_write_enable := false.B - // 提取公共的陷阱处理逻辑 - def handle_trap(cause: UInt): Unit = { + // 使用串行的 when-elsewhen 结构确保只有一个分支被执行 + when(io.instruction === InstructionsRet.mret) { + // 处理 mret + io.interrupt_assert := true.B + io.csr_bundle.direct_write_enable := true.B + io.interrupt_handler_address := io.csr_bundle.mepc + // mstatus 更新: MIE <- MPIE, MPIE <- 1 + val new_mie = mpie << 3 + io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 7)).asUInt) | new_mie | (1.U << 7) | (3.U << 11) + + // mret 不更新 mepc 和 mcause,所以把原来的值写回去 + io.csr_bundle.mepc_write_data := io.csr_bundle.mepc + io.csr_bundle.mcause_write_data := io.csr_bundle.mcause + }.elsewhen(io.interrupt_flag =/= InterruptCode.None && interrupt_enable) { + // 处理硬件中断 io.interrupt_assert := true.B io.csr_bundle.direct_write_enable := true.B io.interrupt_handler_address := io.csr_bundle.mtvec io.csr_bundle.mepc_write_data := instruction_address - io.csr_bundle.mcause_write_data := cause - // 更新 mstatus: MIE(bit 3) <- 0, MPIE(bit 7) <- MIE, MPP(bits 12,11) <- 11 - val new_mpie = mie << 7 - // 清除 MIE, 设置 MPIE 和 MPP - io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 3)).asUInt) | new_mpie.asUInt | (3.U << 11).asUInt - } - - when(io.interrupt_flag =/= InterruptCode.None && interrupt_enable) { // 硬件中断 - // 使用字符串构造UInt以避免负数解释错误 - val cause = Mux( + io.csr_bundle.mcause_write_data := Mux( io.interrupt_flag === InterruptCode.Timer0, - "h80000007".U(Parameters.DataWidth), // Machine timer interrupt - "h8000000B".U(Parameters.DataWidth) // Machine external interrupt (for interrupt_flag=2) + "h80000007".U(Parameters.DataWidth), + "h8000000B".U(Parameters.DataWidth) ) - handle_trap(cause) - }.elsewhen(io.instruction === InstructionsEnv.ecall) { // ecall - handle_trap(11.U) // Environment call from M-mode - }.elsewhen(io.instruction === InstructionsEnv.ebreak) { // ebreak - handle_trap(3.U) // Breakpoint - }.elsewhen(io.instruction === InstructionsRet.mret) { // mret + // mstatus 更新: MIE <- 0, MPIE <- MIE + val new_mpie = mie << 7 + io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 3)).asUInt) | new_mpie | (3.U << 11) + }.elsewhen(io.instruction === InstructionsEnv.ecall) { + // 处理 ecall io.interrupt_assert := true.B io.csr_bundle.direct_write_enable := true.B - io.interrupt_handler_address := io.csr_bundle.mepc + io.interrupt_handler_address := io.csr_bundle.mtvec + io.csr_bundle.mepc_write_data := instruction_address + io.csr_bundle.mcause_write_data := 11.U + // mstatus 更新: MIE <- 0, MPIE <- MIE + val new_mpie = mie << 7 + io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 3)).asUInt) | new_mpie | (3.U << 11) + }.elsewhen(io.instruction === InstructionsEnv.ebreak) { + // 处理 ebreak + io.interrupt_assert := true.B + io.csr_bundle.direct_write_enable := true.B + io.interrupt_handler_address := io.csr_bundle.mtvec + io.csr_bundle.mepc_write_data := instruction_address + io.csr_bundle.mcause_write_data := 3.U + // mstatus 更新: MIE <- 0, MPIE <- MIE + val new_mpie = mie << 7 + io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 3)).asUInt) | new_mpie | (3.U << 11) + }.otherwise { + // 默认情况,所有信号都设为默认值 + io.interrupt_assert := false.B + io.csr_bundle.direct_write_enable := false.B + io.interrupt_handler_address := 0.U - // 更新 mstatus: MIE(bit 3) <- MPIE, MPIE(bit 7) <- 1, MPP(bits 12,11) <- 11 (保持Machine Mode) - val new_mie = mpie << 3 - // 清除 MPIE, 设置 MIE 和 MPIE, MPP - io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 7)).asUInt) | new_mie.asUInt| (1.U << 7).asUInt | (3.U << 11).asUInt + // 把 CSR 的原值“写回”,相当于不改变它们 + io.csr_bundle.mstatus_write_data := mstatus + io.csr_bundle.mepc_write_data := io.csr_bundle.mepc + io.csr_bundle.mcause_write_data := io.csr_bundle.mcause } } \ No newline at end of file