mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
lab2离成功又近了一步
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user