diff --git a/src/main/scala/rvspeccore/checker/Checker.scala b/src/main/scala/rvspeccore/checker/Checker.scala index f8118d5..0a95fb7 100644 --- a/src/main/scala/rvspeccore/checker/Checker.scala +++ b/src/main/scala/rvspeccore/checker/Checker.scala @@ -63,6 +63,7 @@ class CheckerWithResult(checkMem: Boolean = true)(implicit config: RVConfig) ext val dtlbmem = if (checkMem) Some(Input(new TLBSig)) else None val itlbmem = if (checkMem) Some(Input(new TLBSig)) else None }) + // TODO: io.result has .internal states now, consider use it or not // link to spec core val specCore = Module(new RiscvCore) diff --git a/src/main/scala/rvspeccore/core/RiscvCore.scala b/src/main/scala/rvspeccore/core/RiscvCore.scala index 9df8a45..bdb0c2a 100644 --- a/src/main/scala/rvspeccore/core/RiscvCore.scala +++ b/src/main/scala/rvspeccore/core/RiscvCore.scala @@ -29,10 +29,9 @@ abstract class BaseCore()(implicit config: RVConfig) extends Module { val mem = Wire(new MemIO) val tlb = Wire(new TLBIO) // Global Data - val global_data = Wire(new GlobalData) // TODO: GlobalData only has setpc? event, iFetchpc? - val privilegeMode = RegInit(UInt(2.W), 0x3.U) - val event = Wire(new EventSig) - val iFetchpc = Wire(UInt(XLEN.W)) + val global_data = Wire(new GlobalData) // TODO: GlobalData only has setpc? event, iFetchpc? + val event = Wire(new EventSig) + val iFetchpc = Wire(UInt(XLEN.W)) } class GlobalData extends Bundle { val setpc = Bool() @@ -61,19 +60,37 @@ class TLBIO()(implicit XLEN: Int) extends Bundle { val Anotherwrite = Vec(3, new WriteMemIO()) } +class Internal() extends Bundle { + val privilegeMode = UInt(2.W) +} +object Internal { + def apply(): Internal = new Internal + def wireInit(): Internal = { + val internal = Wire(new Internal) + internal.privilegeMode := 0x3.U + internal + } +} + class State()(implicit XLEN: Int, config: RVConfig) extends Bundle { val reg = Vec(32, UInt(XLEN.W)) val pc = UInt(XLEN.W) val csr = CSR() + + val internal = Internal() } object State { def apply()(implicit XLEN: Int, config: RVConfig): State = new State def wireInit(pcStr: String = "h8000_0000")(implicit XLEN: Int, config: RVConfig): State = { val state = Wire(new State) + state.reg := Seq.fill(32)(0.U(XLEN.W)) state.pc := pcStr.U(XLEN.W) state.csr := CSR.wireInit() + + state.internal := Internal.wireInit() + state } } diff --git a/src/main/scala/rvspeccore/core/spec/instset/IBase.scala b/src/main/scala/rvspeccore/core/spec/instset/IBase.scala index a70a3c4..9f77024 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/IBase.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/IBase.scala @@ -328,7 +328,7 @@ trait IBase extends BaseCore with CommonDecode with IBaseInsts with ExceptionSup when(ECALL(inst)) { decodeI; - switch(privilegeMode) { + switch(now.internal.privilegeMode) { is(0x3.U) { raiseException(MExceptionCode.environmentCallFromMmode) } is(0x1.U) { raiseException(MExceptionCode.environmentCallFromSmode) } is(0x0.U) { raiseException(MExceptionCode.environmentCallFromUmode) } diff --git a/src/main/scala/rvspeccore/core/spec/instset/ZicsrExtension.scala b/src/main/scala/rvspeccore/core/spec/instset/ZicsrExtension.scala index 25ef21e..25a5562 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/ZicsrExtension.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/ZicsrExtension.scala @@ -69,7 +69,7 @@ trait ZicsrExtension extends BaseCore with ZicsrDecode with ZicsrExtensionInsts // TODO: what is wen mean? // val justRead = isSet && src1 === 0.U // csrrs and csrrsi are exceptions when their src1 is zero val isIllegalWrite = addr(11, 10) === "b11".U && (!justRead) - val isIllegalMode = privilegeMode < addr(9, 8) + val isIllegalMode = now.internal.privilegeMode < addr(9, 8) // val isIllegalWrite = wen && (addr(11, 10) === "b11".U) && !justRead // Write a read-only CSR register val isIllegalAccess = isIllegalMode || isIllegalWrite val has: Bool = MuxLookup(addr, false.B, now.csr.table.map { x => x.info.addr -> true.B }) diff --git a/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala b/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala index ce82562..d2bd64b 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala @@ -89,12 +89,12 @@ trait CSRSupport extends BaseCore with ExceptionSupport { } def Mret()(implicit config: RVConfig): Unit = { - when(privilegeMode === ModeM) { + when(now.internal.privilegeMode === ModeM) { val mstatusOld = WireInit(now.csr.mstatus.asTypeOf(new MstatusStruct)) val mstatusNew = WireInit(now.csr.mstatus.asTypeOf(new MstatusStruct)) - mstatusNew.mie := mstatusOld.mpie - privilegeMode := mstatusOld.mpp - mstatusNew.mpie := true.B + mstatusNew.mie := mstatusOld.mpie + next.internal.privilegeMode := mstatusOld.mpp + mstatusNew.mpie := true.B // printf("MRET Mstatus: %x, Mode: %x\n", mstatusOld.asUInt, privilegeMode) if (config.CSRMisaExtList.exists(s => s == 'U')) { mstatusNew.mpp := ModeU @@ -120,20 +120,20 @@ trait CSRSupport extends BaseCore with ExceptionSupport { // return instruction, SRET. When TSR=1, attempts to execute SRET while executing in S-mode // will raise an illegal instruction exception. When TSR=0, this operation is permitted in S-mode. // TSR is read-only 0 when S-mode is not supported. - val illegalSret = privilegeMode < ModeS - val illegalSModeSret = privilegeMode === ModeS && mstatusOld.tsr.asBool + val illegalSret = now.internal.privilegeMode < ModeS + val illegalSModeSret = now.internal.privilegeMode === ModeS && mstatusOld.tsr.asBool when(illegalSret || illegalSModeSret) { raiseException(MExceptionCode.illegalInstruction) }.otherwise { // FIXME: is mstatus not sstatus ? - mstatusNew.sie := mstatusOld.spie - privilegeMode := Cat(0.U(1.W), mstatusOld.spp) - mstatusNew.spie := true.B // 正确的 - mstatusNew.spp := ModeU - mstatusNew.mprv := 0x0.U // Volume II P21 " If xPP != M, xRET also sets MPRV = 0 " - next.csr.mstatus := mstatusNew.asUInt - lr := false.B - retTarget := next.csr.sepc(VAddrBits - 1, 0) + mstatusNew.sie := mstatusOld.spie + next.internal.privilegeMode := Cat(0.U(1.W), mstatusOld.spp) + mstatusNew.spie := true.B // 正确的 + mstatusNew.spp := ModeU + mstatusNew.mprv := 0x0.U // Volume II P21 " If xPP != M, xRET also sets MPRV = 0 " + next.csr.mstatus := mstatusNew.asUInt + lr := false.B + retTarget := next.csr.sepc(VAddrBits - 1, 0) // printf("nextpc1:%x\n",now.csr.sepc) global_data.setpc := true.B next.pc := now.csr.sepc diff --git a/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala b/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala index c5b65d8..91e206c 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala @@ -119,9 +119,8 @@ trait ExceptionSupport extends BaseCore { val illegalInstruction = WireInit(false.B) // 看看产生的是中断还是异常 // 仲裁之后的统一执行 尾部折叠判断优先级 - val exceptionVec = Wire(Vec(16, Bool())) - exceptionVec.map(_ := false.B) - val exceptionNO = Priority.excPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(exceptionVec(i), i.U, sum)) + val exceptionVec = WireInit(VecInit(Seq.fill(16)(false.B))) + val exceptionNO = MuxCase(0.U, Priority.excPriority.map(i => exceptionVec(i) -> i.U)) def exceptionSupportInit() = { illegalInstruction := true.B } @@ -136,7 +135,7 @@ trait ExceptionSupport extends BaseCore { } when(raiseExceptionIntr) { event.valid := true.B - dealExceptionCode + dealExceptionCode() }.otherwise { event.valid := false.B } @@ -145,7 +144,7 @@ trait ExceptionSupport extends BaseCore { exceptionVec(exceptionCode) := true.B raiseExceptionIntr := true.B } - def dealExceptionCode: Unit = { + def dealExceptionCode(): Unit = { // event.intrNO := exceptionNO event.cause := exceptionNO @@ -153,32 +152,27 @@ trait ExceptionSupport extends BaseCore { event.exceptionInst := io.inst(31, 0) // FIXME: 目前仅仅考虑了异常 val deleg = now.csr.medeleg - val delegS = (deleg(exceptionNO)) && (privilegeMode < ModeM) - // printf("[Error]Exception:%d Deleg[hex]:%x DelegS[hex]:%x Mode:%x \n",exceptionNO, deleg, delegS, privilegeMode) - // printf("[Debug] mstatus:%x %x\n", now.csr.mstatus, next.csr.mstatus) - // printf("[Debug] mepc:%x %x\n", now.csr.mepc, next.csr.mepc) - // printf("[Debug] mcause:%x %x Mode:%x\n", now.csr.mcause, next.csr.mcause, privilegeMode) + val delegS = (deleg(exceptionNO)) && (now.internal.privilegeMode < ModeM) // TODO: def raise an Interrupt // FIXME: 需要对中断做出处理 但是当前只针对异常进行处理 val mstatusOld = WireInit(now.csr.mstatus.asTypeOf(new MstatusStruct)) val mstatusNew = WireInit(now.csr.mstatus.asTypeOf(new MstatusStruct)) when(delegS) { - // printf("USE S Mode ing...\n") - event.cause := next.csr.scause - mstatusNew.spp := privilegeMode - mstatusNew.spie := mstatusOld.sie - mstatusNew.sie := false.B - privilegeMode := ModeS + event.cause := next.csr.scause + mstatusNew.spp := now.internal.privilegeMode + mstatusNew.spie := mstatusOld.sie + mstatusNew.sie := false.B + next.internal.privilegeMode := ModeS switch(now.csr.MXLEN) { is(32.U(8.W)) { doRaiseExceptionS(exceptionNO, 32) } is(64.U(8.W)) { if (XLEN >= 64) { doRaiseExceptionS(exceptionNO, 64) } } } }.otherwise { - event.cause := next.csr.mcause - mstatusNew.mpp := privilegeMode - mstatusNew.mpie := mstatusOld.mie - mstatusNew.mie := false.B - privilegeMode := ModeM + event.cause := next.csr.mcause + mstatusNew.mpp := now.internal.privilegeMode + mstatusNew.mpie := mstatusOld.mie + mstatusNew.mie := false.B + next.internal.privilegeMode := ModeM switch(now.csr.MXLEN) { is(32.U(8.W)) { doRaiseExceptionM(exceptionNO, 32) } is(64.U(8.W)) { if (XLEN >= 64) { doRaiseExceptionM(exceptionNO, 64) } } @@ -188,12 +182,12 @@ trait ExceptionSupport extends BaseCore { def doRaiseExceptionM(exceptionCode: UInt, MXLEN: Int): Unit = { // printf("[Debug]Mtval:%x\n", next.csr.mtval) // common part - next.csr.mcause := Cat(0.U, zeroExt(exceptionCode, MXLEN - 1)) - next.csr.mepc := now.pc - mstatusNew.mpp := privilegeMode - mstatusNew.mpie := mstatusOld.mie - mstatusNew.mie := false.B - privilegeMode := ModeM // 之前写的大bug + next.csr.mcause := Cat(0.U, zeroExt(exceptionCode, MXLEN - 1)) + next.csr.mepc := now.pc + mstatusNew.mpp := now.internal.privilegeMode + mstatusNew.mpie := mstatusOld.mie + mstatusNew.mie := false.B + next.internal.privilegeMode := ModeM // 之前写的大bug // FIXME: tva此处写法欠妥 next.csr.mtval := 0.U // : For other traps, mtval is set to zero next.csr.mstatus := mstatusNew.asUInt @@ -257,13 +251,13 @@ trait ExceptionSupport extends BaseCore { // common part next.csr.scause := Cat(false.B, zeroExt(exceptionCode, MXLEN - 1)) // printf("[Debug]:scause %x, normal %x \n", next.csr.scause, Cat(false.B, zeroExt(exceptionCode, MXLEN - 1))) - next.csr.sepc := now.pc - mstatusNew.spp := privilegeMode - mstatusNew.spie := mstatusOld.sie - mstatusNew.sie := false.B - privilegeMode := ModeS - next.csr.stval := 0.U // : For other traps, mtval is set to zero - next.csr.mstatus := mstatusNew.asUInt + next.csr.sepc := now.pc + mstatusNew.spp := now.internal.privilegeMode + mstatusNew.spie := mstatusOld.sie + mstatusNew.sie := false.B + next.internal.privilegeMode := ModeS + next.csr.stval := 0.U // : For other traps, mtval is set to zero + next.csr.mstatus := mstatusNew.asUInt // TODO: modify the exception case // special part switch(exceptionCode) { diff --git a/src/main/scala/rvspeccore/core/tool/LoadStore.scala b/src/main/scala/rvspeccore/core/tool/LoadStore.scala index 83cc5f3..392506f 100644 --- a/src/main/scala/rvspeccore/core/tool/LoadStore.scala +++ b/src/main/scala/rvspeccore/core/tool/LoadStore.scala @@ -60,11 +60,9 @@ trait LoadStore extends BaseCore with MMU { val rOff = addr(bytesWidth - 1, 0) << 3 // addr(byteWidth-1,0) * 8 val rMask = width2Mask(memWidth) val mstatusStruct = now.csr.mstatus.asTypeOf(new MstatusStruct) - val pv = Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode) + val pv = Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, now.internal.privilegeMode) val vmEnable = now.csr.satp.asTypeOf(new SatpStruct).mode === 8.U && (pv < 0x3.U) - // printf("[Debug]Read addr:%x, privilegeMode:%x %x %x %x vm:%x\n", addr, pv, mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode, vmEnable) mem.read.valid := true.B - // printf("[DEBUG] vmEnable: %x pv: %x mprv: %x mpp: %x pvmode:%x \n", vmEnable, pv, mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode) when(vmEnable) { // mem.read.addr := AddrTransRead(addr) // FIXME: addr 的虚实地址均并非64位 需进一步加以限制 @@ -90,7 +88,7 @@ trait LoadStore extends BaseCore with MMU { } else { // val pv = Mux(now.csr.mstatus) val mstatusStruct = now.csr.mstatus.asTypeOf(new MstatusStruct) - val pv = Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode) + val pv = Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, now.internal.privilegeMode) val vmEnable = now.csr.satp.asTypeOf(new SatpStruct).mode === 8.U && (pv < 0x3.U) // printf("[Debug]Write addr:%x, privilegeMode:%x %x %x %x vm:%x\n", addr, pv, mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode, vmEnable) mem.write.valid := true.B @@ -111,7 +109,7 @@ trait LoadStore extends BaseCore with MMU { } def iFetchTrans(addr: UInt): (Bool, UInt) = { - val vmEnable = now.csr.satp.asTypeOf(new SatpStruct).mode === 8.U && (privilegeMode < 0x3.U) + val vmEnable = now.csr.satp.asTypeOf(new SatpStruct).mode === 8.U && (now.internal.privilegeMode < 0x3.U) // printf("[Debug]iFetchTrans addr:%x, vm:%x \n", addr, vmEnable) val resultStatus = Wire(Bool()) val resultPC = Wire(UInt(XLEN.W)) diff --git a/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala b/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala index eb0521c..20630d0 100644 --- a/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala +++ b/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala @@ -22,6 +22,8 @@ class ConnectHelperSpec extends AnyFlatSpec with ChiselScalatestTester { val csr = ConnectCheckerResult.makeCSRSource() csr := now.csr ConnectCheckerResult.setChecker(checker) + + checker.io.result.internal := DontCare } it should "pass RiscvTests without mem check" in {