From f8cce5b4ae19b9417ef06969614afb2448c7a9b7 Mon Sep 17 00:00:00 2001 From: handsomezhuzhu <2658601135@qq.com> Date: Sun, 12 Oct 2025 00:14:14 +0800 Subject: [PATCH] =?UTF-8?q?lab2=E8=BF=98=E6=9C=89=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=98=B2=E6=AD=A2=E6=94=B9=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab2/src/main/scala/peripheral/Timer.scala | 24 +++++++- lab2/src/main/scala/riscv/core/CLINT.scala | 65 ++++++++++++++------ lab2/src/main/scala/riscv/core/CSR.scala | 16 ++--- lab2/src/main/scala/riscv/core/Execute.scala | 28 +++++++-- 4 files changed, 101 insertions(+), 32 deletions(-) diff --git a/lab2/src/main/scala/peripheral/Timer.scala b/lab2/src/main/scala/peripheral/Timer.scala index bca60cb..e5e1b23 100644 --- a/lab2/src/main/scala/peripheral/Timer.scala +++ b/lab2/src/main/scala/peripheral/Timer.scala @@ -34,5 +34,27 @@ class Timer extends Module { io.debug_enabled := enabled //lab2(CLINTCSR) - //finish the read-write for count,limit,enabled. And produce appropriate signal_interrupt + val address = io.bundle.address + io.bundle.read_data := 0.U + when(address === 0x4.U) { + io.bundle.read_data := limit + }.elsewhen(address === 0x8.U) { + io.bundle.read_data := enabled + } + + when(io.bundle.write_enable) { + when(address === 0x4.U) { + limit := io.bundle.write_data + }.elsewhen(address === 0x8.U) { + enabled := io.bundle.write_data(0) + } + } + + when(enabled && count >= limit) { + io.signal_interrupt := true.B + count := 0.U + }.otherwise { + io.signal_interrupt := false.B + count := count + 1.U + } } diff --git a/lab2/src/main/scala/riscv/core/CLINT.scala b/lab2/src/main/scala/riscv/core/CLINT.scala index de92382..519102d 100644 --- a/lab2/src/main/scala/riscv/core/CLINT.scala +++ b/lab2/src/main/scala/riscv/core/CLINT.scala @@ -15,7 +15,7 @@ package riscv.core import chisel3._ -import chisel3.util.MuxLookup +import chisel3.util._ import riscv.Parameters object InterruptCode { @@ -66,24 +66,49 @@ class CLINT extends Module { io.instruction_address + 4.U, ) //lab2(CLINTCSR) - /* - val interrupt_enable = + 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 = { + 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 =/= InterruptStatus.None && interrupt_enable) { - io.csr_bundle.mstatus_write_data := - io.csr_bundle.mepc_write_data := - io.csr_bundle.mcause_write_data := - io.csr_bundle.direct_write_enable := - io.interrupt_assert := - io.interrupt_handler_address := + when(io.interrupt_flag =/= InterruptCode.None && interrupt_enable) { // 硬件中断 + // 使用字符串构造UInt以避免负数解释错误 + val cause = Mux( + io.interrupt_flag === InterruptCode.Timer0, + "h80000007".U(Parameters.DataWidth), // Machine timer interrupt + "h8000000B".U(Parameters.DataWidth) // Machine external interrupt (for interrupt_flag=2) + ) + 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 + io.interrupt_assert := true.B + io.csr_bundle.direct_write_enable := true.B + io.interrupt_handler_address := io.csr_bundle.mepc + + // 更新 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 } - .elsewhen(io.instruction === InstructionsEnv.ebreak || io.instruction === InstructionsEnv.ecall) { - ...... - } - .elsewhen(io.instruction === InstructionsRet.mret) { - ...... - }.otherwise { - ...... - } - */ -} +} \ No newline at end of file diff --git a/lab2/src/main/scala/riscv/core/CSR.scala b/lab2/src/main/scala/riscv/core/CSR.scala index 8533b4c..49cd9d8 100644 --- a/lab2/src/main/scala/riscv/core/CSR.scala +++ b/lab2/src/main/scala/riscv/core/CSR.scala @@ -71,13 +71,15 @@ class CSR extends Module { io.debug_reg_read_data := MuxLookup(io.debug_reg_read_address, 0.U,regLUT) //lab2(CLINTCSR) - //what data should be passed from csr to clint (Note: what should clint see is the next state of the CPU) - /* - io.clint_access_bundle.mstatus := - io.clint_access_bundle.mtvec := - io.clint_access_bundle.mcause := - io.clint_access_bundle.mepc := - */ + val mstatus_next = Mux(io.reg_write_enable_id && io.reg_write_address_id === CSRRegister.MSTATUS, io.reg_write_data_ex, mstatus) + val mepc_next = Mux(io.reg_write_enable_id && io.reg_write_address_id === CSRRegister.MEPC, io.reg_write_data_ex, mepc) + val mcause_next = Mux(io.reg_write_enable_id && io.reg_write_address_id === CSRRegister.MCAUSE, io.reg_write_data_ex, mcause) + val mtvec_next = Mux(io.reg_write_enable_id && io.reg_write_address_id === CSRRegister.MTVEC, io.reg_write_data_ex, mtvec) + + io.clint_access_bundle.mstatus := mstatus_next + io.clint_access_bundle.mepc := mepc_next + io.clint_access_bundle.mcause := mcause_next + io.clint_access_bundle.mtvec := mtvec_next when(io.clint_access_bundle.direct_write_enable) { mstatus := io.clint_access_bundle.mstatus_write_data diff --git a/lab2/src/main/scala/riscv/core/Execute.scala b/lab2/src/main/scala/riscv/core/Execute.scala index 96ac0c8..23dfabc 100644 --- a/lab2/src/main/scala/riscv/core/Execute.scala +++ b/lab2/src/main/scala/riscv/core/Execute.scala @@ -73,7 +73,27 @@ class Execute extends Module { io.if_jump_address := io.immediate + Mux(opcode === Instructions.jalr, io.reg1_data, io.instruction_address) io.mem_alu_result := alu.io.result //lab2(CLINTCSR) - /* - io.csr_reg_write_data := - */ -} + val rs1_data = io.reg1_data + val uimm = io.instruction(19, 15) + + // 默认写回数据为0 + io.csr_reg_write_data := 0.U + + // 使用 opcode 的字面量值,确保判断正确 + when(opcode === "b1110011".U) { + val rs1_is_zero = io.instruction(19, 15) === 0.U + io.csr_reg_write_data := MuxLookup( + funct3, + 0.U, + IndexedSeq( + InstructionsTypeCSR.csrrw -> rs1_data, + InstructionsTypeCSR.csrrs -> Mux(rs1_is_zero, io.csr_reg_read_data, io.csr_reg_read_data | rs1_data), + InstructionsTypeCSR.csrrc -> Mux(rs1_is_zero, io.csr_reg_read_data, io.csr_reg_read_data & (~rs1_data).asUInt), + InstructionsTypeCSR.csrrwi -> uimm, + InstructionsTypeCSR.csrrsi -> Mux(uimm === 0.U, io.csr_reg_read_data, io.csr_reg_read_data | uimm), + InstructionsTypeCSR.csrrci -> Mux(uimm === 0.U, io.csr_reg_read_data, io.csr_reg_read_data & (~uimm).asUInt) + ) + ) + } + +} \ No newline at end of file