mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
lab2打包
This commit is contained in:
126
lab2/朱梓涵24325356/core/CLINT.scala
Normal file
126
lab2/朱梓涵24325356/core/CLINT.scala
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2021 Howard Lau
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package riscv.core
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import riscv.Parameters
|
||||
|
||||
object InterruptCode {
|
||||
val None = 0x0.U(8.W)
|
||||
val Timer0 = 0x1.U(8.W)
|
||||
val Ret = 0xFF.U(8.W)
|
||||
}
|
||||
|
||||
object InterruptEntry {
|
||||
val Timer0 = 0x4.U(8.W)
|
||||
}
|
||||
|
||||
|
||||
class CSRDirectAccessBundle extends Bundle {
|
||||
val mstatus = Input(UInt(Parameters.DataWidth))
|
||||
val mepc = Input(UInt(Parameters.DataWidth))
|
||||
val mcause = Input(UInt(Parameters.DataWidth))
|
||||
val mtvec = Input(UInt(Parameters.DataWidth))
|
||||
|
||||
val mstatus_write_data= Output(UInt(Parameters.DataWidth))
|
||||
val mepc_write_data= Output(UInt(Parameters.DataWidth))
|
||||
val mcause_write_data= Output(UInt(Parameters.DataWidth))
|
||||
|
||||
val direct_write_enable = Output(Bool())
|
||||
}
|
||||
|
||||
// Core Local Interrupt Controller
|
||||
class CLINT extends Module {
|
||||
val io = IO(new Bundle {
|
||||
// Interrupt signals from peripherals
|
||||
val interrupt_flag = Input(UInt(Parameters.InterruptFlagWidth))
|
||||
|
||||
val instruction = Input(UInt(Parameters.InstructionWidth))
|
||||
val instruction_address = Input(UInt(Parameters.AddrWidth))
|
||||
|
||||
val jump_flag = Input(Bool())
|
||||
val jump_address = Input(UInt(Parameters.AddrWidth))
|
||||
|
||||
val interrupt_handler_address = Output(UInt(Parameters.AddrWidth))
|
||||
val interrupt_assert = Output(Bool())
|
||||
|
||||
val csr_bundle = new CSRDirectAccessBundle
|
||||
})
|
||||
val interrupt_enable = io.csr_bundle.mstatus(3)
|
||||
val instruction_address = Mux(
|
||||
io.jump_flag,
|
||||
io.jump_address,
|
||||
io.instruction_address + 4.U,
|
||||
)
|
||||
//lab2(CLINTCSR)
|
||||
val mstatus = io.csr_bundle.mstatus
|
||||
val mie = mstatus(3)
|
||||
val mpie = mstatus(7)
|
||||
|
||||
when(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 := Mux(
|
||||
io.interrupt_flag === InterruptCode.Timer0,
|
||||
"h80000007".U(Parameters.DataWidth),
|
||||
"h8000000B".U(Parameters.DataWidth)
|
||||
)
|
||||
val new_mpie = mie << 7
|
||||
io.csr_bundle.mstatus_write_data := (mstatus & (~(1.U << 3)).asUInt) | new_mpie | (3.U << 11)
|
||||
}.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 // 跳转回 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.instruction === InstructionsEnv.ecall) {
|
||||
// 处理 ecall
|
||||
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 := 11.U
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user