feat(csr): 增加exc、int和mret的信号处理
This commit is contained in:
parent
610323dec9
commit
a4247ae490
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue