From 3739b9ac8897263eaa7104db6a68e5b58a4df09c Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 29 Aug 2023 08:58:48 +0200 Subject: [PATCH 1/8] plic update --- src/test/scala/vexriscv/experimental/PlicCost.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/scala/vexriscv/experimental/PlicCost.scala b/src/test/scala/vexriscv/experimental/PlicCost.scala index 79d5c66..df00842 100644 --- a/src/test/scala/vexriscv/experimental/PlicCost.scala +++ b/src/test/scala/vexriscv/experimental/PlicCost.scala @@ -33,6 +33,7 @@ class PlicBench(inputCount : Int) extends Component{ val targets = Seq( PlicTarget( + id = 0, gateways = gateways, priorityWidth = priorityWidth ) From 73733dd8b1781f93102aeb83c934e3fb906e1260 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 8 Sep 2023 16:00:59 +0200 Subject: [PATCH 2/8] litex privileged debug --- .../demo/smp/VexRiscvSmpCluster.scala | 75 ++++++++++++++++--- .../demo/smp/VexRiscvSmpLitexCluster.scala | 7 +- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index 6fffb6a..abf503b 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -14,6 +14,7 @@ import spinal.lib.com.jtag.xilinx.Bscane2BmbMasterGenerator import spinal.lib.generator._ import spinal.core.fiber._ import spinal.idslplugin.PostInitCallback +import spinal.lib.cpu.riscv.debug.{DebugModule, DebugModuleCpuConfig, DebugModuleParameter, DebugTransportModuleParameter, DebugTransportModuleTunneled} import spinal.lib.misc.plic.PlicMapping import spinal.lib.system.debugger.SystemDebuggerConfig import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionCache, InstructionCacheConfig} @@ -30,7 +31,8 @@ case class VexRiscvSmpClusterParameter(cpuConfigs : Seq[VexRiscvConfig], withExclusiveAndInvalidation : Boolean, forcePeripheralWidth : Boolean = true, outOfOrderDecoder : Boolean = true, - fpu : Boolean = false) + fpu : Boolean = false, + privilegedDebug : Boolean = false) class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with PostInitCallback{ val cpuCount = p.cpuConfigs.size @@ -52,10 +54,12 @@ class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with implicit val interconnect = BmbInterconnectGenerator() - val debugBridge = debugCd.outputClockDomain on JtagInstructionDebuggerGenerator(p.jtagHeaderIgnoreWidth) - debugBridge.jtagClockDomain.load(ClockDomain.external("jtag", withReset = false)) + val customDebug = !p.privilegedDebug generate new Area { + val debugBridge = debugCd.outputClockDomain on JtagInstructionDebuggerGenerator(p.jtagHeaderIgnoreWidth) + debugBridge.jtagClockDomain.load(ClockDomain.external("jtag", withReset = false)) - val debugPort = Handle(debugBridge.logic.jtagBridge.io.ctrl.toIo) + val debugPort = Handle(debugBridge.logic.jtagBridge.io.ctrl.toIo) + } val dBusCoherent = BmbBridgeGenerator() val dBusNonCoherent = BmbBridgeGenerator() @@ -80,12 +84,65 @@ class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with interconnect.addConnection( cpu.dBus -> List(dBusCoherent.bmb) ) - cpu.enableDebugBmb( - debugCd = debugCd.outputClockDomain, - resetCd = systemCd, - mapping = SizeMapping(cpuId*0x1000, 0x1000) + + if(!p.privilegedDebug) { + cpu.enableDebugBmb( + debugCd = debugCd.outputClockDomain, + resetCd = systemCd, + mapping = SizeMapping(cpuId * 0x1000, 0x1000) + ) + interconnect.addConnection(customDebug.debugBridge.bmb, cpu.debugBmb) + } else { + cpu.enableRiscvDebug(debugCd.outputClockDomain, systemCd) + } + } + + val privilegedDebug = p.privilegedDebug generate new Area{ + val jtagCd = ClockDomain.external("jtag", withReset = false) + + val systemReset = Handle(Bool()) + systemCd.relaxedReset(systemReset, ResetSensitivity.HIGH) + + val p = DebugTransportModuleParameter( + addressWidth = 7, + version = 1, + idle = 7 ) - interconnect.addConnection(debugBridge.bmb, cpu.debugBmb) + + val logic = hardFork(debugCd.outputClockDomain on new Area { + val XLEN = 32 + + val dm = DebugModule( + DebugModuleParameter( + version = p.version + 1, + harts = cpuCount, + progBufSize = 2, + datacount = XLEN / 32 + cores.exists(_.cpu.config.get.FLEN == 64).toInt, + hartsConfig = cores.map(c => DebugModuleCpuConfig( + xlen = XLEN, + flen = c.cpu.config.get.FLEN, + withFpuRegAccess = c.cpu.config.get.FLEN == 64 + )) + ) + ) + systemReset := dm.io.ndmreset + for ((cpu, i) <- cores.zipWithIndex) { + val privBus = cpu.cpu.debugRiscv + privBus <> dm.io.harts(i) + privBus.dmToHart.removeAssignments() <-< dm.io.harts(i).dmToHart + } + + val clintStop = (cores.map(e => e.cpu.logic.cpu.service(classOf[CsrPlugin]).stoptime).andR) + + val tunnel = DebugTransportModuleTunneled( + p = p, + jtagCd = jtagCd, + debugCd = ClockDomain.current + ) + dm.io.ctrl <> tunnel.io.bus + + val debugPort = Handle(tunnel.io.instruction.toIo) + }) } } diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala index 3454577..3d380ca 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala @@ -101,6 +101,7 @@ class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexR object VexRiscvLitexSmpClusterCmdGen extends App { + Handle.loadHandleAsync = true var cpuCount = 1 var iBusWidth = 64 var dBusWidth = 64 @@ -108,6 +109,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { var dCacheSize = 8192 var iCacheWays = 2 var dCacheWays = 2 + var privilegedDebug = false var liteDramWidth = 128 var coherentDma = false var wishboneMemory = false @@ -131,6 +133,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { opt[String]("dcache-size") action { (v, c) => dCacheSize = v.toInt } opt[String]("icache-ways") action { (v, c) => iCacheWays = v.toInt } opt[String]("dcache-ways") action { (v, c) => dCacheWays = v.toInt } + opt[Boolean]("privileged-debug") action { (v, c) => privilegedDebug = v } opt[String]("litedram-width") action { (v, c) => liteDramWidth = v.toInt } opt[String]("netlist-directory") action { (v, c) => netlistDirectory = v } opt[String]("netlist-name") action { (v, c) => netlistName = v } @@ -160,6 +163,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { iCacheWays = iCacheWays, dCacheWays = dCacheWays, coherency = coherency, + privilegedDebug = privilegedDebug, iBusRelax = true, earlyBranch = true, withFloat = fpu, @@ -178,7 +182,8 @@ object VexRiscvLitexSmpClusterCmdGen extends App { forcePeripheralWidth = !wishboneMemory || wishboneForce32b, outOfOrderDecoder = outOfOrderDecoder, fpu = fpu, - jtagHeaderIgnoreWidth = 0 + jtagHeaderIgnoreWidth = 0, + privilegedDebug = privilegedDebug ), liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = liteDramWidth), liteDramMapping = SizeMapping(0x40000000l, 0x40000000l), From 9fd127d6d9a555aae10fead3cd7297770888c7e8 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 8 Sep 2023 16:26:23 +0200 Subject: [PATCH 3/8] fix naming --- src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index abf503b..2b8fb7d 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -58,7 +58,7 @@ class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with val debugBridge = debugCd.outputClockDomain on JtagInstructionDebuggerGenerator(p.jtagHeaderIgnoreWidth) debugBridge.jtagClockDomain.load(ClockDomain.external("jtag", withReset = false)) - val debugPort = Handle(debugBridge.logic.jtagBridge.io.ctrl.toIo) + val debugPort = Handle(debugBridge.logic.jtagBridge.io.ctrl.toIo).setName("debugPort") } val dBusCoherent = BmbBridgeGenerator() @@ -141,7 +141,7 @@ class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with ) dm.io.ctrl <> tunnel.io.bus - val debugPort = Handle(tunnel.io.instruction.toIo) + val debugPort = Handle(tunnel.io.instruction.toIo).setName("debugPort") }) } } @@ -216,7 +216,7 @@ class VexRiscvSmpClusterWithPeripherals(p : VexRiscvSmpClusterParameter) extends clint.cpuCount.load(cpuCount) } - +//python3 -m litex_boards.targets.digilent_nexys_video --cpu-type=vexriscv_smp --with-privileged-debug --sys-clk-freq 50000000 --cpu-count 1 --build --load object VexRiscvSmpClusterGen { def vexRiscvConfig(hartId : Int, ioRange : UInt => Bool = (x => x(31 downto 28) === 0xF), From 220a2733be0e490dd627b8b412000cf60dd1f9c1 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 8 Sep 2023 16:47:54 +0200 Subject: [PATCH 4/8] litex privileged debug stop time now connect to clint --- src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index 2b8fb7d..b93e5f4 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -214,6 +214,7 @@ class VexRiscvSmpClusterWithPeripherals(p : VexRiscvSmpClusterParameter) extends } clint.cpuCount.load(cpuCount) + if(p.privilegedDebug) hardFork(clint.logic.io.stop := privilegedDebug.logic.clintStop) } //python3 -m litex_boards.targets.digilent_nexys_video --cpu-type=vexriscv_smp --with-privileged-debug --sys-clk-freq 50000000 --cpu-count 1 --build --load From 213e4b863a1d0ae898f7eea7be5771c2a8dbcc63 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 12 Sep 2023 10:40:45 +0200 Subject: [PATCH 5/8] litex add -expose-time --- .../demo/smp/VexRiscvSmpLitexCluster.scala | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala index 3d380ca..a314177 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala @@ -7,6 +7,7 @@ import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping} import spinal.lib.bus.wishbone.{WishboneConfig, WishboneToBmbGenerator} import spinal.lib.generator.GeneratorComponent import spinal.lib.sim.SparseMemory +import vexriscv.demo.smp.VexRiscvLitexSmpClusterCmdGen.exposeTime import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig import vexriscv.ip.fpu.{FpuCore, FpuParameter} import vexriscv.plugin.{AesPlugin, DBusCachedPlugin, FpuPlugin} @@ -17,7 +18,8 @@ case class VexRiscvLitexSmpClusterParameter( cluster : VexRiscvSmpClusterParamet liteDramMapping : AddressMapping, coherentDma : Boolean, wishboneMemory : Boolean, - cpuPerFpu : Int) + cpuPerFpu : Int, + exposeTime : Boolean) class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexRiscvSmpClusterWithPeripherals(p.cluster) { @@ -97,6 +99,8 @@ class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexR interconnect.setPipelining(iBridge.bmb)(cmdHalfRate = true) interconnect.setPipelining(dBridge.bmb)(cmdReady = true) } + + val clint_time = p.exposeTime generate hardFork(clint.logic.io.time.toIo) } @@ -123,6 +127,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { var iTlbSize = 4 var dTlbSize = 4 var wishboneForce32b = false + var exposeTime = false assert(new scopt.OptionParser[Unit]("VexRiscvLitexSmpClusterCmdGen") { help("help").text("prints this usage text") opt[Unit]("coherent-dma") action { (v, c) => coherentDma = true } @@ -146,6 +151,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { opt[String]("rvc") action { (v, c) => rvc = v.toBoolean } opt[String]("itlb-size") action { (v, c) => iTlbSize = v.toInt } opt[String]("dtlb-size") action { (v, c) => dTlbSize = v.toInt } + opt[String]("expose-time") action { (v, c) => exposeTime = v.toBoolean } }.parse(args, Unit).nonEmpty) val coherency = coherentDma || cpuCount > 1 @@ -172,8 +178,8 @@ object VexRiscvLitexSmpClusterCmdGen extends App { loadStoreWidth = if(fpu) 64 else 32, rvc = rvc, injectorStage = rvc, - iTlbSize = iTlbSize, - dTlbSize = dTlbSize + iTlbSize = iTlbSize, + dTlbSize = dTlbSize ) if(aesInstruction) c.add(new AesPlugin) c @@ -189,7 +195,8 @@ object VexRiscvLitexSmpClusterCmdGen extends App { liteDramMapping = SizeMapping(0x40000000l, 0x40000000l), coherentDma = coherentDma, wishboneMemory = wishboneMemory, - cpuPerFpu = cpuPerFpu + cpuPerFpu = cpuPerFpu, + exposeTime = exposeTime ) def dutGen = { @@ -265,7 +272,8 @@ object VexRiscvLitexSmpClusterOpenSbi extends App{ liteDramMapping = SizeMapping(0x80000000l, 0x70000000l), coherentDma = false, wishboneMemory = false, - cpuPerFpu = 4 + cpuPerFpu = 4, + exposeTime = false ) def dutGen = { From acf6ad3bfdfc8cd44f4432b055945fd1d7d38fe8 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 13 Sep 2023 14:55:35 +0200 Subject: [PATCH 6/8] Add doc about official RISC-V debug support --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index c7578c6..28bace2 100644 --- a/README.md +++ b/README.md @@ -1294,6 +1294,42 @@ Write Address 0x04 -> The OpenOCD port is here: +#### EmbeddedRiscvJtag + +VexRiscv also support the official RISC-V debug specification (Thanks Efinix for the funding !). + +To enable it, you need to add the EmbeddedRiscvJtag to the plugin list : + +```scala +new EmbeddedRiscvJtag( + p = DebugTransportModuleParameter( + addressWidth = 7, + version = 1, + idle = 7 + ), + withTunneling = false, + withTap = true +) +``` + +And turn on the withPrivilegedDebug option in the CsrPlugin config. + +Here is an example of openocd tcl script to connect : + +```tcl +# ADD HERE YOUR JTAG ADAPTER SETTINGS + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10002FFF + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME + +init +halt +``` + #### YamlPlugin This plugin offers a service to other plugins to generate a useful Yaml file describing the CPU configuration. It contains, for instance, the sequence of instructions required From e21dc6cda51ff0848d3ee654f5a372519b1821ac Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 20 Sep 2023 09:08:18 +0200 Subject: [PATCH 7/8] litex add hardwarebreapoint parameter --- src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala | 4 +++- .../scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index b93e5f4..854828f 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -32,7 +32,8 @@ case class VexRiscvSmpClusterParameter(cpuConfigs : Seq[VexRiscvConfig], forcePeripheralWidth : Boolean = true, outOfOrderDecoder : Boolean = true, fpu : Boolean = false, - privilegedDebug : Boolean = false) + privilegedDebug : Boolean = false, + hardwareBreakpoints : Int = 0) class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with PostInitCallback{ val cpuCount = p.cpuConfigs.size @@ -85,6 +86,7 @@ class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Area with cpu.dBus -> List(dBusCoherent.bmb) ) + cpu.hardwareBreakpointCount.load(p.hardwareBreakpoints) if(!p.privilegedDebug) { cpu.enableDebugBmb( debugCd = debugCd.outputClockDomain, diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala index a314177..9a8aefe 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala @@ -114,6 +114,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { var iCacheWays = 2 var dCacheWays = 2 var privilegedDebug = false + var hardwareBreakpoints = 0 var liteDramWidth = 128 var coherentDma = false var wishboneMemory = false @@ -130,7 +131,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { var exposeTime = false assert(new scopt.OptionParser[Unit]("VexRiscvLitexSmpClusterCmdGen") { help("help").text("prints this usage text") - opt[Unit]("coherent-dma") action { (v, c) => coherentDma = true } + opt[Unit] ("coherent-dma") action { (v, c) => coherentDma = true } opt[String]("cpu-count") action { (v, c) => cpuCount = v.toInt } opt[String]("ibus-width") action { (v, c) => iBusWidth = v.toInt } opt[String]("dbus-width") action { (v, c) => dBusWidth = v.toInt } @@ -139,6 +140,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App { opt[String]("icache-ways") action { (v, c) => iCacheWays = v.toInt } opt[String]("dcache-ways") action { (v, c) => dCacheWays = v.toInt } opt[Boolean]("privileged-debug") action { (v, c) => privilegedDebug = v } + opt[Int] ("hardware-breakpoints") action { (v, c) => hardwareBreakpoints = v } opt[String]("litedram-width") action { (v, c) => liteDramWidth = v.toInt } opt[String]("netlist-directory") action { (v, c) => netlistDirectory = v } opt[String]("netlist-name") action { (v, c) => netlistName = v } @@ -189,7 +191,8 @@ object VexRiscvLitexSmpClusterCmdGen extends App { outOfOrderDecoder = outOfOrderDecoder, fpu = fpu, jtagHeaderIgnoreWidth = 0, - privilegedDebug = privilegedDebug + privilegedDebug = privilegedDebug, + hardwareBreakpoints = hardwareBreakpoints ), liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = liteDramWidth), liteDramMapping = SizeMapping(0x40000000l, 0x40000000l), From 281818af9c04517baa7c6dffe62e229bfa7e036a Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 31 Oct 2023 11:05:00 +0100 Subject: [PATCH 8/8] #373 Add GenFullWithTcm demo --- README.md | 1 + .../scala/vexriscv/demo/GenFullWithTcm.scala | 100 ++++++++++++++++++ .../vexriscv/plugin/DBusCachedPlugin.scala | 9 ++ 3 files changed, 110 insertions(+) create mode 100644 src/main/scala/vexriscv/demo/GenFullWithTcm.scala diff --git a/README.md b/README.md index 28bace2..30c814e 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ This repository hosts a RISC-V implementation written in SpinalHDL. Here are som - Linux compatible (SoC : https://github.com/enjoy-digital/linux-on-litex-vexriscv) - Zephyr compatible - [FreeRTOS port](https://github.com/Dolu1990/FreeRTOS-RISCV) +- Support tightly coupled memory on I$ D$ (see GenFullWithTcm) The hardware description of this CPU is done by using a very software oriented approach (without any overhead in the generated hardware). Here is a list of software concepts used: diff --git a/src/main/scala/vexriscv/demo/GenFullWithTcm.scala b/src/main/scala/vexriscv/demo/GenFullWithTcm.scala new file mode 100644 index 0000000..0b7618e --- /dev/null +++ b/src/main/scala/vexriscv/demo/GenFullWithTcm.scala @@ -0,0 +1,100 @@ +package vexriscv.demo + +import spinal.core._ +import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig} +import vexriscv.plugin._ +import vexriscv.{VexRiscv, VexRiscvConfig, plugin} + +/** + * Both iBusTc and dBusTc assume + * - 1 cycle read latency + * - read_data stay on the port until the next access + * - writes should only occure when dBusTc_enable && dBusTc_write_enable + * - address is in byte, don't care about the 2 LSB + */ +object GenFullWithTcm extends App{ + def config = VexRiscvConfig( + plugins = List( + new IBusCachedPlugin( + prediction = DYNAMIC, + config = InstructionCacheConfig( + cacheSize = 4096, + bytePerLine =32, + wayCount = 1, + addressWidth = 32, + cpuDataWidth = 32, + memDataWidth = 32, + catchIllegalAccess = true, + catchAccessFault = true, + asyncTagMemory = false, + twoCycleRam = true, + twoCycleCache = true + ), + memoryTranslatorPortConfig = MmuPortConfig( + portTlbSize = 4 + ) + ).newTightlyCoupledPort( + TightlyCoupledPortParameter("iBusTc", a => a(31 downto 28) === 0x2) + ), + new DBusCachedPlugin( + config = new DataCacheConfig( + cacheSize = 4096, + bytePerLine = 32, + wayCount = 1, + addressWidth = 32, + cpuDataWidth = 32, + memDataWidth = 32, + catchAccessError = true, + catchIllegal = true, + catchUnaligned = true + ), + memoryTranslatorPortConfig = MmuPortConfig( + portTlbSize = 6 + ) + ).newTightlyCoupledPort( + TightlyCoupledDataPortParameter("dBusTc", a => a(31 downto 28) === 0x3) + ), + new MmuPlugin( + virtualRange = _(31 downto 28) === 0xC, + ioRange = _(31 downto 28) === 0xF + ), + new DecoderSimplePlugin( + catchIllegalInstruction = true + ), + new RegFilePlugin( + regFileReadyKind = plugin.SYNC, + zeroBoot = false + ), + new IntAluPlugin, + new SrcPlugin( + separatedAddSub = false, + executeInsertion = true + ), + new FullBarrelShifterPlugin, + new HazardSimplePlugin( + bypassExecute = true, + bypassMemory = true, + bypassWriteBack = true, + bypassWriteBackBuffer = true, + pessimisticUseSrc = false, + pessimisticWriteRegFile = false, + pessimisticAddressMatch = false + ), + new MulPlugin, + new DivPlugin, + new CsrPlugin(CsrPluginConfig.small(0x80000020l)), + new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))), + new BranchPlugin( + earlyBranch = false, + catchAddressMisaligned = true + ), + new YamlPlugin("cpu0.yaml") + ) + ) + + def cpu() = new VexRiscv( + config + ) + + SpinalVerilog(cpu()) +} diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 593eb91..e32ff96 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -87,6 +87,12 @@ class DBusCachedPlugin(val config : DataCacheConfig, val tightlyCoupledPorts = ArrayBuffer[TightlyCoupledDataPort]() def tightlyGen = tightlyCoupledPorts.nonEmpty + def newTightlyCoupledPort(p: TightlyCoupledDataPortParameter) = { + val port = TightlyCoupledDataPort(p, null) + tightlyCoupledPorts += port + this + } + def newTightlyCoupledPort(mapping : UInt => Bool) = { val port = TightlyCoupledDataPort(TightlyCoupledDataPortParameter(null, mapping), TightlyCoupledDataBus()) tightlyCoupledPorts += port @@ -173,6 +179,9 @@ class DBusCachedPlugin(val config : DataCacheConfig, import Riscv._ import pipeline.config._ + + tightlyCoupledPorts.filter(_.bus == null).foreach(p => p.bus = master(TightlyCoupledDataBus()).setName(p.p.name)) + dBus = master(DataCacheMemBus(this.config)).setName("dBus") val decoderService = pipeline.service(classOf[DecoderService])