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) 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 } } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index c981922..8c681b6 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -23,6 +23,7 @@ class DBusCachedPlugin(val 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(val 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._ @@ -220,6 +222,8 @@ class DBusCachedPlugin(val 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{ @@ -227,7 +231,7 @@ class DBusCachedPlugin(val 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/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) } } diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index cedf989..52097e9 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -396,11 +396,14 @@ class DBusDimension extends VexRiscvDimension("DBus") { var wayCount = 0 val withLrSc = catchAll val withAmo = catchAll && 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) { + 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 = { @@ -416,8 +419,13 @@ class DBusDimension extends VexRiscvDimension("DBus") { catchIllegal = catchAll, catchUnaligned = catchAll, withLrSc = withLrSc, - withAmo = withAmo + withAmo = withAmo, + earlyWaysHits = earlyWaysHits ), + dBusCmdMasterPipe = dBusCmdMasterPipe, + dBusCmdSlavePipe = dBusCmdSlavePipe, + dBusRspSlavePipe = dBusRspSlavePipe, + relaxedMemoryTranslationRegister = relaxedMemoryTranslationRegister, memoryTranslatorPortConfig = mmuConfig ) }