diff --git a/src/main/scala/SpinalRiscv/Plugin/MachineCsr.scala b/src/main/scala/SpinalRiscv/Plugin/MachineCsr.scala index d5ca473..6f5a4e3 100644 --- a/src/main/scala/SpinalRiscv/Plugin/MachineCsr.scala +++ b/src/main/scala/SpinalRiscv/Plugin/MachineCsr.scala @@ -33,8 +33,9 @@ case class MachineCsrConfig( mepcAccess : CsrAccess, mscratchGen : Boolean, mcauseAccess : CsrAccess, - mbadaddrAccess : CsrAccess - + mbadaddrAccess : CsrAccess, + mcycleAccess : CsrAccess, + minstretAccess : CsrAccess ) @@ -54,11 +55,6 @@ case class CsrMapping(){ def r [T <: Data](csrAddress : Int, thats : (Int, Data)*) : Unit = for(that <- thats) r(csrAddress,that._1, that._2) def rw[T <: Data](csrAddress : Int, that : T): Unit = rw(csrAddress,0,that) def r [T <: Data](csrAddress : Int, that : T): Unit = r(csrAddress,0,that) - def rx [T <: Data](csrAddress : Int, thats : (Int, Data)*)(writable : Boolean) : Unit = - if(writable) - for(that <- thats) rw(csrAddress,that._1, that._2) - else - for(that <- thats) r(csrAddress,that._1, that._2) } @@ -135,6 +131,7 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except pluginExceptionPort.valid := False pluginExceptionPort.payload.assignDontCare() } + def xlen = 32 override def build(pipeline: VexRiscv): Unit = { import pipeline._ @@ -147,7 +144,7 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except } pipeline plug new Area{ - //Define CSR registers + //Define CSR mapping utilities val csrMapping = new CsrMapping() implicit class CsrAccessPimper(csrAccess : CsrAccess){ def apply(csrAddress : Int, thats : (Int, Data)*) : Unit = csrAccess match{ @@ -160,6 +157,8 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except } } + + //Define CSR registers val mtvec = RegInit(U(mtvecInit,xlen bits)) val mepc = Reg(UInt(xlen bits)) @@ -178,6 +177,10 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except val exceptionCode = Reg(UInt(exceptionCodeWidth bits)) } val mbadaddr = Reg(UInt(xlen bits)) + val mcycle = Reg(UInt(64 bits)) randBoot() + val minstret = Reg(UInt(64 bits)) randBoot() + + //Define CSR registers accessibility if(mvendorid != null) READ_ONLY(CSR.MVENDORID, U(mvendorid)) @@ -195,6 +198,18 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except if(mscratchGen) READ_WRITE(CSR.MSCRATCH, mscratch) mcauseAccess(CSR.MCAUSE, xlen-1 -> mcause.interrupt, 0 -> mcause.exceptionCode) mbadaddrAccess(CSR.MBADADDR, mbadaddr) + mcycleAccess(CSR.MCYCLE, mcycle(31 downto 0)) + mcycleAccess(CSR.MCYCLEH, mcycle(63 downto 32)) + minstretAccess(CSR.MINSTRET, minstret(31 downto 0)) + minstretAccess(CSR.MINSTRETH, minstret(63 downto 32)) + + + + //Manage counters + mcycle := mcycle + 1 + when(writeBack.arbitration.isFiring) { + minstret := minstret + 1 + } diff --git a/src/main/scala/SpinalRiscv/Riscv.scala b/src/main/scala/SpinalRiscv/Riscv.scala index a8bc584..ad5af75 100644 --- a/src/main/scala/SpinalRiscv/Riscv.scala +++ b/src/main/scala/SpinalRiscv/Riscv.scala @@ -100,5 +100,15 @@ object Riscv{ def MCAUSE = 0x342 // MRW Machine trap cause. def MBADADDR = 0x343 // MRW Machine bad address. def MIP = 0x344 // MRW Machine interrupt pending. + def MBASE = 0x380 // MRW Base register. + def MBOUND = 0x381 // MRW Bound register. + def MIBASE = 0x382 // MRW Instruction base register. + def MIBOUND = 0x383 // MRW Instruction bound register. + def MDBASE = 0x384 // MRW Data base register. + def MDBOUND = 0x385 // MRW Data bound register. + def MCYCLE = 0xB00 // MRW Machine cycle counter. + def MINSTRET = 0xB02 // MRW Machine instructions-retired counter. + def MCYCLEH = 0xB80 // MRW Upper 32 bits of mcycle, RV32I only. + def MINSTRETH = 0xB82 // MRW Upper 32 bits of minstret, RV32I only. } } diff --git a/src/main/scala/SpinalRiscv/TopLevel.scala b/src/main/scala/SpinalRiscv/TopLevel.scala index 226edce..59b1a00 100644 --- a/src/main/scala/SpinalRiscv/TopLevel.scala +++ b/src/main/scala/SpinalRiscv/TopLevel.scala @@ -44,7 +44,9 @@ object TopLevel { mepcAccess = READ_WRITE, mscratchGen = true, mcauseAccess = READ_WRITE, - mbadaddrAccess = READ_WRITE + mbadaddrAccess = READ_WRITE, + mcycleAccess = READ_WRITE, + minstretAccess = READ_WRITE ) config.plugins ++= List(