Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	build.sbt
#	src/main/scala/vexriscv/Riscv.scala
#	src/main/scala/vexriscv/ip/DataCache.scala
#	src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala
#	src/main/scala/vexriscv/plugin/MmuPlugin.scala
#	src/test/cpp/regression/makefile
#	src/test/scala/vexriscv/TestIndividualFeatures.scala
  • Loading branch information
Dolu1990 committed Jan 30, 2021
2 parents d6e8a5e + 50a69d8 commit 6aa6191
Show file tree
Hide file tree
Showing 32 changed files with 1,053 additions and 98 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ Note that sometimes Eclipse needs to be restarted in order to be able to place n

## Briey SoC
As a demonstration, a SoC named Briey is implemented in `src/main/scala/vexriscv/demo/Briey.scala`. This SoC is very similar to
the [Pinsec SoC](https://spinalhdl.github.io/SpinalDoc/spinal/lib/pinsec/hardware/):
the [Pinsec SoC](https://spinalhdl.github.io/SpinalDoc-RTD/SpinalHDL/Legacy/pinsec/hardware_toplevel.html#):

![Briey SoC](assets/brieySoc.png?raw=true "")

Expand All @@ -296,7 +296,7 @@ sbt "runMain vexriscv.demo.Briey"
To run the verilator simulation of the Briey SoC, which can then be connected to OpenOCD/GDB, first get these dependencies:

```sh
sudo apt-get install build-essential xorg-dev libudev-dev libts-dev libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libpulse-dev libopenal-dev libogg-dev libvorbis-dev libaudiofile-dev libpng12-dev libfreetype6-dev libusb-dev libdbus-1-dev zlib1g-dev libdirectfb-dev libsdl2-dev
sudo apt-get install build-essential xorg-dev libudev-dev libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libpulse-dev libopenal-dev libogg-dev libvorbis-dev libaudiofile-dev libpng12-dev libfreetype6-dev libusb-dev libdbus-1-dev zlib1g-dev libdirectfb-dev libsdl2-dev
```

Then go in `src/test/cpp/briey` and run the simulation with (UART TX is printed in the terminal, VGA is displayed in a GUI):
Expand Down Expand Up @@ -412,7 +412,7 @@ Note that VexRiscv can run Linux on both cache full and cache less design.

A prebuild GCC toolsuite can be found here:

- https://www.sifive.com/products/tools/ => SiFive GNU Embedded Toolchain
- https://www.sifive.com/software/ => Prebuilt RISC‑V GCC Toolchain and Emulator

The VexRiscvSocSoftware makefiles are expecting to find this prebuild version in /opt/riscv/__contentOfThisPreBuild__

Expand Down
3 changes: 3 additions & 0 deletions scripts/regression/regression.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ regression_random_linux:
cd ../..
export VEXRISCV_REGRESSION_CONFIG_COUNT=3
export VEXRISCV_REGRESSION_CONFIG_LINUX_RATE=1.0
export VEXRISCV_REGRESSION_CONFIG_SECURE_RATE = 0.0
export VEXRISCV_REGRESSION_FREERTOS_COUNT=1
export VEXRISCV_REGRESSION_ZEPHYR_COUNT=2
export VEXRISCV_REGRESSION_THREAD_COUNT=1
Expand All @@ -24,6 +25,7 @@ regression_random_machine_os:
export VEXRISCV_REGRESSION_CONFIG_COUNT=15
export VEXRISCV_REGRESSION_CONFIG_LINUX_RATE=0.0
export VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE=1.0
export VEXRISCV_REGRESSION_CONFIG_SECURE_RATE = 0.0
export VEXRISCV_REGRESSION_FREERTOS_COUNT=1
export VEXRISCV_REGRESSION_ZEPHYR_COUNT=2
export VEXRISCV_REGRESSION_THREAD_COUNT=1
Expand All @@ -34,6 +36,7 @@ regression_random_baremetal:
export VEXRISCV_REGRESSION_CONFIG_COUNT=40
export VEXRISCV_REGRESSION_CONFIG_LINUX_RATE=0.0
export VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE=0.0
export VEXRISCV_REGRESSION_CONFIG_SECURE_RATE = 0.0
export VEXRISCV_REGRESSION_FREERTOS_COUNT=1
export VEXRISCV_REGRESSION_ZEPHYR_COUNT=no
export VEXRISCV_REGRESSION_THREAD_COUNT=1
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/vexriscv/Riscv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ object Riscv{
def UCYCLEH = 0xC80
def UTIME = 0xC01 // rdtime
def UTIMEH = 0xC81

def UINSTRET = 0xC02 // UR Machine instructions-retired counter.
def UINSTRETH = 0xC82 // UR Upper 32 bits of minstret, RV32I only.
}
}
1 change: 1 addition & 0 deletions src/main/scala/vexriscv/Services.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ case class MemoryTranslatorCmd() extends Bundle{
case class MemoryTranslatorRsp(p : MemoryTranslatorBusParameter) extends Bundle{
val physicalAddress = UInt(32 bits)
val isIoAccess = Bool
val isPaging = Bool
val allowRead, allowWrite, allowExecute = Bool
val exception = Bool
val refilling = Bool
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/vexriscv/demo/Briey.scala
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ object BrieyConfig{
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
86 changes: 86 additions & 0 deletions src/main/scala/vexriscv/demo/GenSecure.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package vexriscv.demo

import vexriscv.plugin._
import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig}
import vexriscv.{plugin, VexRiscv, VexRiscvConfig}
import spinal.core._

object GenSecure extends App {
def cpu() = new VexRiscv(
config = VexRiscvConfig(
plugins = List(
new IBusCachedPlugin(
resetVector = 0x80000000l,
prediction = STATIC,
config = InstructionCacheConfig(
cacheSize = 4096,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true
)
),
new DBusCachedPlugin(
config = new DataCacheConfig(
cacheSize = 4096,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchAccessError = true,
catchIllegal = true,
catchUnaligned = true
)
),
new PmpPlugin(
regions = 16,
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 MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 1,
divUnrollFactor = 1
),
new CsrPlugin(CsrPluginConfig.secure(0x00000020l)),
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin(
earlyBranch = false,
catchAddressMisaligned = true
),
new YamlPlugin("cpu0.yaml")
)
)
)

SpinalVerilog(cpu())
}
17 changes: 11 additions & 6 deletions src/main/scala/vexriscv/demo/Murax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ case class MuraxConfig(coreFrequency : HertzNumber,


object MuraxConfig{
def default : MuraxConfig = default(false)
def default(withXip : Boolean) = MuraxConfig(
def default : MuraxConfig = default(false, false)
def default(withXip : Boolean = false, bigEndian : Boolean = false) = MuraxConfig(
coreFrequency = 12 MHz,
onChipRamSize = 8 kB,
onChipRamHexFile = null,
Expand All @@ -75,12 +75,14 @@ object MuraxConfig{
cmdForkPersistence = withXip, //Required by the Xip controller
prediction = NONE,
catchAccessFault = false,
compressedGen = false
compressedGen = false,
bigEndian = bigEndian
),
new DBusSimplePlugin(
catchAddressMisaligned = false,
catchAccessFault = false,
earlyInjection = false
earlyInjection = false,
bigEndian = bigEndian
),
new CsrPlugin(CsrPluginConfig.smallest(mtvecInit = if(withXip) 0xE0040020l else 0x80000020l)),
new DecoderSimplePlugin(
Expand Down Expand Up @@ -214,9 +216,11 @@ case class Murax(config : MuraxConfig) extends Component{
dataWidth = 32
)

val bigEndianDBus = config.cpuPlugins.exists(_ match{ case plugin : DBusSimplePlugin => plugin.bigEndian case _ => false})

//Arbiter of the cpu dBus/iBus to drive the mainBus
//Priority to dBus, !! cmd transactions can change on the fly !!
val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig)
val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig, bigEndianDBus)

//Instanciate the CPU
val cpu = new VexRiscv(
Expand Down Expand Up @@ -258,7 +262,8 @@ case class Murax(config : MuraxConfig) extends Component{
val ram = new MuraxPipelinedMemoryBusRam(
onChipRamSize = onChipRamSize,
onChipRamHexFile = onChipRamHexFile,
pipelinedMemoryBusConfig = pipelinedMemoryBusConfig
pipelinedMemoryBusConfig = pipelinedMemoryBusConfig,
bigEndian = bigEndianDBus
)
mainBusMapping += ram.io.bus -> (0x80000000l, onChipRamSize)

Expand Down
20 changes: 12 additions & 8 deletions src/main/scala/vexriscv/demo/MuraxUtiles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,18 @@ import spinal.lib._
import spinal.lib.bus.simple._
import vexriscv.plugin.{DBusSimpleBus, IBusSimpleBus}

class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{
class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig, bigEndian : Boolean = false) extends Component{
val io = new Bundle{
val iBus = slave(IBusSimpleBus(null))
val dBus = slave(DBusSimpleBus())
val dBus = slave(DBusSimpleBus(bigEndian))
val masterBus = master(PipelinedMemoryBus(pipelinedMemoryBusConfig))
}

io.masterBus.cmd.valid := io.iBus.cmd.valid || io.dBus.cmd.valid
io.masterBus.cmd.write := io.dBus.cmd.valid && io.dBus.cmd.wr
io.masterBus.cmd.address := io.dBus.cmd.valid ? io.dBus.cmd.address | io.iBus.cmd.pc
io.masterBus.cmd.data := io.dBus.cmd.data
io.masterBus.cmd.mask := io.dBus.cmd.size.mux(
0 -> B"0001",
1 -> B"0011",
default -> B"1111"
) |<< io.dBus.cmd.address(1 downto 0)
io.masterBus.cmd.mask := io.dBus.genMask(io.dBus.cmd)
io.iBus.cmd.ready := io.masterBus.cmd.ready && !io.dBus.cmd.valid
io.dBus.cmd.ready := io.masterBus.cmd.ready

Expand Down Expand Up @@ -53,7 +49,7 @@ class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) ex
}


case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{
case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, pipelinedMemoryBusConfig : PipelinedMemoryBusConfig, bigEndian : Boolean = false) extends Component{
val io = new Bundle{
val bus = slave(PipelinedMemoryBus(pipelinedMemoryBusConfig))
}
Expand All @@ -71,6 +67,14 @@ case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile :

if(onChipRamHexFile != null){
HexTools.initRam(ram, onChipRamHexFile, 0x80000000l)
if(bigEndian)
// HexTools.initRam (incorrectly) assumes little endian byte ordering
for((word, wordIndex) <- ram.initialContent.zipWithIndex)
ram.initialContent(wordIndex) =
((word & 0xffl) << 24) |
((word & 0xff00l) << 8) |
((word & 0xff0000l) >> 8) |
((word & 0xff000000l) >> 24)
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ object VexRiscvAhbLite3{
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ object VexRiscvAvalonForSim{
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ object VexRiscvAvalonWithIntegratedJtag{
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ object VexRiscvAxi4WithIntegratedJtag{
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
8 changes: 6 additions & 2 deletions src/main/scala/vexriscv/ip/DataCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -890,12 +890,16 @@ class DataCache(val p : DataCacheConfig, mmuParameter : MemoryTranslatorBusParam
dataWriteCmd.way := waysHits
}

val badPermissions = (!mmuRsp.allowWrite && request.wr) || (!mmuRsp.allowRead && (!request.wr || isAmo))
val loadStoreFault = io.cpu.writeBack.isValid && (mmuRsp.exception || badPermissions)

io.cpu.redo := False
io.cpu.writeBack.accessError := False
io.cpu.writeBack.mmuException := io.cpu.writeBack.isValid && (if(catchIllegal) mmuRsp.exception || (!mmuRsp.allowWrite && request.wr) || (!mmuRsp.allowRead && (!request.wr || isAmo)) else False)
io.cpu.writeBack.mmuException := loadStoreFault && (if(catchIllegal) mmuRsp.isPaging else False)
io.cpu.writeBack.unalignedAccess := io.cpu.writeBack.isValid && unaligned
io.cpu.writeBack.isWrite := request.wr


io.mem.cmd.valid := False
io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto cpuWordRange.low) @@ U(0, cpuWordRange.low bits)
io.mem.cmd.length := 0
Expand Down Expand Up @@ -1002,7 +1006,7 @@ class DataCache(val p : DataCacheConfig, mmuParameter : MemoryTranslatorBusParam
if(catchAccessError) io.cpu.writeBack.accessError := !request.wr && isLast && io.mem.rsp.valid && io.mem.rsp.error
} otherwise {
io.cpu.writeBack.data := dataMux
if(catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0
if(catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0 || (loadStoreFault && !mmuRsp.isPaging)
}

if(withLrSc) when(request.isLrsc && request.wr){
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/vexriscv/ip/InstructionCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,9 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
val mmuRsp = io.cpu.fetch.mmuRsp

io.cpu.fetch.cacheMiss := !hit.valid
io.cpu.fetch.error := hit.error
io.cpu.fetch.error := hit.error || (!mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute))
io.cpu.fetch.mmuRefilling := mmuRsp.refilling
io.cpu.fetch.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute)
io.cpu.fetch.mmuException := !mmuRsp.refilling && mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute)
})
}

Expand Down Expand Up @@ -478,9 +478,9 @@ class InstructionCache(p : InstructionCacheConfig, mmuParameter : MemoryTranslat
}

io.cpu.decode.cacheMiss := !hit.valid
io.cpu.decode.error := hit.error
io.cpu.decode.error := hit.error || (!mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute))
io.cpu.decode.mmuRefilling := mmuRsp.refilling
io.cpu.decode.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute)
io.cpu.decode.mmuException := !mmuRsp.refilling && mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute)
io.cpu.decode.physicalAddress := mmuRsp.physicalAddress
})
}
Expand Down
Loading

0 comments on commit 6aa6191

Please sign in to comment.