diff --git a/src/main/scala/vexriscv/demo/SynthesisBench.scala b/src/main/scala/vexriscv/demo/SynthesisBench.scala index 6a044ea..7a1ff35 100644 --- a/src/main/scala/vexriscv/demo/SynthesisBench.scala +++ b/src/main/scala/vexriscv/demo/SynthesisBench.scala @@ -2,6 +2,8 @@ package vexriscv.demo import spinal.core._ import spinal.lib._ +import spinal.lib.com.jtag.Jtag +import spinal.lib.cpu.riscv.debug.DebugTransportModuleParameter import spinal.lib.eda.bench._ import spinal.lib.eda.icestorm.IcestormStdTargets import spinal.lib.eda.xilinx.VivadoFlow @@ -9,7 +11,7 @@ import spinal.lib.io.InOutWrapper import vexriscv.demo.smp.VexRiscvSmpClusterGen import vexriscv.plugin.CsrAccess.{READ_ONLY, READ_WRITE, WRITE_ONLY} import vexriscv.{VexRiscv, VexRiscvConfig, plugin} -import vexriscv.plugin.{BranchPlugin, CsrPlugin, CsrPluginConfig, DBusSimplePlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusSimplePlugin, IntAluPlugin, LightShifterPlugin, NONE, RegFilePlugin, SrcPlugin, YamlPlugin} +import vexriscv.plugin.{BranchPlugin, CsrPlugin, CsrPluginConfig, DBusSimplePlugin, DebugPlugin, DecoderSimplePlugin, EmbeddedRiscvJtag, FullBarrelShifterPlugin, HazardSimplePlugin, IBusSimplePlugin, IntAluPlugin, LightShifterPlugin, NONE, Plugin, RegFilePlugin, SrcPlugin, YamlPlugin} import scala.collection.mutable.ArrayBuffer import scala.util.Random @@ -409,88 +411,94 @@ object VexRiscvCustomSynthesisBench { def main(args: Array[String]) { - def gen(csr : CsrPlugin) = new VexRiscv( - config = VexRiscvConfig( - plugins = List( - new IBusSimplePlugin( - resetVector = 0x80000000l, - cmdForkOnSecondStage = false, - cmdForkPersistence = false, - prediction = NONE, - catchAccessFault = false, - compressedGen = false - ), - new DBusSimplePlugin( - catchAddressMisaligned = false, - catchAccessFault = false - ), - new DecoderSimplePlugin( - catchIllegalInstruction = false - ), - new RegFilePlugin( - regFileReadyKind = plugin.SYNC, - zeroBoot = false - ), - new IntAluPlugin, - new SrcPlugin( - separatedAddSub = false, - executeInsertion = true - ), - csr, - new FullBarrelShifterPlugin(), - new HazardSimplePlugin( - bypassExecute = true, - bypassMemory = true, - bypassWriteBack = true, - bypassWriteBackBuffer = true, - pessimisticUseSrc = false, - pessimisticWriteRegFile = false, - pessimisticAddressMatch = false - ), - new BranchPlugin( - earlyBranch = false, - catchAddressMisaligned = false - ), - new YamlPlugin("cpu0.yaml") + def gen(csr : CsrPlugin, p : Plugin[VexRiscv]) = { + val cpu = new VexRiscv( + config = VexRiscvConfig( + plugins = List( + p, + new IBusSimplePlugin( + resetVector = 0x80000000l, + cmdForkOnSecondStage = false, + cmdForkPersistence = false, + prediction = NONE, + catchAccessFault = false, + compressedGen = false + ), + new DBusSimplePlugin( + catchAddressMisaligned = false, + catchAccessFault = false + ), + new DecoderSimplePlugin( + catchIllegalInstruction = false + ), + new RegFilePlugin( + regFileReadyKind = plugin.SYNC, + zeroBoot = false + ), + new IntAluPlugin, + new SrcPlugin( + separatedAddSub = false, + executeInsertion = true + ), + csr, + new FullBarrelShifterPlugin(), + new HazardSimplePlugin( + bypassExecute = true, + bypassMemory = true, + bypassWriteBack = true, + bypassWriteBackBuffer = true, + pessimisticUseSrc = false, + pessimisticWriteRegFile = false, + pessimisticAddressMatch = false + ), + new BranchPlugin( + earlyBranch = false, + catchAddressMisaligned = false + ), + new YamlPlugin("cpu0.yaml") + ) ) ) - ) - - - val fixedMtvec = new Rtl { - override def getName(): String = "Fixed MTVEC" - override def getRtlPath(): String = "fixedMtvec.v" - SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(0x80000000l))).setDefinitionName(getRtlPath().split("\\.").head)) - } - - val writeOnlyMtvec = new Rtl { - override def getName(): String = "write only MTVEC" - override def getRtlPath(): String = "woMtvec.v" - SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(null).copy(mtvecAccess = WRITE_ONLY))).setDefinitionName(getRtlPath().split("\\.").head)) - } - - val readWriteMtvec = new Rtl { - override def getName(): String = "read write MTVEC" - override def getRtlPath(): String = "wrMtvec.v" - SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(null).copy(mtvecAccess = READ_WRITE))).setDefinitionName(getRtlPath().split("\\.").head)) - } - - val fixedMtvecRoCounter = new Rtl { - override def getName(): String = "Fixed MTVEC, read only mcycle/minstret" - override def getRtlPath(): String = "fixedMtvecRoCounter.v" - SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(0x80000000l).copy(mcycleAccess = READ_ONLY, minstretAccess = READ_ONLY))).setDefinitionName(getRtlPath().split("\\.").head)) + cpu.rework { + for (plugin <- cpu.config.plugins) plugin match { + case plugin: DebugPlugin => plugin.debugClockDomain { + plugin.io.bus.setAsDirectionLess() + val jtag = slave(new Jtag()) + .setName("jtag") + jtag <> plugin.io.bus.fromJtag() + } + case _ => + } + } + cpu } - val rwMtvecRoCounter = new Rtl { - override def getName(): String = "read write MTVEC, read only mcycle/minstret" - override def getRtlPath(): String = "readWriteMtvecRoCounter.v" - SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(null).copy(mtvecAccess = READ_WRITE, mcycleAccess = READ_ONLY, minstretAccess = READ_ONLY))).setDefinitionName(getRtlPath().split("\\.").head)) + val riscvDebug = new Rtl { + override def getName(): String = "riscvDebug" + override def getRtlPath(): String = "riscvDebug.v" + SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(0x80000000l).copy(withPrivilegedDebug = true)), new EmbeddedRiscvJtag( + p = DebugTransportModuleParameter( + addressWidth = 7, + version = 1, + idle = 7 + ), + withTunneling = false, + withTap = true + )).setDefinitionName(getRtlPath().split("\\.").head)) + } + + val vexDebug = new Rtl { + override def getName(): String = "vexDebug" + override def getRtlPath(): String = "vexDebug.v" + SpinalVerilog(gen(new CsrPlugin(CsrPluginConfig.smallest(0x80000000l)), + new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))) + ).setDefinitionName(getRtlPath().split("\\.").head)) } // val rtls = List(twoStage, twoStageBarell, twoStageMulDiv, twoStageAll, smallestNoCsr, smallest, smallAndProductive, smallAndProductiveWithICache, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full, linuxBalanced, linuxBalancedSmp) - val rtls = List(fixedMtvec, writeOnlyMtvec, readWriteMtvec,fixedMtvecRoCounter, rwMtvecRoCounter) + val rtls = List(riscvDebug, vexDebug) // val rtls = List(smallest) val targets = XilinxStdTargets() ++ AlteraStdTargets() ++ IcestormStdTargets().take(1) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 6d05e69..40f6a6e 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -470,6 +470,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep var externalMhartId : UInt = null var utime : UInt = null var stoptime : Bool = null + var xretAwayFromMachine : Bool = null var debugBus : DebugHartBus = null var debugMode : Bool = null @@ -633,6 +634,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep decoderService.add(SFENCE_VMA, List(IS_SFENCE_VMA -> True)) } + xretAwayFromMachine = False injectionPort = withPrivilegedDebug generate pipeline.service(classOf[IBusFetcher]).getInjectionPort() debugMode = withPrivilegedDebug generate Bool().setName("debugMode") @@ -751,7 +753,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep val prv = RegInit(U"11") val step = RegInit(False) //TODO val nmip = False - val mprven = False + val mprven = True val cause = RegInit(U"000") val stoptime = RegInit(False) val stopcount = RegInit(False) @@ -1380,14 +1382,20 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep mstatus.MIE := mstatus.MPIE mstatus.MPIE := True jumpInterface.payload := mepc - if(privilegeGen) privilegeReg := mstatus.MPP + if(privilegeGen) { + privilegeReg := mstatus.MPP + xretAwayFromMachine setWhen(mstatus.MPP < 3) + } } if(supervisorGen) is(1){ sstatus.SPP := U"0" sstatus.SIE := sstatus.SPIE sstatus.SPIE := True jumpInterface.payload := sepc - if(privilegeGen) privilegeReg := U"0" @@ sstatus.SPP + if(privilegeGen) { + privilegeReg := U"0" @@ sstatus.SPP + xretAwayFromMachine := True + } } } } diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index 093f59a..c984b03 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -69,7 +69,7 @@ class MmuPlugin(ioRange : UInt => Bool, import pipeline._ import pipeline.config._ import Riscv._ - val csrService = pipeline.service(classOf[CsrInterface]) + val csrService = pipeline.service(classOf[CsrPlugin]) //Sorted by priority val sortedPortsInfo = portsInfo.sortBy(_.priority) @@ -89,6 +89,7 @@ class MmuPlugin(ioRange : UInt => Bool, val csr = pipeline plug new Area{ val status = new Area{ val sum, mxr, mprv = RegInit(False) + mprv clearWhen(csrService.xretAwayFromMachine) } val satp = new Area { val mode = RegInit(False)