diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index 86cd8cb..185a67f 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -206,7 +206,7 @@ object VexRiscvSmpClusterGen { val csrConfig = if(withSupervisor){ var c = CsrPluginConfig.openSbi(mhartid = hartId, misa = misa).copy(utimeAccess = CsrAccess.READ_ONLY, withPrivilegedDebug = privilegedDebug) if(csrFull){ - c.copy( + c = c.copy( mcauseAccess = CsrAccess.READ_WRITE, mbadaddrAccess = CsrAccess.READ_WRITE ) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 85407de..4f4c481 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -952,13 +952,20 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep } }) + def guardedWrite(csrId : Int, bitRange: Range, allowed : Seq[Int], target : Bits) = { + onWrite(csrId){ + when(allowed.map(writeData()(bitRange) === _).orR){ + target := writeData()(bitRange) + } + } + } val machineCsr = pipeline plug new Area{ //Define CSR registers // Status => MXR, SUM, TVM, TW, TSE ? val misa = new Area{ - val base = Reg(UInt(2 bits)) init(U"01") allowUnsetRegToAvoidLatch - val extensions = Reg(Bits(26 bits)) init(misaExtensionsInit) allowUnsetRegToAvoidLatch + val base = U"01" + val extensions = B(misaExtensionsInit, 26 bits) } val mtvec = Reg(Xtvec()).allowUnsetRegToAvoidLatch @@ -1001,7 +1008,10 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep if(mimpid != null) READ_ONLY(CSR.MIMPID , U(mimpid )) if(mhartid != null && !withExternalMhartid) READ_ONLY(CSR.MHARTID , U(mhartid )) if(withExternalMhartid) READ_ONLY(CSR.MHARTID , externalMhartId) - misaAccess(CSR.MISA, xlen-2 -> misa.base , 0 -> misa.extensions) + if(misaAccess.canRead) { + READ_ONLY(CSR.MISA, xlen-2 -> misa.base , 0 -> misa.extensions) + onWrite(CSR.MISA){} + } //Machine CSR READ_WRITE(CSR.MSTATUS, 7 -> mstatus.MPIE, 3 -> mstatus.MIE) @@ -1018,7 +1028,11 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep } } - mtvecAccess(CSR.MTVEC, 2 -> mtvec.base, 0 -> mtvec.mode) + mtvecAccess(CSR.MTVEC, 2 -> mtvec.base) + if(mtvecAccess.canWrite && xtvecModeGen) { + guardedWrite(CSR.MTVEC, 1 downto 0, List(0, 1), mtvec.mode) + } + mepcAccess(CSR.MEPC, mepc) if(mscratchGen) READ_WRITE(CSR.MSCRATCH, mscratch) mcauseAccess(CSR.MCAUSE, xlen-1 -> mcause.interrupt, 0 -> mcause.exceptionCode) @@ -1091,7 +1105,10 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep for(offset <- List(CSR.MIE, CSR.SIE)) READ_WRITE(offset, 9 -> sie.SEIE, 5 -> sie.STIE, 1 -> sie.SSIE) - stvecAccess(CSR.STVEC, 2 -> stvec.base, 0 -> stvec.mode) + stvecAccess(CSR.STVEC, 2 -> stvec.base) + if(mtvecAccess.canWrite && xtvecModeGen) { + guardedWrite(CSR.STVEC, 1 downto 0, List(0, 1), stvec.mode) + } sepcAccess(CSR.SEPC, sepc) if(sscratchGen) READ_WRITE(CSR.SSCRATCH, sscratch) scauseAccess(CSR.SCAUSE, xlen-1 -> scause.interrupt, 0 -> scause.exceptionCode) @@ -1651,6 +1668,13 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep case element : CsrOnRead => when(readEnable){element.doThat()} } + //When no PMP => +// if(!csrMapping.mapping.contains(0x3A0)){ +// when(arbitration.isValid && input(IS_CSR) && U(csrAddress) >= 0x3A0 && U(csrAddress) <= 0x3EF){ +// csrMapping.allowCsrSignal := True +// } +// } + illegalAccess clearWhen(csrMapping.allowCsrSignal) val forceFail = CombInit(csrMapping.doForceFailCsr) diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 35e9cc3..3bbd26c 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -629,7 +629,10 @@ public: case UTIMEH: *value = dutRfWriteValue; break; #endif - default: return true; break; + default: { +// if(csr >= 0x3A0 && csr <= 0x3EF) break; //PMP + return true; + }break; } // if(csr == MSTATUS || csr == SSTATUS){ // printf("READ %x %x\n", pc, *value); @@ -657,7 +660,7 @@ public: case MSTATUS: status.raw = value & 0x7FFFFFFF; break; case MIP: ipSoft = value; break; case MIE: ie.raw = value; break; - case MTVEC: mtvec.raw = value; break; + case MTVEC: mtvec.raw = value & 0xFFFFFFFC; break; case MCAUSE: mcause.raw = value; break; case MBADADDR: mbadaddr = value; break; case MEPC: mepc = value; break; @@ -669,7 +672,7 @@ public: case SSTATUS: maskedWrite(status.raw, value, 0xC0133 | STATUS_FS_MASK); break; case SIP: maskedWrite(ipSoft, value,0x333); break; case SIE: maskedWrite(ie.raw, value,0x333); break; - case STVEC: stvec.raw = value; break; + case STVEC: stvec.raw = value & 0xFFFFFFFC; break; case SCAUSE: scause.raw = value; break; case STVAL: sbadaddr = value; break; case SEPC: sepc = value; break; @@ -682,7 +685,11 @@ public: case FFLAGS: fcsr.flags = value; status.fs = 3; break; #endif - default: ilegalInstruction(); return true; break; + default: { +// if(csr >= 0x3A0 && csr <= 0x3EF) break; //PMP + ilegalInstruction(); + return true; + }break; } // if(csr == MSTATUS || csr == SSTATUS){ // printf(" %x %x\n", pc, status.raw);