Merge branch 'dev'

This commit is contained in:
Charles Papon 2019-06-16 20:50:43 +02:00
commit 94f1707d65
14 changed files with 215 additions and 55 deletions

View file

@ -100,9 +100,9 @@ VexRiscv full (RV32IM, 1.21 DMIPS/Mhz 2.30 Coremark/Mhz with cache trashing, 4KB
Cyclone IV -> 133 Mhz 2,298 LUT 1,096 FF
VexRiscv full max dmips/mhz -> (RV32IM, 1.44 DMIPS/Mhz 2.70 Coremark/Mhz,, 16KB-I$,16KB-D$, single cycle barrel shifter, debug module, catch exceptions, dynamic branch prediction in the fetch stage, branch and shift operations done in the Execute stage) ->
Artix 7 -> 195 Mhz 1943 LUT 1111 FF
Artix 7 -> 193 Mhz 1758 LUT 1094 FF
Cyclone V -> 90 Mhz 1,089 ALMs
Cyclone IV -> 80 Mhz 2,335 LUT 1,048 FF
Cyclone IV -> 79 Mhz 2,336 LUT 1,048 FF
VexRiscv full with MMU (RV32IM, 1.24 DMIPS/Mhz 2.35 Coremark/Mhz, with cache trashing, 4KB-I$, 4KB-D$, single cycle barrel shifter, debug module, catch exceptions, dynamic branch, MMU) ->
Artix 7 -> 239 Mhz 2029 LUT 1585 FF

View file

@ -7,16 +7,16 @@ lazy val root = (project in file(".")).
version := "2.0.0"
)),
libraryDependencies ++= Seq(
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.5",
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.5",
// "com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.6",
// "com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.6",
"org.scalatest" % "scalatest_2.11" % "2.2.1",
"org.yaml" % "snakeyaml" % "1.8"
),
name := "VexRiscv"
)//.dependsOn(spinalHdlSim,spinalHdlCore,spinalHdlLib)
//lazy val spinalHdlSim = ProjectRef(file("../SpinalHDL"), "sim")
//lazy val spinalHdlCore = ProjectRef(file("../SpinalHDL"), "core")
//lazy val spinalHdlLib = ProjectRef(file("../SpinalHDL"), "lib")
).dependsOn(spinalHdlSim,spinalHdlCore,spinalHdlLib)
lazy val spinalHdlSim = ProjectRef(file("../SpinalHDL"), "sim")
lazy val spinalHdlCore = ProjectRef(file("../SpinalHDL"), "core")
lazy val spinalHdlLib = ProjectRef(file("../SpinalHDL"), "lib")
fork := true

View file

@ -13,7 +13,9 @@ import spinal.lib.com.uart.{Apb3UartCtrl, Uart, UartCtrlGenerics, UartCtrlMemory
import spinal.lib.graphic.RgbConfig
import spinal.lib.graphic.vga.{Axi4VgaCtrl, Axi4VgaCtrlGenerics, Vga}
import spinal.lib.io.TriStateArray
import spinal.lib.memory.sdram.SdramGeneration.SDR
import spinal.lib.memory.sdram._
import spinal.lib.memory.sdram.sdr.{Axi4SharedSdramCtrl, IS42x320D, SdramInterface, SdramTimings}
import spinal.lib.misc.HexTools
import spinal.lib.soc.pinsec.{PinsecTimerCtrl, PinsecTimerCtrlExternal}
import spinal.lib.system.debugger.{JtagAxi4SharedDebugger, JtagBridge, SystemDebugger, SystemDebuggerConfig}
@ -412,6 +414,7 @@ object BrieyDe0Nano{
def main(args: Array[String]) {
object IS42x160G {
def layout = SdramLayout(
generation = SDR,
bankWidth = 2,
columnWidth = 9,
rowWidth = 13,

View file

@ -119,7 +119,12 @@ make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD SUPERVISOR=yes CSR=yes COMPRE
rm -rf cpio
mkdir cpio
cd cpio
cpio -idv < ../rootfs.cpio
sudo cpio -i < ../rootfs.cpio
cd ..
rm rootfs.cpio
cd cpio
sudo find | sudo cpio -H newc -o > ../rootfs.cpio
cd ..
make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes MMU=yes CSR=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=10 TRACE=no COREMARK=yes LINUX_REGRESSION=yes RUN_HEX=~/pro/riscv/zephyr/samples/synchronization/build/zephyr/zephyr.hex

View file

@ -65,7 +65,7 @@ object MuraxConfig{
SpiXdrMasterCtrl.Parameters(8, 12, SpiXdrParameter(2, 2, 1)).addFullDuplex(0,1,false),
cmdFifoDepth = 32,
rspFifoDepth = 32,
xip = SpiXdrMasterCtrl.XipBusParameters(addressWidth = 24, dataWidth = 32)
xip = SpiXdrMasterCtrl.XipBusParameters(addressWidth = 24, lengthWidth = 2)
)),
hardwareBreakpointCount = if(withXip) 3 else 0,
cpuPlugins = ArrayBuffer( //DebugPlugin added by the toplevel
@ -298,13 +298,7 @@ case class Murax(config : MuraxConfig) extends Component{
val accessBus = new PipelinedMemoryBus(PipelinedMemoryBusConfig(24,32))
mainBusMapping += accessBus -> (0xE0000000l, 16 MB)
ctrl.io.xip.cmd.valid <> (accessBus.cmd.valid && !accessBus.cmd.write)
ctrl.io.xip.cmd.ready <> accessBus.cmd.ready
ctrl.io.xip.cmd.payload <> accessBus.cmd.address
ctrl.io.xip.rsp.valid <> accessBus.rsp.valid
ctrl.io.xip.rsp.payload <> accessBus.rsp.data
ctrl.io.xip.fromPipelinedMemoryBus() << accessBus
val bootloader = Apb3Rom("src/main/c/murax/xipBootloader/crt.bin")
apbMapping += bootloader.io.apb -> (0x1E000, 4 kB)
})

View file

@ -12,7 +12,7 @@ import vexriscv.plugin.{DBusSimpleBus, IBusSimpleBus}
class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{
val io = new Bundle{
val iBus = slave(IBusSimpleBus(false))
val iBus = slave(IBusSimpleBus(null))
val dBus = slave(DBusSimpleBus())
val masterBus = master(PipelinedMemoryBus(pipelinedMemoryBusConfig))
}

View file

@ -5,8 +5,10 @@ import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4Shared}
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.bmb.{Bmb, BmbParameter}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import spinal.lib.bus.simple._
import vexriscv.plugin.DBusSimpleBus
case class DataCacheConfig(cacheSize : Int,
@ -64,6 +66,18 @@ case class DataCacheConfig(cacheSize : Int,
useBTE = true,
useCTI = true
)
def getBmbParameter() = BmbParameter(
addressWidth = 32,
dataWidth = 32,
lengthWidth = log2Up(this.bytePerLine),
sourceWidth = 0,
contextWidth = 1,
canRead = true,
canWrite = true,
alignment = BmbParameter.BurstAlignement.LENGTH,
maximumPendingTransactionPerId = Int.MaxValue
)
}
object DataCacheCpuExecute{
@ -298,6 +312,30 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
bus
}
def toBmb() : Bmb = {
val pipelinedMemoryBusConfig = p.getBmbParameter()
val bus = Bmb(pipelinedMemoryBusConfig)
bus.cmd.valid := cmd.valid
bus.cmd.last := cmd.last
bus.cmd.context(0) := cmd.wr
bus.cmd.opcode := (cmd.wr ? B(Bmb.Cmd.Opcode.WRITE) | B(Bmb.Cmd.Opcode.READ))
bus.cmd.address := cmd.address.resized
bus.cmd.data := cmd.data
bus.cmd.length := (cmd.length << 2) | 3 //TODO better sub word access
bus.cmd.mask := cmd.mask
cmd.ready := bus.cmd.ready
rsp.valid := bus.rsp.valid && !bus.rsp.context(0)
rsp.data := bus.rsp.data
rsp.error := bus.rsp.isError
bus.rsp.ready := True
bus
}
}
@ -640,11 +678,13 @@ class DataCache(p : DataCacheConfig) extends Component{
tagsWriteCmd.data.error := error || io.mem.rsp.error
tagsWriteCmd.way := waysAllocator
waysAllocator := (waysAllocator ## waysAllocator.msb).resized
error := False
}
when(!valid){
waysAllocator := (waysAllocator ## waysAllocator.msb).resized
}
io.cpu.redo setWhen(valid)
stageB.mmuRspFreeze setWhen(stageB.loaderValid || valid)
}

View file

@ -5,8 +5,10 @@ import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4ReadOnly}
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.bmb.{Bmb, BmbParameter}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import spinal.lib.bus.simple._
import vexriscv.plugin.{IBusSimpleBus, IBusSimplePlugin}
case class InstructionCacheConfig( cacheSize : Int,
@ -64,6 +66,18 @@ case class InstructionCacheConfig( cacheSize : Int,
useBTE = true,
useCTI = true
)
def getBmbParameter() = BmbParameter(
addressWidth = 32,
dataWidth = 32,
lengthWidth = log2Up(this.bytePerLine),
sourceWidth = 0,
contextWidth = 0,
canRead = true,
canWrite = false,
alignment = BmbParameter.BurstAlignement.LENGTH,
maximumPendingTransactionPerId = 1
)
}
@ -233,6 +247,21 @@ case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle wit
rsp.error := False //TODO
bus
}
def toBmb() : Bmb = {
val busParameter = p.getBmbParameter
val bus = Bmb(busParameter)
bus.cmd.arbitrationFrom(cmd)
bus.cmd.opcode := Bmb.Cmd.Opcode.READ
bus.cmd.address := cmd.address.resized
bus.cmd.length := p.bytePerLine - 1
bus.cmd.last := True
rsp.valid := bus.rsp.valid
rsp.data := bus.rsp.data
rsp.error := bus.rsp.isError
bus.rsp.ready := True
bus
}
}
@ -333,7 +362,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
io.mem.cmd.address := address(tagRange.high downto lineRange.low) @@ U(0,lineRange.low bit)
io.mem.cmd.size := log2Up(p.bytePerLine)
val wayToAllocate = Counter(wayCount, fire)
val wayToAllocate = Counter(wayCount, !valid)
val wordIndex = Reg(UInt(log2Up(memWordPerLine) bits)) init(0)

View file

@ -18,7 +18,7 @@ class DAxiCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
}
}
class DBusCachedPlugin(config : DataCacheConfig,
class DBusCachedPlugin(val config : DataCacheConfig,
memoryTranslatorPortConfig : Any = null,
dBusCmdMasterPipe : Boolean = false,
dBusCmdSlavePipe : Boolean = false,
@ -170,6 +170,14 @@ class DBusCachedPlugin(config : DataCacheConfig,
dBus.cmd << optionPipe(dBusCmdMasterPipe, cmdBuf)(_.m2sPipe())
cache.io.mem.rsp << optionPipe(dBusRspSlavePipe,dBus.rsp)(_.m2sPipe())
pipeline plug new Area{
//Memory bandwidth counter
val rspCounter = RegInit(UInt(32 bits)) init(0)
when(dBus.rsp.valid){
rspCounter := rspCounter + 1
}
}
decode plug new Area {
import decode._

View file

@ -6,6 +6,7 @@ import spinal.lib._
import spinal.lib.bus.amba3.ahblite.{AhbLite3Config, AhbLite3Master}
import spinal.lib.bus.amba4.axi._
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.bmb.{Bmb, BmbParameter}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import spinal.lib.bus.simple._
import vexriscv.ip.DataCacheMemCmd
@ -76,6 +77,17 @@ object DBusSimpleBus{
addressWidth = 32,
dataWidth = 32
)
def getBmbParameter() = BmbParameter(
addressWidth = 32,
dataWidth = 32,
lengthWidth = 2,
sourceWidth = 0,
contextWidth = 1,
canRead = true,
canWrite = true,
alignment = BmbParameter.BurstAlignement.LENGTH,
maximumPendingTransactionPerId = Int.MaxValue
)
}
case class DBusSimpleBus() extends Bundle with IMasterSlave{
@ -208,8 +220,6 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
bus
}
def toAhbLite3Master(avoidWriteToReadHazard : Boolean): AhbLite3Master = {
val bus = AhbLite3Master(DBusSimpleBus.getAhbLite3Config())
bus.HADDR := this.cmd.address
@ -235,6 +245,36 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
this.cmd.ready := False
}
}
bus
}
def toBmb() : Bmb = {
val pipelinedMemoryBusConfig = DBusSimpleBus.getBmbParameter()
val bus = Bmb(pipelinedMemoryBusConfig)
bus.cmd.valid := cmd.valid
bus.cmd.last := True
bus.cmd.context(0) := cmd.wr
bus.cmd.opcode := (cmd.wr ? B(Bmb.Cmd.Opcode.WRITE) | B(Bmb.Cmd.Opcode.READ))
bus.cmd.address := cmd.address.resized
bus.cmd.data := cmd.data
bus.cmd.length := cmd.size.mux(
0 -> U"00",
1 -> U"01",
default -> U"11"
)
bus.cmd.mask := cmd.size.mux(
0 -> B"0001",
1 -> B"0011",
default -> B"1111"
) |<< cmd.address(1 downto 0)
cmd.ready := bus.cmd.ready
rsp.ready := bus.rsp.valid && !bus.rsp.context(0)
rsp.data := bus.rsp.data
rsp.error := bus.rsp.isError
bus.rsp.ready := True
bus
}

View file

@ -262,9 +262,14 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
})
bufferValid clearWhen(output.fire)
val bufferFill = False
when(input.fire){
// bufferValid := !(!isRvc && !input.pc(1) && !bufferValid) && !(isRvc && input.pc(1) && output.ready)
bufferValid := !(!isRvc && !input.pc(1) && !bufferValid) && !(isRvc && input.pc(1) && output.ready)
when(!(!isRvc && !input.pc(1) && !bufferValid) && !(isRvc && input.pc(1) && output.ready)) {
bufferValid := True
bufferFill := True
} otherwise {
bufferValid := False
}
bufferData := input.rsp.inst(31 downto 16)
}
bufferValid.clearWhen(fetcherflushIt)
@ -580,17 +585,15 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val predictionFailure = ifGen(compressedGen && cmdToRspStageCount > 1)(new Area{
val decompressorFailure = RegInit(False)
when(decompressor.input.fire){
decompressorFailure := decompressorContext.hit && !decompressorContext.hazard && !decompressor.output.valid && decompressorContext.line.branchWish(1)
}
decompressorFailure clearWhen(fetcherflushIt || decompressor.output.fire)
val predictionBranch = decompressorContext.hit && !decompressorContext.hazard && decompressorContext.line.branchWish(1)
val unalignedWordIssue = decompressor.bufferFill && decompressor.input.rsp.inst(17 downto 16) === 3 && predictionBranch
val decompressorFailure = RegInit(False) setWhen(unalignedWordIssue) clearWhen(fetcherflushIt)
val injectorFailure = Delay(decompressorFailure, cycleCount=if(injectorStage) 1 else 0, when=injector.decodeInput.ready)
val bypassFailure = if(!injectorStage) False else decompressorFailure && !injector.decodeInput.valid
dynamicTargetFailureCorrection.valid := False
dynamicTargetFailureCorrection.payload := decode.input(PC)
when(injector.decodeInput.valid && injectorFailure){
when(injectorFailure || bypassFailure){
historyWrite.valid := True
historyWrite.address := (decode.input(PC) >> 2).resized
historyWrite.data.branchWish := 0

View file

@ -31,7 +31,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
historyRamSizeLog2 : Int = 10,
compressedGen : Boolean = false,
keepPcPlus4 : Boolean = false,
config : InstructionCacheConfig,
val config : InstructionCacheConfig,
memoryTranslatorPortConfig : Any = null,
injectorStage : Boolean = false,
withoutInjectorStage : Boolean = false,
@ -129,7 +129,13 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
iBus = master(new InstructionCacheMemBus(IBusCachedPlugin.this.config)).setName("iBus")
iBus <> cache.io.mem
iBus.cmd.address.allowOverride := cache.io.mem.cmd.address
//Memory bandwidth counter
val rspCounter = RegInit(UInt(32 bits)) init(0)
when(iBus.rsp.valid){
rspCounter := rspCounter + 1
}
val stageOffset = if(relaxedPcCalculation) 1 else 0
def stages = iBusRsp.stages.drop(stageOffset)

View file

@ -6,6 +6,7 @@ import spinal.lib._
import spinal.lib.bus.amba3.ahblite.{AhbLite3, AhbLite3Config, AhbLite3Master}
import spinal.lib.bus.amba4.axi._
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.bmb.{Bmb, BmbParameter}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import spinal.lib.bus.simple._
import vexriscv.Riscv.{FENCE, FENCE_I}
@ -67,14 +68,27 @@ object IBusSimpleBus{
dataWidth = 32
)
def getAhbLite3Config() = AhbLite3Config(
addressWidth = 32,
dataWidth = 32
)
def getBmbParameter(plugin : IBusSimplePlugin = null) = BmbParameter(
addressWidth = 32,
dataWidth = 32,
lengthWidth = 2,
sourceWidth = 0,
contextWidth = 0,
canRead = true,
canWrite = false,
alignment = BmbParameter.BurstAlignement.LENGTH,
maximumPendingTransactionPerId = if(plugin != null) plugin.pendingMax else Int.MaxValue
)
}
case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with IMasterSlave {
case class IBusSimpleBus(plugin: IBusSimplePlugin) extends Bundle with IMasterSlave {
var cmd = Stream(IBusSimpleCmd())
var rsp = Flow(IBusSimpleRsp())
@ -85,7 +99,7 @@ case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with
def cmdS2mPipe() : IBusSimpleBus = {
val s = IBusSimpleBus()
val s = IBusSimpleBus(plugin)
s.cmd << this.cmd.s2mPipe()
this.rsp << s.rsp
s
@ -93,7 +107,7 @@ case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with
def toAxi4ReadOnly(): Axi4ReadOnly = {
assert(cmdIsPersistente)
assert(plugin.cmdForkPersistence)
val axi = Axi4ReadOnly(IBusSimpleBus.getAxi4Config())
axi.ar.valid := cmd.valid
@ -112,7 +126,7 @@ case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with
}
def toAvalon(): AvalonMM = {
assert(cmdIsPersistente)
assert(plugin.cmdForkPersistence)
val avalonConfig = IBusSimpleBus.getAvalonConfig()
val mm = AvalonMM(avalonConfig)
@ -163,6 +177,7 @@ case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with
bus
}
//cmdForkPersistence need to bet set
def toAhbLite3Master(): AhbLite3Master = {
val bus = AhbLite3Master(IBusSimpleBus.getAhbLite3Config())
@ -182,6 +197,21 @@ case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with
this.rsp.error := bus.HRESP
bus
}
def toBmb() : Bmb = {
val pipelinedMemoryBusConfig = IBusSimpleBus.getBmbParameter(plugin)
val bus = Bmb(pipelinedMemoryBusConfig)
bus.cmd.arbitrationFrom(cmd)
bus.cmd.opcode := Bmb.Cmd.Opcode.READ
bus.cmd.address := cmd.pc.resized
bus.cmd.length := 3
bus.cmd.last := True
rsp.valid := bus.rsp.valid
rsp.inst := bus.rsp.data
rsp.error := bus.rsp.isError
bus.rsp.ready := True
bus
}
}
@ -189,21 +219,21 @@ case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with
class IBusSimplePlugin(resetVector : BigInt,
cmdForkOnSecondStage : Boolean,
cmdForkPersistence : Boolean,
catchAccessFault : Boolean = false,
prediction : BranchPrediction = NONE,
historyRamSizeLog2 : Int = 10,
keepPcPlus4 : Boolean = false,
compressedGen : Boolean = false,
busLatencyMin : Int = 1,
pendingMax : Int = 7,
injectorStage : Boolean = true,
rspHoldValue : Boolean = false,
singleInstructionPipeline : Boolean = false,
memoryTranslatorPortConfig : Any = null,
relaxPredictorAddress : Boolean = true
class IBusSimplePlugin( resetVector : BigInt,
val cmdForkOnSecondStage : Boolean,
val cmdForkPersistence : Boolean,
val catchAccessFault : Boolean = false,
prediction : BranchPrediction = NONE,
historyRamSizeLog2 : Int = 10,
keepPcPlus4 : Boolean = false,
compressedGen : Boolean = false,
val busLatencyMin : Int = 1,
val pendingMax : Int = 7,
injectorStage : Boolean = true,
val rspHoldValue : Boolean = false,
val singleInstructionPipeline : Boolean = false,
val memoryTranslatorPortConfig : Any = null,
relaxPredictorAddress : Boolean = true
) extends IBusFetcherImpl(
resetVector = resetVector,
keepPcPlus4 = keepPcPlus4,
@ -227,7 +257,7 @@ class IBusSimplePlugin(resetVector : BigInt,
override def setup(pipeline: VexRiscv): Unit = {
super.setup(pipeline)
iBus = master(IBusSimpleBus(cmdForkPersistence)).setName("iBus")
iBus = master(IBusSimpleBus(this)).setName("iBus")
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.add(FENCE_I, Nil)

View file

@ -112,8 +112,10 @@ ifneq ($(shell grep timerInterrupt ../../../../VexRiscv.v -w),)
endif
ifneq ($(shell grep externalInterrupt ../../../../VexRiscv.v -w),)
ifneq ($(EXTERNAL_INTERRUPT),no)
ADDCFLAGS += -CFLAGS -DEXTERNAL_INTERRUPT
endif
endif
ifneq ($(RUN_HEX),no)
ADDCFLAGS += -CFLAGS -DRUN_HEX='\"$(RUN_HEX)\"'