From 5f187053584da0ff522ecf68082bdce7bd88c780 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sun, 5 May 2019 21:19:48 +0200 Subject: [PATCH 1/8] Add DBusCachedPlugin.relaxedMemoryTranslationRegister option --- src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala | 6 +++++- src/test/scala/vexriscv/TestIndividualFeatures.scala | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index b8f2ba1..8584a8c 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -23,6 +23,7 @@ class DBusCachedPlugin(config : DataCacheConfig, dBusCmdMasterPipe : Boolean = false, dBusCmdSlavePipe : Boolean = false, dBusRspSlavePipe : Boolean = false, + relaxedMemoryTranslationRegister : Boolean = false, csrInfo : Boolean = false) extends Plugin[VexRiscv] with DBusAccessService { import config._ @@ -49,6 +50,7 @@ class DBusCachedPlugin(config : DataCacheConfig, object MEMORY_LRSC extends Stageable(Bool) object MEMORY_AMO extends Stageable(Bool) object IS_DBUS_SHARING extends Stageable(Bool()) + object MEMORY_VIRTUAL_ADDRESS extends Stageable(UInt(32 bits)) override def setup(pipeline: VexRiscv): Unit = { import Riscv._ @@ -212,6 +214,8 @@ class DBusCachedPlugin(config : DataCacheConfig, when(cache.io.cpu.redo && arbitration.isValid && input(MEMORY_ENABLE)){ arbitration.haltItself := True } + + if(relaxedMemoryTranslationRegister) insert(MEMORY_VIRTUAL_ADDRESS) := cache.io.cpu.execute.address } memory plug new Area{ @@ -219,7 +223,7 @@ class DBusCachedPlugin(config : DataCacheConfig, cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.memory.isStuck := arbitration.isStuck cache.io.cpu.memory.isRemoved := arbitration.removeIt - cache.io.cpu.memory.address := U(input(REGFILE_WRITE_DATA)) + cache.io.cpu.memory.address := (if(relaxedMemoryTranslationRegister) input(MEMORY_VIRTUAL_ADDRESS) else U(input(REGFILE_WRITE_DATA))) cache.io.cpu.memory.mmuBus <> mmuBus cache.io.cpu.memory.mmuBus.rsp.isIoAccess setWhen(pipeline(DEBUG_BYPASS_CACHE) && !cache.io.cpu.memory.isWrite) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index cedf989..03cf8ee 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -396,11 +396,13 @@ class DBusDimension extends VexRiscvDimension("DBus") { var wayCount = 0 val withLrSc = catchAll val withAmo = catchAll && r.nextBoolean() + val dBusCmdMasterPipe, dBusCmdSlavePipe, dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean() + do{ cacheSize = 512 << r.nextInt(5) wayCount = 1 << r.nextInt(3) }while(cacheSize/wayCount < 512 || (catchAll && cacheSize/wayCount > 4096)) - new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine) { + new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(dBusCmdMasterPipe) "Cmp " else "") + (if(dBusCmdSlavePipe) "Csp " else "") + (if(dBusRspSlavePipe) "Rsp " else "") + (if(relaxedMemoryTranslationRegister) "Rmtr " else "")) { override def testParam = "DBUS=CACHED " + (if(withLrSc) "LRSC=yes " else "") + (if(withAmo) "AMO=yes " else "") override def applyOn(config: VexRiscvConfig): Unit = { @@ -418,6 +420,10 @@ class DBusDimension extends VexRiscvDimension("DBus") { withLrSc = withLrSc, withAmo = withAmo ), + dBusCmdMasterPipe = dBusCmdMasterPipe, + dBusCmdSlavePipe = dBusCmdSlavePipe, + dBusRspSlavePipe = dBusRspSlavePipe, + relaxedMemoryTranslationRegister = relaxedMemoryTranslationRegister, memoryTranslatorPortConfig = mmuConfig ) } From 8f1b980337ef881ac03f6748c63ac1cb7bbdfc1f Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sun, 5 May 2019 22:29:33 +0200 Subject: [PATCH 2/8] Revert "Add DBusCachedPlugin.relaxedMemoryTranslationRegister option" This reverts commit 5f187053584da0ff522ecf68082bdce7bd88c780. --- src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala | 6 +----- src/test/scala/vexriscv/TestIndividualFeatures.scala | 8 +------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 8584a8c..b8f2ba1 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -23,7 +23,6 @@ class DBusCachedPlugin(config : DataCacheConfig, dBusCmdMasterPipe : Boolean = false, dBusCmdSlavePipe : Boolean = false, dBusRspSlavePipe : Boolean = false, - relaxedMemoryTranslationRegister : Boolean = false, csrInfo : Boolean = false) extends Plugin[VexRiscv] with DBusAccessService { import config._ @@ -50,7 +49,6 @@ class DBusCachedPlugin(config : DataCacheConfig, object MEMORY_LRSC extends Stageable(Bool) object MEMORY_AMO extends Stageable(Bool) object IS_DBUS_SHARING extends Stageable(Bool()) - object MEMORY_VIRTUAL_ADDRESS extends Stageable(UInt(32 bits)) override def setup(pipeline: VexRiscv): Unit = { import Riscv._ @@ -214,8 +212,6 @@ class DBusCachedPlugin(config : DataCacheConfig, when(cache.io.cpu.redo && arbitration.isValid && input(MEMORY_ENABLE)){ arbitration.haltItself := True } - - if(relaxedMemoryTranslationRegister) insert(MEMORY_VIRTUAL_ADDRESS) := cache.io.cpu.execute.address } memory plug new Area{ @@ -223,7 +219,7 @@ class DBusCachedPlugin(config : DataCacheConfig, cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.memory.isStuck := arbitration.isStuck cache.io.cpu.memory.isRemoved := arbitration.removeIt - cache.io.cpu.memory.address := (if(relaxedMemoryTranslationRegister) input(MEMORY_VIRTUAL_ADDRESS) else U(input(REGFILE_WRITE_DATA))) + cache.io.cpu.memory.address := U(input(REGFILE_WRITE_DATA)) cache.io.cpu.memory.mmuBus <> mmuBus cache.io.cpu.memory.mmuBus.rsp.isIoAccess setWhen(pipeline(DEBUG_BYPASS_CACHE) && !cache.io.cpu.memory.isWrite) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 03cf8ee..cedf989 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -396,13 +396,11 @@ class DBusDimension extends VexRiscvDimension("DBus") { var wayCount = 0 val withLrSc = catchAll val withAmo = catchAll && r.nextBoolean() - val dBusCmdMasterPipe, dBusCmdSlavePipe, dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean() - do{ cacheSize = 512 << r.nextInt(5) wayCount = 1 << r.nextInt(3) }while(cacheSize/wayCount < 512 || (catchAll && cacheSize/wayCount > 4096)) - new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(dBusCmdMasterPipe) "Cmp " else "") + (if(dBusCmdSlavePipe) "Csp " else "") + (if(dBusRspSlavePipe) "Rsp " else "") + (if(relaxedMemoryTranslationRegister) "Rmtr " else "")) { + new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine) { override def testParam = "DBUS=CACHED " + (if(withLrSc) "LRSC=yes " else "") + (if(withAmo) "AMO=yes " else "") override def applyOn(config: VexRiscvConfig): Unit = { @@ -420,10 +418,6 @@ class DBusDimension extends VexRiscvDimension("DBus") { withLrSc = withLrSc, withAmo = withAmo ), - dBusCmdMasterPipe = dBusCmdMasterPipe, - dBusCmdSlavePipe = dBusCmdSlavePipe, - dBusRspSlavePipe = dBusRspSlavePipe, - relaxedMemoryTranslationRegister = relaxedMemoryTranslationRegister, memoryTranslatorPortConfig = mmuConfig ) } From d12decde800c24cbd216a0b4611f540a524eaa4b Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sun, 5 May 2019 22:46:46 +0200 Subject: [PATCH 3/8] Remove test which had issues with the testbench ref checks because of getting passed delayed --- src/test/scala/vexriscv/TestIndividualFeatures.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 03cf8ee..d24f239 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -396,7 +396,8 @@ class DBusDimension extends VexRiscvDimension("DBus") { var wayCount = 0 val withLrSc = catchAll val withAmo = catchAll && r.nextBoolean() - val dBusCmdMasterPipe, dBusCmdSlavePipe, dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean() + val dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean() + val dBusCmdMasterPipe, dBusCmdSlavePipe = false //As it create test bench issues do{ cacheSize = 512 << r.nextInt(5) From d27fa4766d99cef3043c57afc3b3a17d642c6a98 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Mon, 6 May 2019 00:05:40 +0200 Subject: [PATCH 4/8] DBusCachedPlugin add earlyWaysHits in regressions --- src/test/scala/vexriscv/TestIndividualFeatures.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index d24f239..52097e9 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -396,14 +396,14 @@ class DBusDimension extends VexRiscvDimension("DBus") { var wayCount = 0 val withLrSc = catchAll val withAmo = catchAll && r.nextBoolean() - val dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean() + val dBusRspSlavePipe, relaxedMemoryTranslationRegister, earlyWaysHits = r.nextBoolean() val dBusCmdMasterPipe, dBusCmdSlavePipe = false //As it create test bench issues do{ cacheSize = 512 << r.nextInt(5) wayCount = 1 << r.nextInt(3) }while(cacheSize/wayCount < 512 || (catchAll && cacheSize/wayCount > 4096)) - new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(dBusCmdMasterPipe) "Cmp " else "") + (if(dBusCmdSlavePipe) "Csp " else "") + (if(dBusRspSlavePipe) "Rsp " else "") + (if(relaxedMemoryTranslationRegister) "Rmtr " else "")) { + new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount + "BPL" + bytePerLine + (if(dBusCmdMasterPipe) "Cmp " else "") + (if(dBusCmdSlavePipe) "Csp " else "") + (if(dBusRspSlavePipe) "Rsp " else "") + (if(relaxedMemoryTranslationRegister) "Rmtr " else "") + (if(earlyWaysHits) "Ewh " else "")) { override def testParam = "DBUS=CACHED " + (if(withLrSc) "LRSC=yes " else "") + (if(withAmo) "AMO=yes " else "") override def applyOn(config: VexRiscvConfig): Unit = { @@ -419,7 +419,8 @@ class DBusDimension extends VexRiscvDimension("DBus") { catchIllegal = catchAll, catchUnaligned = catchAll, withLrSc = withLrSc, - withAmo = withAmo + withAmo = withAmo, + earlyWaysHits = earlyWaysHits ), dBusCmdMasterPipe = dBusCmdMasterPipe, dBusCmdSlavePipe = dBusCmdSlavePipe, From 01db217ab927dd1f415f28d6ac726edb73ae2ee0 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Mon, 6 May 2019 16:23:43 +0200 Subject: [PATCH 5/8] Add supervisor support in the ExternalInterruptArrayPlugin --- .../scala/vexriscv/plugin/CsrPlugin.scala | 2 +- .../plugin/ExternalInterruptArrayPlugin.scala | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 3c7b036..467dc76 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -310,7 +310,7 @@ trait IContextSwitching{ def isContextSwitching : Bool } -class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor with ExceptionInhibitor with IContextSwitching with CsrInterface{ +class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor with ExceptionInhibitor with IContextSwitching with CsrInterface{ import config._ import CsrAccess._ diff --git a/src/main/scala/vexriscv/plugin/ExternalInterruptArrayPlugin.scala b/src/main/scala/vexriscv/plugin/ExternalInterruptArrayPlugin.scala index fd1a561..43d32f0 100644 --- a/src/main/scala/vexriscv/plugin/ExternalInterruptArrayPlugin.scala +++ b/src/main/scala/vexriscv/plugin/ExternalInterruptArrayPlugin.scala @@ -3,7 +3,11 @@ package vexriscv.plugin import spinal.core._ import vexriscv.VexRiscv -class ExternalInterruptArrayPlugin(arrayWidth : Int = 32, maskCsrId : Int = 0xBC0, pendingsCsrId : Int = 0xFC0) extends Plugin[VexRiscv]{ +class ExternalInterruptArrayPlugin(arrayWidth : Int = 32, + machineMaskCsrId : Int = 0xBC0, + machinePendingsCsrId : Int = 0xFC0, + supervisorMaskCsrId : Int = 0x9C0, + supervisorPendingsCsrId : Int = 0xDC0) extends Plugin[VexRiscv]{ var externalInterruptArray : Bits = null override def setup(pipeline: VexRiscv): Unit = { @@ -12,10 +16,15 @@ class ExternalInterruptArrayPlugin(arrayWidth : Int = 32, maskCsrId : Int = 0xBC override def build(pipeline: VexRiscv): Unit = { val csr = pipeline.service(classOf[CsrPlugin]) - val mask = Reg(Bits(arrayWidth bits)) init(0) - val pendings = mask & RegNext(externalInterruptArray) - csr.externalInterrupt.setAsDirectionLess() := pendings.orR - csr.rw(maskCsrId, mask) - csr.r(pendingsCsrId, pendings) + val externalInterruptArrayBuffer = RegNext(externalInterruptArray) + def gen(maskCsrId : Int, pendingsCsrId : Int, interruptPin : Bool) = new Area { + val mask = Reg(Bits(arrayWidth bits)) init(0) + val pendings = mask & externalInterruptArrayBuffer + interruptPin.setAsDirectionLess() := pendings.orR + csr.rw(maskCsrId, mask) + csr.r(pendingsCsrId, pendings) + } + gen(machineMaskCsrId, machinePendingsCsrId, csr.externalInterrupt) + if(csr.config.supervisorGen) gen(supervisorMaskCsrId, supervisorPendingsCsrId, csr.externalInterruptS) } } From b40dc06b2942d17a08a9268f3d135cb0c6d6e4f2 Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Sat, 18 May 2019 19:56:03 +0200 Subject: [PATCH 6/8] SpinalHDL 1.3.5 --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 1db0792..82b7e08 100644 --- a/build.sbt +++ b/build.sbt @@ -7,8 +7,8 @@ lazy val root = (project in file(".")). version := "2.0.0" )), libraryDependencies ++= Seq( - "com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.4", - "com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.4", + "com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.5", + "com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.5", "org.scalatest" % "scalatest_2.11" % "2.2.1", "org.yaml" % "snakeyaml" % "1.8" ), From 64e8919e89ed647c4bea87be27bf3e5f2ce72a6b Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 28 May 2019 11:28:07 +0200 Subject: [PATCH 7/8] Update README.md Add litex repo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6f56ac..3fbfef0 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ This repository hosts a RISC-V implementation written in SpinalHDL. Here are som - Optional interrupts and exception handling with Machine, [Supervisor] and [User] modes as defined in the [RISC-V Privileged ISA Specification v1.10](https://riscv.org/specifications/privileged-isa/). - Two implementations of shift instructions: Single cycle and shiftNumber cycles - Each stage can have optional bypass or interlock hazard logic -- Linux compatible +- Linux compatible (SoC : https://github.com/enjoy-digital/linux-on-litex-vexriscv) - Zephyr compatible - [FreeRTOS port](https://github.com/Dolu1990/FreeRTOS-RISCV) From 56f7c27d18589f10d143e9e615eb4fc06f10376d Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Wed, 5 Jun 2019 00:32:38 +0200 Subject: [PATCH 8/8] Fix WFI. Not sensitive anymore to global interrupt enables, delegation and privilege --- src/main/scala/vexriscv/plugin/CsrPlugin.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 467dc76..5f81f6f 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -879,9 +879,10 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep import execute._ //Manage WFI instructions val inWfi = False.addTag(Verilator.public) + val wfiWake = RegNext(interruptSpecs.map(_.cond).orR) init(False) if(wfiGenAsWait) when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.WFI){ inWfi := True - when(!interrupt){ + when(!wfiWake){ arbitration.haltItself := True } }