完成实验大致框架
This commit is contained in:
parent
2bc97b8b86
commit
1e35953db9
|
@ -6,12 +6,6 @@ import cpu.defines._
|
|||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class ExceptionInfo extends Bundle {
|
||||
val exception = Vec(EXC_WID, Bool())
|
||||
val interrupt = Vec(INT_WID, Bool())
|
||||
val tval = Vec(EXC_WID, UInt(XLEN.W))
|
||||
}
|
||||
|
||||
class ExtInterrupt extends Bundle {
|
||||
val ei = Bool()
|
||||
val ti = Bool()
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
package cpu.defines
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines.Const._
|
||||
|
||||
class Mstatus extends Bundle {
|
||||
val sd = Output(Bool())
|
||||
|
||||
val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null
|
||||
val sxl = if (XLEN == 64) Output(UInt(2.W)) else null
|
||||
val uxl = if (XLEN == 64) Output(UInt(2.W)) else null
|
||||
val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W))
|
||||
|
||||
val tsr = Output(Bool())
|
||||
val tw = Output(Bool())
|
||||
val tvm = Output(Bool())
|
||||
val mxr = Output(Bool())
|
||||
val sum = Output(Bool())
|
||||
val mprv = Output(Bool())
|
||||
val xs = Output(UInt(2.W))
|
||||
val fs = Output(UInt(2.W))
|
||||
val mpp = Output(UInt(2.W))
|
||||
val hpp = Output(UInt(2.W))
|
||||
val spp = Output(Bool())
|
||||
val pie = new Priv
|
||||
val ie = new Priv
|
||||
}
|
||||
|
||||
class Misa extends Bundle {
|
||||
val mxl = UInt(2.W)
|
||||
val blank = UInt((XLEN - 28).W)
|
||||
val extensions = UInt(26.W)
|
||||
}
|
||||
|
||||
class Mtvec extends Bundle {
|
||||
val base = UInt((XLEN - 2).W)
|
||||
val mode = UInt(2.W)
|
||||
}
|
||||
|
||||
class Mcause extends Bundle {
|
||||
val interrupt = Bool()
|
||||
val excode = UInt((XLEN - 1).W)
|
||||
}
|
||||
|
||||
class Mip extends Bundle {
|
||||
val blank0 = UInt(52.W)
|
||||
val meip = Bool()
|
||||
val blank1 = UInt(2.W)
|
||||
val seip = Bool()
|
||||
val blank2 = UInt(2.W)
|
||||
val mtip = Bool()
|
||||
val blank3 = UInt(2.W)
|
||||
val stip = Bool()
|
||||
val blank4 = UInt(2.W)
|
||||
val msip = Bool()
|
||||
val blank5 = UInt(2.W)
|
||||
val ssip = Bool()
|
||||
val blank6 = UInt(2.W)
|
||||
}
|
||||
|
||||
class Mie extends Bundle {
|
||||
val blank0 = UInt(52.W)
|
||||
val meie = Bool()
|
||||
val blank1 = UInt(2.W)
|
||||
val seie = Bool()
|
||||
val blank2 = UInt(2.W)
|
||||
val mtie = Bool()
|
||||
val blank3 = UInt(2.W)
|
||||
val stie = Bool()
|
||||
val blank4 = UInt(2.W)
|
||||
val msie = Bool()
|
||||
val blank5 = UInt(2.W)
|
||||
val ssie = Bool()
|
||||
val blank6 = UInt(2.W)
|
||||
}
|
||||
|
||||
class Satp extends Bundle {
|
||||
val mode = UInt(4.W)
|
||||
val asid = UInt(16.W)
|
||||
val ppn = UInt(44.W)
|
||||
}
|
||||
|
||||
class Priv extends Bundle {
|
||||
val m = Output(Bool())
|
||||
val h = Output(Bool())
|
||||
val s = Output(Bool())
|
||||
val u = Output(Bool())
|
||||
}
|
||||
|
||||
class Interrupt extends Bundle {
|
||||
val e = new Priv()
|
||||
val t = new Priv()
|
||||
val s = new Priv()
|
||||
}
|
||||
|
||||
object Priv {
|
||||
def u = "b00".U
|
||||
def s = "b01".U
|
||||
def h = "b10".U
|
||||
def m = "b11".U
|
||||
def apply() = UInt(2.W)
|
||||
}
|
|
@ -3,30 +3,6 @@ package cpu.defines
|
|||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
object HasExcInt {
|
||||
def apply(ex: ExceptionInfo) = {
|
||||
ex.exception.asUInt.orR || ex.interrupt.asUInt.orR
|
||||
}
|
||||
}
|
||||
|
||||
object IsMret {
|
||||
def apply(info: Info) = {
|
||||
info.fusel === FuType.csr && info.op === CSROpType.mret
|
||||
}
|
||||
}
|
||||
|
||||
object IsSret {
|
||||
def apply(info: Info) = {
|
||||
info.fusel === FuType.csr && info.op === CSROpType.sret
|
||||
}
|
||||
}
|
||||
|
||||
object HasRet {
|
||||
def apply(info: Info) = {
|
||||
IsMret(info) || IsSret(info)
|
||||
}
|
||||
}
|
||||
|
||||
object SignedExtend {
|
||||
def apply(a: UInt, len: Int) = {
|
||||
val aLen = a.getWidth
|
||||
|
|
|
@ -158,148 +158,3 @@ object CSROpType {
|
|||
|
||||
def isCSROp(op: UInt) = !op(3)
|
||||
}
|
||||
|
||||
trait HasCSRConst {
|
||||
// User Trap Setup
|
||||
val Ustatus = 0x000
|
||||
val Uie = 0x004
|
||||
val Utvec = 0x005
|
||||
|
||||
// User Trap Handling
|
||||
val Uscratch = 0x040
|
||||
val Uepc = 0x041
|
||||
val Ucause = 0x042
|
||||
val Utval = 0x043
|
||||
val Uip = 0x044
|
||||
|
||||
// User Floating-Point CSRs (not implemented)
|
||||
val Fflags = 0x001
|
||||
val Frm = 0x002
|
||||
val Fcsr = 0x003
|
||||
|
||||
// User Counter/Timers
|
||||
val Cycle = 0xc00
|
||||
val Time = 0xc01
|
||||
val Instret = 0xc02
|
||||
|
||||
// Supervisor Trap Setup
|
||||
val Sstatus = 0x100
|
||||
val Sedeleg = 0x102
|
||||
val Sideleg = 0x103
|
||||
val Sie = 0x104
|
||||
val Stvec = 0x105
|
||||
val Scounteren = 0x106
|
||||
|
||||
// Supervisor Trap Handling
|
||||
val Sscratch = 0x140
|
||||
val Sepc = 0x141
|
||||
val Scause = 0x142
|
||||
val Stval = 0x143
|
||||
val Sip = 0x144
|
||||
|
||||
// Supervisor Protection and Translation
|
||||
val Satp = 0x180
|
||||
|
||||
// Machine Information Registers
|
||||
val Mvendorid = 0xf11
|
||||
val Marchid = 0xf12
|
||||
val Mimpid = 0xf13
|
||||
val Mhartid = 0xf14
|
||||
|
||||
// Machine Trap Setup
|
||||
val Mstatus = 0x300
|
||||
val Misa = 0x301
|
||||
val Medeleg = 0x302
|
||||
val Mideleg = 0x303
|
||||
val Mie = 0x304
|
||||
val Mtvec = 0x305
|
||||
val Mcounteren = 0x306
|
||||
|
||||
// Machine Trap Handling
|
||||
val Mscratch = 0x340
|
||||
val Mepc = 0x341
|
||||
val Mcause = 0x342
|
||||
val Mtval = 0x343
|
||||
val Mip = 0x344
|
||||
|
||||
// Machine Memory Protection
|
||||
// TBD
|
||||
val Pmpcfg0 = 0x3a0
|
||||
val Pmpcfg1 = 0x3a1
|
||||
val Pmpcfg2 = 0x3a2
|
||||
val Pmpcfg3 = 0x3a3
|
||||
val PmpaddrBase = 0x3b0
|
||||
|
||||
// Machine Counter/Timers
|
||||
// Currently, NutCore uses perfcnt csr set instead of standard Machine Counter/Timers
|
||||
// 0xB80 - 0x89F are also used as perfcnt csr
|
||||
|
||||
// Machine Counter Setup (not implemented)
|
||||
// Debug/Trace Registers (shared with Debug Mode) (simply implemented)
|
||||
val Tselect = 0x7a0
|
||||
val Tdata1 = 0x7a1
|
||||
// Debug Mode Registers (not implemented)
|
||||
|
||||
def ModeM = 0x3.U
|
||||
def ModeH = 0x2.U
|
||||
def ModeS = 0x1.U
|
||||
def ModeU = 0x0.U
|
||||
|
||||
def IRQ_UEIP = 0
|
||||
def IRQ_SEIP = 1
|
||||
def IRQ_MEIP = 3
|
||||
|
||||
def IRQ_UTIP = 4
|
||||
def IRQ_STIP = 5
|
||||
def IRQ_MTIP = 7
|
||||
|
||||
def IRQ_USIP = 8
|
||||
def IRQ_SSIP = 9
|
||||
def IRQ_MSIP = 11
|
||||
|
||||
val IntPriority = Seq(
|
||||
IRQ_MEIP,
|
||||
IRQ_MSIP,
|
||||
IRQ_MTIP,
|
||||
IRQ_SEIP,
|
||||
IRQ_SSIP,
|
||||
IRQ_STIP,
|
||||
IRQ_UEIP,
|
||||
IRQ_USIP,
|
||||
IRQ_UTIP
|
||||
)
|
||||
}
|
||||
|
||||
trait HasExceptionNO {
|
||||
def instAddrMisaligned = 0
|
||||
def instAccessFault = 1
|
||||
def illegalInst = 2
|
||||
def breakPoint = 3
|
||||
def loadAddrMisaligned = 4
|
||||
def loadAccessFault = 5
|
||||
def storeAddrMisaligned = 6
|
||||
def storeAccessFault = 7
|
||||
def ecallU = 8
|
||||
def ecallS = 9
|
||||
def ecallM = 11
|
||||
def instPageFault = 12
|
||||
def loadPageFault = 13
|
||||
def storePageFault = 15
|
||||
|
||||
val ExcPriority = Seq(
|
||||
breakPoint, // TODO: different BP has different priority
|
||||
instPageFault,
|
||||
instAccessFault,
|
||||
illegalInst,
|
||||
instAddrMisaligned,
|
||||
ecallM,
|
||||
ecallS,
|
||||
ecallU,
|
||||
storeAddrMisaligned,
|
||||
loadAddrMisaligned,
|
||||
storePageFault,
|
||||
loadPageFault,
|
||||
storeAccessFault,
|
||||
loadAccessFault
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ class DataForwardToDecodeUnit extends Bundle {
|
|||
val mem = new RegWrite()
|
||||
}
|
||||
|
||||
class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
|
||||
class DecodeUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = new DecodeUnitCtrl()
|
||||
// 输入
|
||||
|
@ -58,5 +58,4 @@ class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
|
|||
forwardCtrl.out.data.src2.rdata,
|
||||
info.imm
|
||||
)
|
||||
io.executeStage.data.ex := DontCare // TODO: 未实现
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import chisel3.util._
|
|||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
|
||||
class Decoder extends Module with HasInstrType with HasCSRConst {
|
||||
class Decoder extends Module with HasInstrType {
|
||||
val io = IO(new Bundle {
|
||||
// inputs
|
||||
val in = Input(new Bundle {
|
||||
|
|
|
@ -10,7 +10,6 @@ class IdExeData extends Bundle {
|
|||
val pc = UInt(XLEN.W)
|
||||
val info = new Info()
|
||||
val src_info = new SrcInfo()
|
||||
val ex = new ExceptionInfo()
|
||||
}
|
||||
|
||||
class DecodeUnitExecuteUnit extends Bundle {
|
||||
|
|
|
@ -33,7 +33,6 @@ class ExecuteUnit extends Module {
|
|||
fu.data.pc := io.executeStage.data.pc
|
||||
fu.data.info := io.executeStage.data.info
|
||||
fu.data.src_info := io.executeStage.data.src_info
|
||||
fu.data.ex := io.executeStage.data.ex
|
||||
|
||||
io.dataSram <> fu.dataSram
|
||||
|
||||
|
@ -46,7 +45,6 @@ class ExecuteUnit extends Module {
|
|||
io.memoryStage.data.info := io.executeStage.data.info
|
||||
io.memoryStage.data.src_info := io.executeStage.data.src_info
|
||||
io.memoryStage.data.rd_info := fu.data.rd_info
|
||||
io.memoryStage.data.has_exception := fu.data.has_exception
|
||||
|
||||
// 数据前递
|
||||
io.decodeUnit.forward.exe.wen := io.memoryStage.data.info.reg_wen
|
||||
|
|
|
@ -13,8 +13,6 @@ class Fu extends Module {
|
|||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val rd_info = Output(new RdInfo())
|
||||
val ex = Input(new ExceptionInfo())
|
||||
val has_exception = Output(Bool())
|
||||
}
|
||||
|
||||
val dataSram = new DataSram()
|
||||
|
@ -47,7 +45,6 @@ class Fu extends Module {
|
|||
io.data.rd_info.wdata(FuType.alu) := alu.result
|
||||
io.data.rd_info.wdata(FuType.bru) := io.data.pc + 4.U
|
||||
io.data.rd_info.wdata(FuType.mdu) := mdu.result
|
||||
io.data.has_exception := HasExcInt(io.data.ex) // TODO: add exception handling
|
||||
|
||||
io.ctrl.flush := bru.out.branch
|
||||
io.ctrl.target := bru.out.target
|
||||
|
|
|
@ -1,413 +0,0 @@
|
|||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class CsrMemoryUnit(implicit val cpuConfig: CpuConfig) extends Bundle {
|
||||
val in = Input(new Bundle {
|
||||
val pc = UInt(XLEN.W)
|
||||
val ex = new ExceptionInfo()
|
||||
val info = new Info()
|
||||
|
||||
val lr_wen = Bool()
|
||||
val lr_wbit = Bool()
|
||||
val lr_waddr = UInt(XLEN.W)
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val flush = Bool()
|
||||
val target = UInt(XLEN.W)
|
||||
|
||||
val lr = Bool()
|
||||
val lr_addr = UInt(XLEN.W)
|
||||
})
|
||||
}
|
||||
|
||||
class CsrExecuteUnit(implicit val cpuConfig: CpuConfig) extends Bundle {
|
||||
val in = Input(new Bundle {
|
||||
val valid = Bool()
|
||||
val pc = UInt(XLEN.W)
|
||||
val info = new Info()
|
||||
val src_info = new SrcInfo()
|
||||
val ex = new ExceptionInfo()
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val rdata = UInt(XLEN.W)
|
||||
val ex = new ExceptionInfo()
|
||||
val flush = Bool()
|
||||
val target = UInt(XLEN.W)
|
||||
})
|
||||
}
|
||||
|
||||
class CsrDecodeUnit extends Bundle {
|
||||
val mode = Output(Priv())
|
||||
val interrupt = Output(UInt(INT_WID.W))
|
||||
}
|
||||
|
||||
class CsrTlb extends Bundle {
|
||||
val satp = Output(UInt(XLEN.W))
|
||||
val mstatus = Output(UInt(XLEN.W))
|
||||
val imode = Output(Priv())
|
||||
val dmode = Output(Priv())
|
||||
}
|
||||
|
||||
class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst {
|
||||
val io = IO(new Bundle {
|
||||
val ext_int = Input(new ExtInterrupt())
|
||||
val decodeUnit = new CsrDecodeUnit()
|
||||
val executeUnit = new CsrExecuteUnit()
|
||||
val memoryUnit = new CsrMemoryUnit()
|
||||
val tlb = new CsrTlb()
|
||||
})
|
||||
|
||||
// 目前的csr只支持64位
|
||||
require(XLEN == 64, "XLEN must be 64")
|
||||
|
||||
/* CSR寄存器定义 */
|
||||
// Machine Information Registers
|
||||
val mvendorid = RegInit(UInt(XLEN.W), 0.U) // 厂商ID
|
||||
val marchid = RegInit(UInt(XLEN.W), 0.U) // 架构ID
|
||||
val mimpid = RegInit(UInt(XLEN.W), 0.U) // 实现ID
|
||||
val mhartid = RegInit(UInt(XLEN.W), 0.U) // 硬件线程ID
|
||||
|
||||
// Machine Trap Setup
|
||||
val mstatus_init = Wire(new Mstatus())
|
||||
mstatus_init := 0.U.asTypeOf(new Mstatus())
|
||||
mstatus_init.sxl := 2.U
|
||||
mstatus_init.uxl := 2.U
|
||||
val mstatus = RegInit(UInt(XLEN.W), mstatus_init.asUInt) // 状态寄存器
|
||||
val misa_init = Wire(new Misa())
|
||||
misa_init := 0.U.asTypeOf(new Misa())
|
||||
misa_init.mxl := 2.U
|
||||
def getMisaExt(ext: Char): UInt = { 1.U << (ext.toInt - 'a'.toInt) }
|
||||
var extensions = List('i')
|
||||
if (cpuConfig.hasMExtension) { extensions = extensions :+ 'm' }
|
||||
if (cpuConfig.hasAExtension) { extensions = extensions :+ 'a' }
|
||||
if (cpuConfig.hasSMode) { extensions = extensions :+ 's' }
|
||||
if (cpuConfig.hasUMode) { extensions = extensions :+ 'u' }
|
||||
misa_init.extensions := extensions.foldLeft(0.U)((sum, i) => sum | getMisaExt(i))
|
||||
val misa = RegInit(UInt(XLEN.W), misa_init.asUInt) // ISA寄存器
|
||||
val medeleg = RegInit(UInt(XLEN.W), 0.U) // 异常代理寄存器
|
||||
val mideleg = RegInit(UInt(XLEN.W), 0.U) // 中断代理寄存器
|
||||
val mie = RegInit(UInt(XLEN.W), 0.U) // 中断使能寄存器
|
||||
val mtvec = RegInit(UInt(XLEN.W), 0.U) // 中断向量基址寄存器
|
||||
val mcounteren = RegInit(UInt(XLEN.W), 0.U) // 计数器使能寄存器
|
||||
|
||||
// Machine Trap Handling
|
||||
val mscratch = RegInit(UInt(XLEN.W), 0.U) // 临时寄存器
|
||||
val mepc = RegInit(UInt(XLEN.W), 0.U) // 异常程序计数器
|
||||
val mcause = RegInit(UInt(XLEN.W), 0.U) // 异常原因寄存器
|
||||
val mtval = RegInit(UInt(XLEN.W), 0.U) // 异常值寄存器
|
||||
val mipWire = WireInit(0.U.asTypeOf(new Interrupt))
|
||||
val mipReg = RegInit(UInt(XLEN.W), 0.U)
|
||||
val mipFixMask = "hAAA".U(64.W)
|
||||
val mip = mipWire.asUInt | mipReg // 中断挂起寄存器
|
||||
|
||||
// Machine Memory Protection
|
||||
val pmpcfg0 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpcfg1 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpcfg2 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpcfg3 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpaddr0 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpaddr1 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpaddr2 = RegInit(UInt(XLEN.W), 0.U)
|
||||
val pmpaddr3 = RegInit(UInt(XLEN.W), 0.U)
|
||||
|
||||
val pmpaddrWmask = "h3fffffff".U(64.W) // 32bit physical address
|
||||
|
||||
// Machine Counter/Timers
|
||||
val mcycle = RegInit(UInt(XLEN.W), 0.U) // 时钟周期计数器
|
||||
mcycle := mcycle + 1.U
|
||||
val minstret = RegInit(UInt(XLEN.W), 0.U) // 指令计数器
|
||||
|
||||
// Supervisor Trap Setup
|
||||
// sstatus 状态寄存器,源自mstatus
|
||||
val sstatusWmask = "h00000000000c0122".U(XLEN.W)
|
||||
val sstatusRmask = "h80000003000de762".U(XLEN.W)
|
||||
// sedeleg 异常代理寄存器,未实现
|
||||
// sideleg 中断代理寄存器,未实现
|
||||
// sie 中断使能寄存器,源自mie
|
||||
val sieMask = "h222".U(64.W) & mideleg
|
||||
val stvec = RegInit(UInt(XLEN.W), 0.U) // 中断向量基址寄存器
|
||||
val scounteren = RegInit(UInt(XLEN.W), 0.U) // 计数器使能寄存器
|
||||
|
||||
// Supervisor Trap Handling
|
||||
val sscratch = RegInit(UInt(XLEN.W), 0.U) // 临时寄存器
|
||||
val sepc = RegInit(UInt(XLEN.W), 0.U) // 异常程序计数器
|
||||
val scause = RegInit(UInt(XLEN.W), 0.U) // 异常原因寄存器
|
||||
val stval = RegInit(UInt(XLEN.W), 0.U) // 异常值寄存器
|
||||
// sip 中断挂起寄存器,源自mip
|
||||
val sipMask = "h222".U(64.W) & mideleg
|
||||
|
||||
// Supervisor Protection and Translation
|
||||
val satp = RegInit(UInt(XLEN.W), 0.U) // 页表基址寄存器
|
||||
|
||||
// Debug/Trace Registers (shared with Debug Mode)
|
||||
val tselect = RegInit(1.U(XLEN.W)) // 跟踪寄存器选择寄存器
|
||||
val tdata1 = RegInit(UInt(XLEN.W), 0.U) // 跟踪寄存器数据1寄存器
|
||||
|
||||
val rdata = Wire(UInt(XLEN.W))
|
||||
val wdata = Wire(UInt(XLEN.W))
|
||||
|
||||
// Atom LR/SC Control Bits
|
||||
val lr_wen = io.memoryUnit.in.lr_wen
|
||||
val lr_wbit = io.memoryUnit.in.lr_wbit
|
||||
val lr_waddr = io.memoryUnit.in.lr_waddr
|
||||
val lr = RegInit(Bool(), false.B)
|
||||
val lr_addr = RegInit(UInt(XLEN.W), 0.U)
|
||||
|
||||
io.memoryUnit.out.lr := lr
|
||||
io.memoryUnit.out.lr_addr := lr_addr
|
||||
|
||||
when(lr_wen) {
|
||||
lr := lr_wbit
|
||||
lr_addr := lr_waddr
|
||||
}
|
||||
|
||||
// Side Effect
|
||||
def mstatusUpdateSideEffect(mstatus: UInt): UInt = {
|
||||
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
val mstatusNew = Cat(mstatusOld.fs === "b11".U, mstatus(XLEN - 2, 0))
|
||||
mstatusNew
|
||||
}
|
||||
|
||||
val mstatus_wmask = Mux(
|
||||
VecInit(ModeM, ModeS, ModeU).contains(wdata.asTypeOf(new Mstatus).mpp),
|
||||
"h00000000007e19aa".U(64.W),
|
||||
"h00000000007e01aa".U(64.W)
|
||||
)
|
||||
|
||||
// CSR reg map
|
||||
val mapping = Map(
|
||||
// User Counter/Timers
|
||||
MaskedRegMap(Cycle, mcycle),
|
||||
// Supervisor Trap Setup
|
||||
MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask),
|
||||
MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask),
|
||||
MaskedRegMap(Stvec, stvec),
|
||||
MaskedRegMap(Scounteren, scounteren),
|
||||
// Supervisor Trap Handling
|
||||
MaskedRegMap(Sscratch, sscratch),
|
||||
MaskedRegMap(Sepc, sepc),
|
||||
MaskedRegMap(Scause, scause),
|
||||
MaskedRegMap(Stval, stval),
|
||||
MaskedRegMap(Sip, mip, sipMask, MaskedRegMap.Unwritable, sipMask),
|
||||
// Supervisor Protection and Translation
|
||||
MaskedRegMap(Satp, satp),
|
||||
// Machine Information Registers
|
||||
MaskedRegMap(Mvendorid, mvendorid, 0.U, MaskedRegMap.Unwritable),
|
||||
MaskedRegMap(Marchid, marchid, 0.U, MaskedRegMap.Unwritable),
|
||||
MaskedRegMap(Mimpid, mimpid, 0.U, MaskedRegMap.Unwritable),
|
||||
MaskedRegMap(Mhartid, mhartid, 0.U, MaskedRegMap.Unwritable),
|
||||
// Machine Trap Setup
|
||||
MaskedRegMap(Mstatus, mstatus, mstatus_wmask),
|
||||
MaskedRegMap(Misa, misa, 0.U, MaskedRegMap.Unwritable), // MXL,EXT目前不支持可变
|
||||
MaskedRegMap(Medeleg, medeleg, "hbbff".U(XLEN.W)),
|
||||
MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)),
|
||||
MaskedRegMap(Mie, mie),
|
||||
MaskedRegMap(Mtvec, mtvec),
|
||||
MaskedRegMap(Mcounteren, mcounteren),
|
||||
// Machine Trap Handling
|
||||
MaskedRegMap(Mscratch, mscratch),
|
||||
MaskedRegMap(Mepc, mepc),
|
||||
MaskedRegMap(Mcause, mcause),
|
||||
MaskedRegMap(Mtval, mtval),
|
||||
MaskedRegMap(Mip, mip, 0.U, MaskedRegMap.Unwritable),
|
||||
// Machine Memory Protection
|
||||
// MaskedRegMap(Pmpcfg0, pmpcfg0),
|
||||
// MaskedRegMap(Pmpcfg1, pmpcfg1),
|
||||
// MaskedRegMap(Pmpcfg2, pmpcfg2),
|
||||
// MaskedRegMap(Pmpcfg3, pmpcfg3),
|
||||
// MaskedRegMap(PmpaddrBase + 0, pmpaddr0, pmpaddrWmask),
|
||||
// MaskedRegMap(PmpaddrBase + 1, pmpaddr1, pmpaddrWmask),
|
||||
// MaskedRegMap(PmpaddrBase + 2, pmpaddr2, pmpaddrWmask),
|
||||
// MaskedRegMap(PmpaddrBase + 3, pmpaddr3, pmpaddrWmask)
|
||||
|
||||
// Debug/Trace Registers (shared with Debug Mode)
|
||||
MaskedRegMap(Tselect, tselect, 0.U, MaskedRegMap.Unwritable), // 用于通过 risc-v test
|
||||
MaskedRegMap(Tdata1, tdata1, 0.U, MaskedRegMap.Unwritable)
|
||||
)
|
||||
|
||||
val mode = RegInit(Priv.m) // 当前特权模式
|
||||
|
||||
// interrupts
|
||||
val mtip = io.ext_int.ti
|
||||
val meip = io.ext_int.ei
|
||||
val msip = io.ext_int.si
|
||||
mipWire.t.m := mtip
|
||||
mipWire.e.m := meip
|
||||
mipWire.s.m := msip
|
||||
val seip = meip
|
||||
val mip_raise_interrupt = WireInit(mip.asTypeOf(new Interrupt()))
|
||||
mip_raise_interrupt.e.s := mip.asTypeOf(new Interrupt).e.s | seip
|
||||
|
||||
val mstatusBundle = mstatus.asTypeOf(new Mstatus())
|
||||
|
||||
val ideleg = (mideleg & mip_raise_interrupt.asUInt)
|
||||
def priviledgedEnableDetect(x: Bool): Bool = Mux(
|
||||
x,
|
||||
((mode === ModeS) && mstatusBundle.ie.s) || (mode < ModeS),
|
||||
((mode === ModeM) && mstatusBundle.ie.m) || (mode < ModeM)
|
||||
)
|
||||
|
||||
val interrupt_enable = Wire(Vec(INT_WID, Bool()))
|
||||
interrupt_enable.zip(ideleg.asBools).map { case (x, y) => x := priviledgedEnableDetect(y) }
|
||||
io.decodeUnit.interrupt := mie(INT_WID - 1, 0) & mip_raise_interrupt.asUInt & interrupt_enable.asUInt
|
||||
|
||||
// 优先使用inst0的信息
|
||||
val mem_pc = io.memoryUnit.in.pc
|
||||
val mem_ex = io.memoryUnit.in.ex
|
||||
val mem_inst_info = io.memoryUnit.in.info
|
||||
val mem_inst = mem_inst_info.inst
|
||||
val mem_valid = mem_inst_info.valid
|
||||
val mem_addr = mem_inst(31, 20)
|
||||
|
||||
val raise_exception = mem_ex.exception.asUInt.orR && mem_valid
|
||||
val raise_interrupt = mem_ex.interrupt.asUInt.orR && mem_valid
|
||||
val raise_exc_int = raise_exception || raise_interrupt
|
||||
// 不带前缀的信号为exe阶段的信号
|
||||
val valid = io.executeUnit.in.valid && !io.memoryUnit.out.flush // mem发生flush时,清刷掉exe的信号
|
||||
val info = io.executeUnit.in.info
|
||||
val op = io.executeUnit.in.info.op
|
||||
val fusel = io.executeUnit.in.info.fusel
|
||||
val addr = io.executeUnit.in.info.inst(31, 20)
|
||||
val src1 = io.executeUnit.in.src_info.src1_data
|
||||
val csri = ZeroExtend(io.executeUnit.in.info.inst(19, 15), XLEN)
|
||||
wdata := LookupTree(
|
||||
op,
|
||||
List(
|
||||
CSROpType.csrrw -> src1,
|
||||
CSROpType.csrrs -> (rdata | src1),
|
||||
CSROpType.csrrc -> (rdata & ~src1),
|
||||
CSROpType.csrrwi -> csri,
|
||||
CSROpType.csrrsi -> (rdata | csri),
|
||||
CSROpType.csrrci -> (rdata & ~csri)
|
||||
)
|
||||
)
|
||||
|
||||
val satp_legal = (wdata.asTypeOf(new Satp()).mode === 0.U) || (wdata.asTypeOf(new Satp()).mode === 8.U)
|
||||
val write = (valid && CSROpType.isCSROp(op)) && (addr =/= Satp.U || satp_legal)
|
||||
val only_read =
|
||||
VecInit(CSROpType.csrrs, CSROpType.csrrsi, CSROpType.csrrc, CSROpType.csrrci).contains(op) && src1 === 0.U
|
||||
val illegal_mode = mode < addr(9, 8)
|
||||
val illegal_write = write && (addr(11, 10) === "b11".U) && !only_read
|
||||
val illegal_access = illegal_mode || illegal_write
|
||||
val wen = write && !illegal_access
|
||||
|
||||
MaskedRegMap.generate(mapping, addr, rdata, wen, wdata)
|
||||
val illegal_addr = MaskedRegMap.isIllegalAddr(mapping, addr)
|
||||
val write_satp = (addr === Satp.U) && write
|
||||
val ipMapping = Map(
|
||||
MaskedRegMap(Mip, mipReg, mipFixMask),
|
||||
MaskedRegMap(Sip, mipReg, sipMask, MaskedRegMap.NoSideEffect, sipMask)
|
||||
)
|
||||
val rdataDummy = Wire(UInt(XLEN.W))
|
||||
MaskedRegMap.generate(ipMapping, addr, rdataDummy, wen, wdata)
|
||||
|
||||
// CSR inst decode
|
||||
val ret = Wire(Bool())
|
||||
val isMret = IsMret(mem_inst_info) && mem_valid
|
||||
val isSret = IsSret(mem_inst_info) && mem_valid
|
||||
ret := isMret || isSret
|
||||
|
||||
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 = (raise_interrupt << (XLEN - 1)) | Mux(raise_interrupt, interruptNO, exceptionNO)
|
||||
|
||||
val deleg = Mux(raise_interrupt, mideleg, medeleg)
|
||||
val delegS = (deleg(causeNO(log2Ceil(EXC_WID) - 1, 0))) && (mode < ModeM)
|
||||
|
||||
val tval_wen = raise_interrupt ||
|
||||
!raise_exception
|
||||
|
||||
when(raise_exception) {
|
||||
val tval = mem_ex.tval(exceptionNO)
|
||||
when(delegS) {
|
||||
stval := tval
|
||||
}.otherwise {
|
||||
mtval := tval
|
||||
}
|
||||
}
|
||||
|
||||
when(raise_exc_int) {
|
||||
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
val mstatusNew = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
|
||||
when(delegS) {
|
||||
scause := causeNO
|
||||
sepc := SignedExtend(mem_pc, XLEN)
|
||||
mstatusNew.spp := mode
|
||||
mstatusNew.pie.s := mstatusOld.ie.s
|
||||
mstatusNew.ie.s := false.B
|
||||
mode := ModeS
|
||||
when(tval_wen) { stval := 0.U }
|
||||
}.otherwise {
|
||||
mcause := causeNO
|
||||
mepc := SignedExtend(mem_pc, XLEN)
|
||||
mstatusNew.mpp := mode
|
||||
mstatusNew.pie.m := mstatusOld.ie.m
|
||||
mstatusNew.ie.m := false.B
|
||||
mode := ModeM
|
||||
when(tval_wen) { mtval := 0.U }
|
||||
}
|
||||
mstatus := mstatusNew.asUInt
|
||||
}
|
||||
|
||||
val ret_target = Wire(UInt(XLEN.W))
|
||||
ret_target := DontCare
|
||||
|
||||
val trap_target = Wire(UInt(XLEN.W))
|
||||
val tvec = Mux(delegS, stvec, mtvec)
|
||||
trap_target := (tvec(XLEN - 1, 2) << 2) + Mux(
|
||||
tvec(0) && raise_interrupt,
|
||||
(causeNO << 2),
|
||||
0.U
|
||||
)
|
||||
|
||||
when(isMret) {
|
||||
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
val mstatusNew = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
when(mstatusOld.mpp =/= ModeM) {
|
||||
mstatusNew.mprv := false.B
|
||||
}
|
||||
mstatusNew.ie.m := mstatusOld.pie.m
|
||||
mode := mstatusOld.mpp
|
||||
mstatusNew.pie.m := true.B
|
||||
mstatusNew.mpp := ModeU
|
||||
mstatus := mstatusNew.asUInt
|
||||
lr := false.B
|
||||
ret_target := mepc
|
||||
}
|
||||
|
||||
when(isSret) {
|
||||
val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
val mstatusNew = WireInit(mstatus.asTypeOf(new Mstatus))
|
||||
when(mstatusOld.spp =/= ModeM) {
|
||||
mstatusNew.mprv := false.B
|
||||
}
|
||||
mstatusNew.ie.s := mstatusOld.pie.s
|
||||
mode := Cat(0.U(1.W), mstatusOld.spp)
|
||||
mstatusNew.pie.s := true.B
|
||||
mstatusNew.spp := ModeU
|
||||
mstatus := mstatusNew.asUInt
|
||||
lr := false.B
|
||||
ret_target := sepc
|
||||
}
|
||||
|
||||
io.tlb.imode := mode
|
||||
io.tlb.dmode := Mux(mstatusBundle.mprv, mstatusBundle.mpp, mode)
|
||||
io.tlb.satp := satp
|
||||
io.tlb.mstatus := mstatus
|
||||
io.decodeUnit.mode := mode
|
||||
io.executeUnit.out.ex := io.executeUnit.in.ex
|
||||
io.executeUnit.out.ex.exception(illegalInst) :=
|
||||
(illegal_addr || illegal_access) && write | io.executeUnit.in.ex.exception(illegalInst)
|
||||
io.executeUnit.out.ex.tval(illegalInst) := io.executeUnit.in.info.inst
|
||||
io.executeUnit.out.rdata := rdata
|
||||
io.executeUnit.out.flush := write_satp
|
||||
io.executeUnit.out.target := io.executeUnit.in.pc + 4.U
|
||||
io.memoryUnit.out.flush := raise_exc_int || ret
|
||||
io.memoryUnit.out.target := Mux(raise_exc_int, trap_target, ret_target)
|
||||
}
|
|
@ -11,7 +11,6 @@ class ExeMemData extends Bundle {
|
|||
val info = new Info()
|
||||
val rd_info = new RdInfo()
|
||||
val src_info = new SrcInfo()
|
||||
val has_exception = Bool()
|
||||
}
|
||||
|
||||
class ExecuteUnitMemoryUnit extends Bundle {
|
||||
|
|
|
@ -10,7 +10,6 @@ class MemWbData extends Bundle {
|
|||
val pc = UInt(XLEN.W)
|
||||
val info = new Info()
|
||||
val rd_info = new RdInfo()
|
||||
val has_exception = Bool()
|
||||
}
|
||||
|
||||
class MemoryUnitWriteBackUnit extends Bundle {
|
||||
|
|
|
@ -17,8 +17,7 @@ class WriteBackUnit extends Module {
|
|||
io.regfile.wen :=
|
||||
io.writeBackStage.data.info.valid &&
|
||||
io.ctrl.ctrlSignal.allow_to_go &&
|
||||
io.writeBackStage.data.info.reg_wen &&
|
||||
!io.writeBackStage.data.has_exception
|
||||
io.writeBackStage.data.info.reg_wen
|
||||
|
||||
io.regfile.waddr := io.writeBackStage.data.info.reg_waddr
|
||||
io.regfile.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel)
|
||||
|
|
2
difftest
2
difftest
|
@ -1 +1 @@
|
|||
Subproject commit 2d18d26d5c5f4f920184318462589b96ab4e1504
|
||||
Subproject commit e5cf2ffe5854c0ba3cd50fd5e09dc67955d13e9c
|
Loading…
Reference in New Issue