lab2离成功又近了一步

This commit is contained in:
2025-10-12 00:26:44 +08:00
parent f8cce5b4ae
commit d6b780df0f

View File

@@ -69,46 +69,62 @@ class CLINT extends Module {
val mstatus = io.csr_bundle.mstatus val mstatus = io.csr_bundle.mstatus
val mie = mstatus(3) val mie = mstatus(3)
val mpie = mstatus(7) val mpie = mstatus(7)
// 默认输出 // 使用串行的 when-elsewhen 结构确保只有一个分支被执行
io.interrupt_assert := false.B when(io.instruction === InstructionsRet.mret) {
io.interrupt_handler_address := 0.U // 处理 mret
io.csr_bundle.mstatus_write_data := 0.U io.interrupt_assert := true.B
io.csr_bundle.mepc_write_data := 0.U io.csr_bundle.direct_write_enable := true.B
io.csr_bundle.mcause_write_data := 0.U io.interrupt_handler_address := io.csr_bundle.mepc
io.csr_bundle.direct_write_enable := false.B // mstatus 更新: MIE <- MPIE, MPIE <- 1
// 提取公共的陷阱处理逻辑 val new_mie = mpie << 3
def handle_trap(cause: UInt): Unit = { 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.interrupt_assert := true.B
io.csr_bundle.direct_write_enable := true.B io.csr_bundle.direct_write_enable := true.B
io.interrupt_handler_address := io.csr_bundle.mtvec io.interrupt_handler_address := io.csr_bundle.mtvec
io.csr_bundle.mepc_write_data := instruction_address io.csr_bundle.mepc_write_data := instruction_address
io.csr_bundle.mcause_write_data := cause io.csr_bundle.mcause_write_data := Mux(
// 更新 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.interrupt_flag === InterruptCode.Timer0, io.interrupt_flag === InterruptCode.Timer0,
"h80000007".U(Parameters.DataWidth), // Machine timer interrupt "h80000007".U(Parameters.DataWidth),
"h8000000B".U(Parameters.DataWidth) // Machine external interrupt (for interrupt_flag=2) "h8000000B".U(Parameters.DataWidth)
) )
handle_trap(cause) // mstatus 更新: MIE <- 0, MPIE <- MIE
}.elsewhen(io.instruction === InstructionsEnv.ecall) { // ecall val new_mpie = mie << 7
handle_trap(11.U) // Environment call from M-mode io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 3)).asUInt) | new_mpie | (3.U << 11)
}.elsewhen(io.instruction === InstructionsEnv.ebreak) { // ebreak }.elsewhen(io.instruction === InstructionsEnv.ecall) {
handle_trap(3.U) // Breakpoint // 处理 ecall
}.elsewhen(io.instruction === InstructionsRet.mret) { // mret
io.interrupt_assert := true.B io.interrupt_assert := true.B
io.csr_bundle.direct_write_enable := 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) // 把 CSR 的原值“写回”,相当于不改变它们
val new_mie = mpie << 3 io.csr_bundle.mstatus_write_data := mstatus
// 清除 MPIE, 设置 MIE 和 MPIE, MPP io.csr_bundle.mepc_write_data := io.csr_bundle.mepc
io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 7)).asUInt) | new_mie.asUInt| (1.U << 7).asUInt | (3.U << 11).asUInt io.csr_bundle.mcause_write_data := io.csr_bundle.mcause
} }
} }