feat(csr): 增加exc、int和mret的信号处理

This commit is contained in:
Liphen 2023-11-29 16:37:51 +08:00
parent 610323dec9
commit a4247ae490
5 changed files with 105 additions and 61 deletions

View File

@ -7,6 +7,7 @@ import cpu.CpuConfig
trait CoreParameter { trait CoreParameter {
def config = new CpuConfig def config = new CpuConfig
val XLEN = if (config.isRV32) 32 else 64 val XLEN = if (config.isRV32) 32 else 64
val VADDR_WID = 32
} }
trait Constants extends CoreParameter { trait Constants extends CoreParameter {

View File

@ -5,32 +5,26 @@ import chisel3.util._
import cpu.defines.Const._ import cpu.defines.Const._
class Mstatus extends Bundle { class Mstatus extends Bundle {
val sd = Bool() val sd = Output(UInt(1.W))
val wpri0 = UInt(25.W)
val mbe = Bool() val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null
val sbe = Bool() val sxl = if (XLEN == 64) Output(UInt(2.W)) else null
val sxl = UInt(2.W) val uxl = if (XLEN == 64) Output(UInt(2.W)) else null
val uxl = UInt(2.W) val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W))
val wpri1 = UInt(9.W)
val tsr = Bool() val tsr = Output(UInt(1.W))
val tw = Bool() val tw = Output(UInt(1.W))
val tvm = Bool() val tvm = Output(UInt(1.W))
val mxr = Bool() val mxr = Output(UInt(1.W))
val sum = Bool() val sum = Output(UInt(1.W))
val mprv = Bool() val mprv = Output(UInt(1.W))
val xs = UInt(2.W) val xs = Output(UInt(2.W))
val fs = UInt(2.W) val fs = Output(UInt(2.W))
val mpp = UInt(2.W) val mpp = Output(UInt(2.W))
val vs = UInt(2.W) val hpp = Output(UInt(2.W))
val spp = Bool() val spp = Output(UInt(1.W))
val mpie = Bool() val pie = new Priv
val ube = Bool() val ie = new Priv
val spie = Bool()
val wpri2 = Bool()
val mie = Bool()
val wpri3 = Bool()
val sie = Bool()
val wpri4 = Bool()
} }
class Misa extends Bundle { class Misa extends Bundle {

View File

@ -124,11 +124,11 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti
io.executeStage.inst0.ex.exception(breakPoint) := inst_info(0).inst(31, 20) === privEbreak && io.executeStage.inst0.ex.exception(breakPoint) := inst_info(0).inst(31, 20) === privEbreak &&
inst_info(0).op === CSROpType.jmp inst_info(0).op === CSROpType.jmp
io.executeStage.inst0.ex.exception(ecallM) := inst_info(0).inst(31, 20) === privEcall && io.executeStage.inst0.ex.exception(ecallM) := inst_info(0).inst(31, 20) === privEcall &&
inst_info(0).op === CSROpType.jmp && priv_mode === ModeM inst_info(0).op === CSROpType.jmp && priv_mode === ModeM && inst_info(0).fusel === FuType.csr
io.executeStage.inst0.ex.exception(ecallS) := inst_info(0).inst(31, 20) === privEcall && io.executeStage.inst0.ex.exception(ecallS) := inst_info(0).inst(31, 20) === privEcall &&
inst_info(0).op === CSROpType.jmp && priv_mode === ModeS inst_info(0).op === CSROpType.jmp && priv_mode === ModeS && inst_info(0).fusel === FuType.csr
io.executeStage.inst0.ex.exception(ecallU) := inst_info(0).inst(31, 20) === privEcall && io.executeStage.inst0.ex.exception(ecallU) := inst_info(0).inst(31, 20) === privEcall &&
inst_info(0).op === CSROpType.jmp && priv_mode === ModeU inst_info(0).op === CSROpType.jmp && priv_mode === ModeU && inst_info(0).fusel === FuType.csr
io.executeStage.inst0.ex.tval := Mux( io.executeStage.inst0.ex.tval := Mux(
io.executeStage.inst0.ex.exception(instrAccessFault) || io.executeStage.inst0.ex.exception(instrAddrMisaligned), io.executeStage.inst0.ex.exception(instrAccessFault) || io.executeStage.inst0.ex.exception(instrAddrMisaligned),
io.instFifo.inst(0).pc, io.instFifo.inst(0).pc,
@ -162,11 +162,11 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti
io.executeStage.inst1.ex.exception(breakPoint) := inst_info(1).inst(31, 20) === privEbreak && io.executeStage.inst1.ex.exception(breakPoint) := inst_info(1).inst(31, 20) === privEbreak &&
inst_info(1).op === CSROpType.jmp inst_info(1).op === CSROpType.jmp
io.executeStage.inst1.ex.exception(ecallM) := inst_info(1).inst(31, 20) === privEcall && io.executeStage.inst1.ex.exception(ecallM) := inst_info(1).inst(31, 20) === privEcall &&
inst_info(1).op === CSROpType.jmp && priv_mode === ModeM inst_info(1).op === CSROpType.jmp && priv_mode === ModeM && inst_info(1).fusel === FuType.csr
io.executeStage.inst1.ex.exception(ecallS) := inst_info(1).inst(31, 20) === privEcall && io.executeStage.inst1.ex.exception(ecallS) := inst_info(1).inst(31, 20) === privEcall &&
inst_info(1).op === CSROpType.jmp && priv_mode === ModeS inst_info(1).op === CSROpType.jmp && priv_mode === ModeS && inst_info(1).fusel === FuType.csr
io.executeStage.inst1.ex.exception(ecallU) := inst_info(1).inst(31, 20) === privEcall && io.executeStage.inst1.ex.exception(ecallU) := inst_info(1).inst(31, 20) === privEcall &&
inst_info(1).op === CSROpType.jmp && priv_mode === ModeU inst_info(1).op === CSROpType.jmp && priv_mode === ModeU && inst_info(1).fusel === FuType.csr
io.executeStage.inst1.ex.tval := Mux( io.executeStage.inst1.ex.tval := Mux(
io.executeStage.inst1.ex.exception(instrAccessFault) || io.executeStage.inst1.ex.exception(instrAddrMisaligned), io.executeStage.inst1.ex.exception(instrAccessFault) || io.executeStage.inst1.ex.exception(instrAddrMisaligned),

View File

@ -14,6 +14,7 @@ class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle {
new Bundle { new Bundle {
val pc = UInt(PC_WID.W) val pc = UInt(PC_WID.W)
val ex = new ExceptionInfo() val ex = new ExceptionInfo()
val inst_info = new InstInfo()
} }
) )
}) })
@ -194,7 +195,7 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
val interrupt_enable = Wire(UInt(INT_WID.W)) // 不用考虑ideleg val interrupt_enable = Wire(UInt(INT_WID.W)) // 不用考虑ideleg
interrupt_enable := Fill( interrupt_enable := Fill(
INT_WID, INT_WID,
(((priv_mode === ModeM) && mstatus.asTypeOf(new Mstatus()).mie) || (priv_mode < ModeM)) (((priv_mode === ModeM) && mstatus.asTypeOf(new Mstatus()).ie.m) || (priv_mode < ModeM))
) )
io.decoderUnit.interrupt := mie(11, 0) & mip_has_interrupt.asUInt & interrupt_enable.asUInt io.decoderUnit.interrupt := mie(11, 0) & mip_has_interrupt.asUInt & interrupt_enable.asUInt
@ -202,8 +203,12 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
val exc_sel = val exc_sel =
(io.memoryUnit.in.inst(0).ex.exception.asUInt.orR || io.memoryUnit.in.inst(0).ex.interrupt.asUInt.orR) || (io.memoryUnit.in.inst(0).ex.exception.asUInt.orR || io.memoryUnit.in.inst(0).ex.interrupt.asUInt.orR) ||
!(io.memoryUnit.in.inst(1).ex.exception.asUInt.orR || io.memoryUnit.in.inst(1).ex.interrupt.asUInt.orR) !(io.memoryUnit.in.inst(1).ex.exception.asUInt.orR || io.memoryUnit.in.inst(1).ex.interrupt.asUInt.orR)
val pc = Mux(exc_sel, io.memoryUnit.in.inst(0).pc, io.memoryUnit.in.inst(1).pc) val mem_pc = Mux(exc_sel, io.memoryUnit.in.inst(0).pc, io.memoryUnit.in.inst(1).pc)
val exc = Mux(exc_sel, io.memoryUnit.in.inst(0).ex, io.memoryUnit.in.inst(1).ex) val mem_ex = Mux(exc_sel, io.memoryUnit.in.inst(0).ex, io.memoryUnit.in.inst(1).ex)
val mem_inst_info = Mux(exc_sel, io.memoryUnit.in.inst(0).inst_info, io.memoryUnit.in.inst(1).inst_info)
val mem_inst = mem_inst_info.inst
val mem_valid = mem_inst_info.valid
val mem_addr = mem_inst(31, 20)
val valid = io.executeUnit.in.valid val valid = io.executeUnit.in.valid
val op = io.executeUnit.in.inst_info.op val op = io.executeUnit.in.inst_info.op
val fusel = io.executeUnit.in.inst_info.fusel val fusel = io.executeUnit.in.inst_info.fusel
@ -244,18 +249,60 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
// CSR inst decode // CSR inst decode
val ret = Wire(Bool()) val ret = Wire(Bool())
val isMret = addr === privMret && op === CSROpType.jmp val isMret = mem_addr === privMret && op === CSROpType.jmp && mem_inst_info.fusel === FuType.csr && mem_valid
val isSret = addr === privSret && op === CSROpType.jmp val isSret = mem_addr === privSret && op === CSROpType.jmp && mem_inst_info.fusel === FuType.csr && mem_valid
val isUret = addr === privUret && op === CSROpType.jmp val isUret = mem_addr === privUret && op === CSROpType.jmp && mem_inst_info.fusel === FuType.csr && mem_valid
ret := isMret || isSret || isUret ret := isMret || isSret || isUret
val has_exception = mem_ex.exception.asUInt.orR
val has_interrupt = mem_ex.interrupt.asUInt.orR
val has_exc_int = has_exception || has_interrupt
val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(mem_ex.exception(i), i.U, sum))
val interruptNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(mem_ex.interrupt(i), i.U, sum))
val causeNO = (has_interrupt << (XLEN - 1)) | Mux(has_interrupt, interruptNO, exceptionNO)
val tval_wen = has_interrupt ||
!(mem_ex.exception(instrPageFault) ||
mem_ex.exception(loadPageFault) ||
mem_ex.exception(storePageFault) ||
mem_ex.exception(loadAddrMisaligned) ||
mem_ex.exception(storeAddrMisaligned))
when(has_exc_int) {
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
val mstatusNew = WireInit(mstatus.asTypeOf(new Mstatus))
mcause := causeNO
mepc := SignedExtend(mem_pc, XLEN)
mstatusNew.mpp := priv_mode
mstatusNew.pie.m := mstatusOld.ie.m
mstatusNew.ie.m := false.B
priv_mode := ModeM
when(tval_wen) { mtval := 0.U }
mstatus := mstatusNew.asUInt
}
val ret_target = Wire(UInt(VADDR_WID.W))
ret_target := DontCare
val trap_target = Wire(UInt(VADDR_WID.W))
trap_target := mtvec(VADDR_WID - 1, 0)
when(isMret) {
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
val mstatusNew = WireInit(mstatus.asTypeOf(new Mstatus))
// mstatusNew.mpp.m := ModeU //TODO: add mode U
mstatusNew.ie.m := mstatusOld.pie.m
priv_mode := mstatusOld.mpp
mstatusNew.pie.m := true.B
mstatusNew.mpp := ModeU
mstatus := mstatusNew.asUInt
// lr := false.B //TODO: add原子操作
ret_target := mepc(VADDR_WID - 1, 0)
}
io.decoderUnit.priv_mode := priv_mode
io.executeUnit.out.ex := io.executeUnit.in.ex io.executeUnit.out.ex := io.executeUnit.in.ex
io.executeUnit.out.ex.exception(illegalInstr) := (illegal_addr || illegal_access) && wen io.executeUnit.out.ex.exception(illegalInstr) := (illegal_addr || illegal_access) && wen
io.executeUnit.out.rdata := rdata io.executeUnit.out.rdata := rdata
io.memoryUnit.out.flush := has_exc_int || ret
io.decoderUnit.priv_mode := priv_mode io.memoryUnit.out.flush_pc := Mux(has_exc_int, trap_target, ret_target)
io.memoryUnit.out.flush := exc.exception.asUInt.orR || exc.interrupt.asUInt.orR
io.memoryUnit.out.flush_pc := mtvec
} }

View File

@ -72,8 +72,10 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
io.csr.in.inst(0).pc := io.writeBackStage.inst0.pc io.csr.in.inst(0).pc := io.writeBackStage.inst0.pc
io.csr.in.inst(0).ex := io.writeBackStage.inst0.ex io.csr.in.inst(0).ex := io.writeBackStage.inst0.ex
io.csr.in.inst(0).inst_info := io.writeBackStage.inst0.inst_info
io.csr.in.inst(1).pc := io.writeBackStage.inst1.pc io.csr.in.inst(1).pc := io.writeBackStage.inst1.pc
io.csr.in.inst(1).ex := io.writeBackStage.inst1.ex io.csr.in.inst(1).ex := io.writeBackStage.inst1.ex
io.csr.in.inst(1).inst_info := io.writeBackStage.inst1.inst_info
io.fetchUnit.flush := io.csr.out.flush io.fetchUnit.flush := io.csr.out.flush
io.fetchUnit.flush_pc := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U) io.fetchUnit.flush_pc := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U)