Merge remote-tracking branch 'origin/master' into reworkFetcher

Conflicts:
	src/main/scala/vexriscv/plugin/PcManagerSimplePlugin.scala
	src/test/cpp/regression/main.cpp
This commit is contained in:
Dolu1990 2018-05-24 14:04:01 +02:00
commit 9815763b7f
16 changed files with 983 additions and 72 deletions

60
.travis.yml Normal file
View File

@ -0,0 +1,60 @@
language: scala
notifications:
email:
on_success: never
# See 'project/Version.scala'
scala:
- 2.11.6
sbt_args: -no-colors -J-Xss2m
script:
- sbt -jvm-opts travis/jvmopts.compile compile
- sbt -jvm-opts travis/jvmopts.test test
jdk:
- oraclejdk8
# - oraclejdk7
# - openjdk7
env:
- secure: "v7FHP8yK/zixpv1ML05qcRhZfDVDFdTmTPjfMZHL7gmrJveVDgze22x4tY4tB1+JEXhKuVTYvimOrX/Ok+rOOT5gVKLowv4PUQwCR+HgWVIbqjcfZNLsa369v03/p4K/zbjJSiXFahZYOXa0ApED2KWHcVfCrNsPv0UF7YZGiIa1Q/lPBwfmpN1rLih2Mpgn4KVaJky22t7JXJyVrNdGVmIA51slVbyFwFAE8Ww/0tkC+i2PUcWWRMIxtXP4iyq/9Npcq5VdqOatKfWHqAElLfKSPNMYLMlcyxyNpNx4paq8cL6fQxFcBLi9M2msz2i/qpKv30a0tzNo5bQQgucAXOQJB2Buks728upLuqsr+k25hwcqrtjyMOr9UQkt7qXAJH/0kimW7aW1yoMxbm/6mNG98X9D1EzNRewHAKatwJeFy1bw5qIuSQxPBwQMGloManrHOHGotmHKk7Y+dgM/z1UlaAdxSQuKWGXBc8QlQvif8puPYEdJMoInJNRxiWfYu06XnmzTXgMketK7RdULM9DVYzw8hzS2EIWKu8Oa0zn0PTevD2YeJNd4G8mDqO0vz5hloIc7pFsq/exQUB/kFozfCsnvhW8P+MPN0LpuSpptBQTsLWbM5BH0hd46HoWcneDdlMvVrUcgsTPmmSroIkLIEUo+Y2iN5eQHPPp85Cw="
before_install:
# JDK fix
- cat /etc/hosts # optionally check the content *before*
- sudo hostname "$(hostname | cut -c1-63)"
- sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts | sudo tee /etc/hosts
- cat /etc/hosts # optionally check the content *after*
- cd ..
# Verilator
#- sudo apt-get install git make autoconf g++ flex bison -y # First time prerequisites
#- git clone http://git.veripool.org/git/verilator # Only first time
#- unset VERILATOR_ROOT # For bash
#- cd verilator
#- git pull # Make sure we're up-to-date
#- git checkout verilator_3_916
#- autoconf # Create ./configure script
#- ./configure
#- make -j$(nproc)
#- sudo make install
#- cd ..
- cd VexRiscv
- curl -T README.md -udolu1990:$BINTRAY_KEY https://api.bintray.com/content/spinalhdl/VexRiscv/test/0.0.4/README.md
- curl -X POST -udolu1990:$BINTRAY_KEY https://api.bintray.com/content/spinalhdl/VexRiscv/test/0.0.4/publish
- sbt compile
before_cache:
# Tricks to avoid unnecessary cache updates
- find $HOME/.ivy2 -name "ivydata-*.properties" -delete
- find $HOME/.sbt -name "*.lock" -delete
cache:
directories:
- $HOME/.ivy2/cache
- $HOME/.sbt/boot/

View File

@ -19,27 +19,6 @@
- [CPU clock and resets](#cpu-clock-and-resets)
- [VexRiscv Architecture](#vexriscv-architecture)
* [Plugins](#plugins)
+ [PcManagerSimplePlugin](#pcmanagersimpleplugin)
+ [IBusSimplePlugin](#ibussimpleplugin)
+ [IBusCachedPlugin](#ibuscachedplugin)
+ [DecoderSimplePlugin](#decodersimpleplugin)
+ [RegFilePlugin](#regfileplugin)
+ [HazardSimplePlugin](#hazardsimpleplugin)
+ [SrcPlugin](#srcplugin)
+ [IntAluPlugin](#intaluplugin)
+ [LightShifterPlugin](#lightshifterplugin)
+ [FullBarrielShifterPlugin](#fullbarrielshifterplugin)
+ [BranchPlugin](#branchplugin)
+ [DBusSimplePlugin](#dbussimpleplugin)
+ [DBusCachedPlugin](#dbuscachedplugin)
+ [MulPlugin](#mulplugin)
+ [DivPlugin](#divplugin)
+ [MulDivIterativePlugin](#muldiviterativeplugin)
+ [CsrPlugin](#csrplugin)
+ [StaticMemoryTranslatorPlugin](#staticmemorytranslatorplugin)
+ [MemoryTranslatorPlugin](#memorytranslatorplugin)
+ [DebugPlugin](#debugplugin)
+ [YamlPlugin](#yamlplugin)
@ -47,7 +26,7 @@
This repository host an RISC-V implementation written in SpinalHDL. There is some specs :
- RV32IM instruction set
- RV32I[M] instruction set
- Pipelined on 5 stages (Fetch, Decode, Execute, Memory, WriteBack)
- 1.44 DMIPS/Mhz when all features are enabled
- Optimized for FPGA, fully portable
@ -60,6 +39,8 @@ This repository host an RISC-V implementation written in SpinalHDL. There is som
- Two implementation of shift instructions, Single cycle / shiftNumber cycles
- Each stage could have bypass or interlock hazard logic
- FreeRTOS port https://github.com/Dolu1990/FreeRTOS-RISCV
- The data cache support atomic LR/SC
- RV32 compressed instruction are supported in the reworkFetch branch for configurations without instruction cache (will be merge in master, WIP)
The hardware description of this CPU is done by using an very software oriented approach
(without any overhead in the generated hardware). There is a list of software concepts used :
@ -86,21 +67,25 @@ VexRiscv smallest (RV32I, 0.52 DMIPS/Mhz, no datapath bypass, no interrupt) ->
Artix 7 -> 346 Mhz 481 LUT 539 FF
Cyclone V -> 201 Mhz 347 ALMs
Cyclone IV -> 190 Mhz 673 LUT 529 FF
iCE40 -> 81 Mhz 1130 LC
VexRiscv smallest (RV32I, 0.52 DMIPS/Mhz, no datapath bypass) ->
Artix 7 -> 340 Mhz 562 LUT 589 FF
Cyclone V -> 202 Mhz 387 ALMs
Cyclone IV -> 180 Mhz 780 LUT 579 FF
iCE40 -> 71 Mhz 1278 LC
VexRiscv small and productive (RV32I, 0.82 DMIPS/Mhz) ->
Artix 7 -> 327 Mhz 698 LUT 558 FF
Cyclone V -> 158 Mhz 524 ALMs
Cyclone IV -> 146 Mhz 1,061 LUT 552 FF
iCE40 -> 55 Mhz 1541 LC
VexRiscv small and productive with I$ (RV32I, 0.72 DMIPS/Mhz, 4KB-I$) ->
Artix 7 -> 331 Mhz 727 LUT 600 FF
Cyclone V -> 152 Mhz 536 ALMs
Cyclone IV -> 156 Mhz 1,075 LUT 565 FF
iCE40 -> 54 Mhz 1686 LC
VexRiscv full no cache (RV32IM, 1.22 DMIPS/Mhz, single cycle barrel shifter, debug module, catch exceptions, static branch) ->
Artix 7 -> 295 Mhz 1399 LUT 971 FF
@ -629,7 +614,29 @@ So again, if you generate the CPU without any plugin, it will only contain the 5
### Plugins
This chapter (WIP) will describe plugins currently implemented
This chapter is describing plugins currently implemented.
- [PcManagerSimplePlugin](#pcmanagersimpleplugin)
- [IBusSimplePlugin](#ibussimpleplugin)
- [IBusCachedPlugin](#ibuscachedplugin)
- [DecoderSimplePlugin](#decodersimpleplugin)
- [RegFilePlugin](#regfileplugin)
- [HazardSimplePlugin](#hazardsimpleplugin)
- [SrcPlugin](#srcplugin)
- [IntAluPlugin](#intaluplugin)
- [LightShifterPlugin](#lightshifterplugin)
- [FullBarrielShifterPlugin](#fullbarrielshifterplugin)
- [BranchPlugin](#branchplugin)
- [DBusSimplePlugin](#dbussimpleplugin)
- [DBusCachedPlugin](#dbuscachedplugin)
- [MulPlugin](#mulplugin)
- [DivPlugin](#divplugin)
- [MulDivIterativePlugin](#muldiviterativeplugin)
- [CsrPlugin](#csrplugin)
- [StaticMemoryTranslatorPlugin](#staticmemorytranslatorplugin)
- [MemoryTranslatorPlugin](#memorytranslatorplugin)
- [DebugPlugin](#debugplugin)
- [YamlPlugin](#yamlplugin)
#### PcManagerSimplePlugin

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View File

@ -0,0 +1,241 @@
package spinal.lib.bus.wishbone
import spinal.core._
import spinal.lib._
/** This class is used for configuring the Wishbone class
* @param addressWidth size in bits of the address line
* @param dataWidth size in bits of the data line
* @param selWidth size in bits of the selection line, deafult to 0 (disabled)
* @param useSTALL activate the stall line, default to false (disabled)
* @param useLOCK activate the lock line, default to false (disabled)
* @param useERR activate the error line, default to false (disabled)
* @param useRTY activate the retry line, default to false (disabled)
* @param tgaWidth size in bits of the tag address linie, deafult to 0 (disabled)
* @param tgcWidth size in bits of the tag cycle line, deafult to 0 (disabled)
* @param tgdWidth size in bits of the tag data line, deafult to 0 (disabled)
* @param useBTE activate the BTE line, deafult to 0 (disabled)
* @param useCTI activate the CTI line, deafult to 0 (disabled)
* @example {{{
* val wishboneBusConf = new WishboneConfig(32,8).withCycleTag(8).withDataTag(8)
* val wishboneBus = new Wishbone(wishboneBusConf)
* }}}
* @todo test example
*/
case class WishboneConfig(
val addressWidth : Int,
val dataWidth : Int,
val selWidth : Int = 0,
val useSTALL : Boolean = false,
val useLOCK : Boolean = false,
val useERR : Boolean = false,
val useRTY : Boolean = false,
val tgaWidth : Int = 0,
val tgcWidth : Int = 0,
val tgdWidth : Int = 0,
val useBTE : Boolean = false,
val useCTI : Boolean = false
){
def useTGA = tgaWidth > 0
def useTGC = tgcWidth > 0
def useTGD = tgdWidth > 0
def useSEL = selWidth > 0
def isPipelined = useSTALL
def pipelined : WishboneConfig = this.copy(useSTALL = true)
def withDataTag(size : Int) : WishboneConfig = this.copy(tgdWidth = size)
def withAddressTag(size : Int) : WishboneConfig = this.copy(tgaWidth = size)
def withCycleTag(size : Int) : WishboneConfig = this.copy(tgdWidth = size)
}
/** This class rappresent a Wishbone bus
* @param config an istance of WishboneConfig, it will be used to configurate the Wishbone Bus
*/
case class Wishbone(config: WishboneConfig) extends Bundle with IMasterSlave {
/////////////////////
// MINIMAL SIGNALS //
/////////////////////
val CYC = Bool
val STB = Bool
val ACK = Bool
val WE = Bool
val ADR = UInt(config.addressWidth bits)
val DAT_MISO = Bits(config.dataWidth bits)
val DAT_MOSI = Bits(config.dataWidth bits)
///////////////////////////
// OPTIONAL FLOW CONTROS //
///////////////////////////
val SEL = if(config.useSEL) Bits(config.selWidth bits) else null
val STALL = if(config.useSTALL) Bool else null
val LOCK = if(config.useLOCK) Bool else null
val ERR = if(config.useERR) Bool else null
val RTY = if(config.useRTY) Bool else null
//////////
// TAGS //
//////////
val TGD_MISO = if(config.useTGD) Bits(config.tgdWidth bits) else null
val TGD_MOSI = if(config.useTGD) Bits(config.tgdWidth bits) else null
val TGA = if(config.useTGA) Bits(config.tgaWidth bits) else null
val TGC = if(config.useTGC) Bits(config.tgcWidth bits) else null
val BTE = if(config.useBTE) Bits(2 bits) else null
val CTI = if(config.useCTI) Bits(3 bits) else null
override def asMaster(): Unit = {
outWithNull(DAT_MOSI, TGD_MOSI, ADR, CYC, LOCK, SEL, STB, TGA, TGC, WE, CTI, BTE)
inWithNull(DAT_MISO, TGD_MISO, ACK, STALL, ERR, RTY)
}
// def isCycle : Bool = if(config.useERR) !ERR && CYC else CYC
// def isWrite : Bool = isCycle && WE
// def isRead : Bool = isCycle && !WE
// def isReadCycle : Bool = isRead && STB
// def isWriteCycle : Bool = isWrite && STB
// def isStalled : Bool = if(config.isPipelined) isCycle && STALL else False
// def isAcknoledge : Bool = isCycle && ACK
// def isStrobe : Bool = isCycle && STB
// def doSlaveWrite : Bool = this.CYC && this.STB && this.WE
// def doSlaveRead : Bool = this.CYC && this.STB && !this.WE
// def doSlavePipelinedWrite : Bool = this.CYC && this.WE
// def doSlavePipelinedRead : Bool = this.CYC && !this.WE
/** Connect the istance of this bus with another, allowing for resize of data
* @param that the wishbone instance that will be connected and resized
* @param allowDataResize allow to resize "that" data lines, default to false (disable)
* @param allowAddressResize allow to resize "that" address lines, default to false (disable)
* @param allowTagResize allow to resize "that" tag lines, default to false (disable)
*/
def connectTo(that : Wishbone, allowDataResize : Boolean = false, allowAddressResize : Boolean = false, allowTagResize : Boolean = false) : Unit = {
this.CYC <> that.CYC
this.STB <> that.STB
this.WE <> that.WE
this.ACK <> that.ACK
if(allowDataResize){
this.DAT_MISO.resized <> that.DAT_MISO
this.DAT_MOSI <> that.DAT_MOSI.resized
} else {
this.DAT_MOSI <> that.DAT_MOSI
this.DAT_MISO <> that.DAT_MISO
}
if(allowAddressResize){
this.ADR <> that.ADR.resized
} else {
this.ADR <> that.ADR
}
///////////////////////////
// OPTIONAL FLOW CONTROS //
///////////////////////////
if(this.config.useSTALL && that.config.useSTALL) this.STALL <> that.STALL
if(this.config.useERR && that.config.useERR) this.ERR <> that.ERR
if(this.config.useRTY && that.config.useRTY) this.RTY <> that.RTY
if(this.config.useSEL && that.config.useSEL) this.SEL <> that.SEL
if(this.config.useCTI && that.config.useCTI) this.CTI <> that.CTI
//////////
// TAGS //
//////////
if(this.config.useTGA && that.config.useTGA)
if(allowTagResize) this.TGA <> that.TGA.resized else this.TGA <> that.TGA
if(this.config.useTGC && that.config.useTGC)
if(allowTagResize) this.TGC <> that.TGC.resized else this.TGC <> that.TGC
if(this.config.useBTE && that.config.useBTE)
if(allowTagResize) this.BTE <> that.BTE.resized else this.BTE <> that.BTE
if(this.config.useTGD && that.config.useTGD){
if(allowTagResize){
this.TGD_MISO <> that.TGD_MISO.resized
this.TGD_MOSI <> that.TGD_MOSI.resized
} else {
this.TGD_MISO <> that.TGD_MISO
this.TGD_MOSI <> that.TGD_MOSI
}
}
}
/** Connect common Wishbone signals
* @example{{{wishbone1 <-> wishbone2}}}
*/
def <-> (sink : Wishbone) : Unit = {
/////////////////////
// MINIMAL SIGNALS //
/////////////////////
sink.CYC <> this.CYC
sink.ADR <> this.ADR
sink.DAT_MOSI <> this.DAT_MOSI
sink.DAT_MISO <> this.DAT_MISO
sink.STB <> this.STB
sink.WE <> this.WE
sink.ACK <> this.ACK
///////////////////////////
// OPTIONAL FLOW CONTROS //
///////////////////////////
if(this.config.useSTALL && sink.config.useSTALL) sink.STALL <> this.STALL
if(this.config.useERR && sink.config.useERR) sink.ERR <> this.ERR
if(this.config.useRTY && sink.config.useRTY) sink.RTY <> this.RTY
if(this.config.useSEL && sink.config.useSEL) sink.SEL <> this.SEL
//////////
// TAGS //
//////////
if(this.config.useTGA && sink.config.useTGA) sink.TGA <> this.TGA
if(this.config.useTGC && sink.config.useTGC) sink.TGC <> this.TGC
if(this.config.useCTI && sink.config.useCTI) sink.CTI <> this.CTI
if(this.config.useBTE && sink.config.useBTE) sink.BTE <> this.BTE
if(this.config.useTGD && sink.config.useTGD){
sink.TGD_MISO <> this.TGD_MISO
sink.TGD_MOSI <> this.TGD_MOSI
}
}
/** Clear all the relevant signals in the wishbone bus
* @example{{{
* val wishbone1 = master(Wishbone(WishboneConfig(8,8)))
* val wishbone2 = slave(Wishbone(WishboneConfig(8,8)))
* val wishbone2 = slave(Wishbone(WishboneConfig(8,8).withDataTag(8)))
*
* // this will clear only the following signals: CYC,ADR,DAT_MOSI,STB,WE
* wishbone1.clearAll()
* // this will clear only the following signals: DAT_MISO,ACK
* wishbone2.clearAll()
* // this will clear only the following signals: DAT_MISO,ACK,TGD_MISO
* wishbone3.clearAll()
* }}}
*/
def clearAll() : Unit = {
/////////////////////
// MINIMAl SIGLALS //
/////////////////////
if( isMasterInterface) this.CYC.clear()
if( isMasterInterface) this.ADR.clearAll()
if( isMasterInterface) this.DAT_MOSI.clearAll()
if(!isMasterInterface) this.DAT_MISO.clearAll()
if( isMasterInterface) this.STB.clear()
if( isMasterInterface) this.WE.clear()
if(!isMasterInterface) this.ACK.clear()
///////////////////////////
// OPTIONAL FLOW CONTROS //
///////////////////////////
if(this.config.useSTALL && !isMasterInterface) this.STALL.clear()
if(this.config.useERR && !isMasterInterface) this.ERR.clear()
if(this.config.useRTY && !isMasterInterface) this.RTY.clear()
if(this.config.useSEL && isMasterInterface) this.SEL.clearAll()
//////////
// TAGS //
//////////
if(this.config.useTGA && isMasterInterface) this.TGA.clearAll()
if(this.config.useTGC && isMasterInterface) this.TGC.clearAll()
if(this.config.useCTI && isMasterInterface) this.CTI.clearAll()
if(this.config.useBTE && isMasterInterface) this.BTE.clearAll()
if(this.config.useTGD && !isMasterInterface) this.TGD_MISO.clearAll()
if(this.config.useTGD && isMasterInterface) this.TGD_MOSI.clearAll()
}
}

View File

@ -0,0 +1,195 @@
package spinal.lib.eda.icestorm
import spinal.lib.eda._
import spinal.lib.eda.bench.{Report, Rtl, Target}
import scala.collection.mutable.ArrayBuffer
import java.io.File
import java.nio.file.Paths
import org.apache.commons.io.FileUtils
import spinal.core._
import spinal.lib.StreamFifo
import spinal.lib.eda.bench.Report
import scala.sys.process._
object IcestormFlow {
def doCmd(cmd : Seq[String], path : String): String ={
println(cmd)
val str = new StringBuilder()
val log = new ProcessLogger {
override def err(s: => String): Unit = {
str ++= s
stderr.println(s)
}
override def out(s: => String): Unit = {
str ++= s
stdout.println(s)
}
override def buffer[T](f: => T) = f
}
if(isWindows)
Process("cmd /C " + cmd, new java.io.File(path)) !(log)
else
Process.apply(cmd, new java.io.File(path)) !(log)
return str.toString()
}
val isWindows = System.getProperty("os.name").toLowerCase().contains("win")
def apply(workspacePath : String,toplevelPath : String,family : String,device : String, pack : String) : Report = {
val projectName = toplevelPath.split("/").last.split("[.]").head
val workspacePathFile = new File(workspacePath)
FileUtils.deleteDirectory(workspacePathFile)
workspacePathFile.mkdir()
FileUtils.copyFileToDirectory(new File(toplevelPath), workspacePathFile)
doCmd(List("yosys", "-v3", "-p", s"synth_ice40 -top $projectName -blif ${projectName}.blif", s"$projectName.v" ), workspacePath)
val arachne = doCmd(List("arachne-pnr", "-d", device.replace("hx","").replace("up",""), "--max-passes", "600", "-P", pack, s"$projectName.blif" ,"-o", s"$projectName.asc"), workspacePath)
doCmd(List("icepack", s"$projectName.asc", s"$projectName.bin"), workspacePath)
val icetime = doCmd(List("icetime", "-tmd", device, s"${projectName}.asc"), workspacePath)
new Report{
val intFind = "(\\d+,?)+".r
val fMaxReg = """[-+]?(\d*[.])?\d+""".r
override def getFMax() = {
try {
fMaxReg.findAllMatchIn("Total path delay: [^\\n]* MHz".r.findFirstIn(icetime).get).drop(1).next.toString().toDouble * 1e6
} catch {
case e : Throwable => -1
}
}
override def getArea() = {
try {
intFind.findFirstIn("LCs[^\\n]*\\/".r.findFirstIn(arachne).get).get.toString() + " LC"
} catch {
case e : Throwable => "error"
}
}
}
// mkdir -p bin
// rm -f Murax.v*.bin
// cp ../../../Murax.v*.bin . | true
// yosys -v3 -p "synth_ice40 -top toplevel -blif bin/toplevel.blif" ${VERILOG}
//
// val isVhdl = toplevelPath.endsWith(".vhd") || toplevelPath.endsWith(".vhdl")
//
// val tcl = new java.io.FileWriter(Paths.get(workspacePath,"doit.tcl").toFile)
// tcl.write(
// s"""read_${if(isVhdl) "vhdl" else "verilog"} $toplevelPath
//read_xdc doit.xdc
//
//synth_design -part $device -top ${toplevelPath.split("\\.").head}
//opt_design
//place_design
//route_design
//
//report_utilization
//report_timing"""
// )
//
// tcl.flush();
// tcl.close();
//
//
// val xdc = new java.io.FileWriter(Paths.get(workspacePath,"doit.xdc").toFile)
// xdc.write(s"""create_clock -period ${(targetPeriod*1e9) toBigDecimal} [get_ports clk]""")
//
// xdc.flush();
// xdc.close();
//
// doCmd(s"$vivadoPath/vivado -nojournal -log doit.log -mode batch -source doit.tcl", workspacePath)
//
// new Report{
// override def getFMax(): Double = {
// import scala.io.Source
// val report = Source.fromFile(Paths.get(workspacePath,"doit.log").toFile).getLines.mkString
// val intFind = "-?(\\d+\\.?)+".r
// val slack = try {
// (family match {
// case "Artix 7" =>
// intFind.findFirstIn("-?(\\d+.?)+ns \\(required time - arrival time\\)".r.findFirstIn(report).get).get
// }).toDouble
// }catch{
// case e : Exception => -1.0
// }
// return 1.0/(targetPeriod.toDouble-slack*1e-9)
// }
// override def getArea(): String = {
// import scala.io.Source
// val report = Source.fromFile(Paths.get(workspacePath,"doit.log").toFile).getLines.mkString
// val intFind = "(\\d+,?)+".r
// val leArea = try {
// family match {
// case "Artix 7" =>
// intFind.findFirstIn("Slice LUTs[ ]*\\|[ ]*(\\d+,?)+".r.findFirstIn(report).get).get + " LUT " +
// intFind.findFirstIn("Slice Registers[ ]*\\|[ ]*(\\d+,?)+".r.findFirstIn(report).get).get + " FF "
// }
// }catch{
// case e : Exception => "???"
// }
// return leArea
// }
// }
}
def main(args: Array[String]) {
// SpinalVerilog(StreamFifo(Bits(8 bits), 64))
// val report = IcestormFlow(
// workspacePath="/home/spinalvm/tmp",
// toplevelPath="StreamFifo.v",
// family="iCE40",
// device="hx8k",
// pack = "ct256"
// )
// println(report.getArea())
// println(report.getFMax())
// }
SpinalVerilog(StreamFifo(Bits(8 bits), 64))
val report = IcestormFlow(
workspacePath="/home/spinalvm/tmp",
toplevelPath="StreamFifo.v",
family="iCE40",
device="up5k",
pack = "sg48"
)
println(report.getArea())
println(report.getFMax())
}
}
object IcestormStdTargets {
def apply(): Seq[Target] = {
val targets = ArrayBuffer[Target]()
targets += new Target {
override def getFamilyName(): String = "iCE40"
override def synthesise(rtl: Rtl, workspace: String): Report = {
IcestormFlow(
workspacePath=workspace,
toplevelPath=rtl.getRtlPath(),
family=getFamilyName(),
device="hx8k",
pack = "ct256"
)
}
}
targets += new Target {
override def getFamilyName(): String = "iCE40Ultra"
override def synthesise(rtl: Rtl, workspace: String): Report = {
IcestormFlow(
workspacePath=workspace,
toplevelPath=rtl.getRtlPath(),
family=getFamilyName(),
device="up5k",
pack = "sg48"
)
}
}
targets
}
}

View File

@ -391,6 +391,21 @@ object Briey{
}
}
//DE1-SoC with memory init
object BrieyWithMemoryInit{
def main(args: Array[String]) {
val config = SpinalConfig()
config.generateVerilog({
val toplevel = new Briey(BrieyConfig.default)
toplevel.axi.vgaCtrl.vga.ctrl.io.error.addAttribute(Verilator.public)
toplevel.axi.vgaCtrl.vga.ctrl.io.frameStart.addAttribute(Verilator.public)
HexTools.initRam(toplevel.axi.ram.ram, "src/main/ressource/hex/muraxDemo.hex", 0x80000000l)
toplevel
})
}
}
//DE0-Nano
object BrieyDe0Nano{
def main(args: Array[String]) {

View File

@ -73,7 +73,45 @@ class MuraxMasterArbiter(simpleBusConfig : SimpleBusConfig) extends Component{
io.dBus.rsp.error := False
}
object HexTools{
def readHexFile(path : String, callback : (Int, Int) => Unit): Unit ={
import scala.io.Source
def hToI(that : String, start : Int, size : Int) = Integer.parseInt(that.substring(start,start + size), 16)
var offset = 0
for (line <- Source.fromFile(path).getLines) {
if (line.charAt(0) == ':'){
val byteCount = hToI(line, 1, 2)
val nextAddr = hToI(line, 3, 4) + offset
val key = hToI(line, 7, 2)
key match {
case 0 =>
for(i <- 0 until byteCount){
callback(nextAddr + i, hToI(line, 9 + i * 2, 2))
}
case 2 =>
offset = hToI(line, 9, 4) << 4
case 4 =>
offset = hToI(line, 9, 4) << 16
case 3 =>
case 5 =>
case 1 =>
}
}
}
}
def initRam[T <: Data](ram : Mem[T], onChipRamHexFile : String, ramOffset : BigInt): Unit ={
val initContent = Array.fill[BigInt](ram.wordCount)(0)
HexTools.readHexFile(onChipRamHexFile,(address,data) => {
val addressWithoutOffset = (address - ramOffset).toInt
initContent(addressWithoutOffset >> 2) |= BigInt(data) << ((addressWithoutOffset & 3)*8)
})
ram.initBigInt(initContent)
}
}
class MuraxSimpleBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, simpleBusConfig : SimpleBusConfig) extends Component{
val io = new Bundle{
@ -92,39 +130,7 @@ class MuraxSimpleBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, simpl
io.bus.cmd.ready := True
if(onChipRamHexFile != null){
def readHexFile(path : String, callback : (Int, Int) => Unit): Unit ={
import scala.io.Source
def hToI(that : String, start : Int, size : Int) = Integer.parseInt(that.substring(start,start + size), 16)
var offset = 0
for (line <- Source.fromFile(path).getLines) {
if (line.charAt(0) == ':'){
val byteCount = hToI(line, 1, 2)
val nextAddr = hToI(line, 3, 4) + offset
val key = hToI(line, 7, 2)
key match {
case 0 =>
for(i <- 0 until byteCount){
callback(nextAddr + i, hToI(line, 9 + i * 2, 2))
}
case 2 =>
offset = hToI(line, 9, 4) << 4
case 4 =>
offset = hToI(line, 9, 4) << 16
case 3 =>
case 5 =>
case 1 =>
}
}
}
}
val initContent = Array.fill[BigInt](ram.wordCount)(0)
readHexFile(onChipRamHexFile,(address,data) => {
val addressWithoutOffset = address + Int.MinValue
initContent(addressWithoutOffset >> 2) |= BigInt(data) << ((addressWithoutOffset & 3)*8)
})
ram.initBigInt(initContent)
HexTools.initRam(ram, onChipRamHexFile, 0x80000000l)
}
}

View File

@ -2,8 +2,9 @@ package vexriscv.demo
import spinal.core._
import spinal.lib.eda.bench._
import spinal.lib.eda.icestorm.IcestormStdTargets
import vexriscv.VexRiscv
import vexriscv.plugin.DecoderSimplePlugin
import vexriscv.plugin.{DecoderSimplePlugin, KeepAttribute}
import scala.collection.mutable.ArrayBuffer
@ -14,6 +15,11 @@ object VexRiscvSynthesisBench {
def main(args: Array[String]) {
def wrap(that : => Component) : Component = that
// def wrap(that : => Component) : Component = {
// val c = that
// c.getAllIo.foreach(io => KeepAttribute(io.asDirectionLess()))
// c
// }
// Wrap with input/output registers
// def wrap(that : => Component) : Component = {
// //new WrapWithReg.Wrapper(that)
@ -105,8 +111,9 @@ object VexRiscvSynthesisBench {
) ++ AlteraStdTargets(
quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin",
quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin"
)
) ++ IcestormStdTargets()
// val targets = IcestormStdTargets()
Bench(rtls, targets, "/eda/tmp/")
}
}
@ -147,7 +154,7 @@ object MuraxSynthesisBench {
override def getName(): String = "Murax"
override def getRtlPath(): String = "Murax.v"
SpinalVerilog({
val murax = new Murax(MuraxConfig.default).setDefinitionName(getRtlPath().split("\\.").head)
val murax = new Murax(MuraxConfig.defsbault).setDefinitionName(getRtlPath().split("\\.").head)
murax.io.mainClk.setName("clk")
murax
})

View File

@ -0,0 +1,159 @@
package vexriscv.demo
import spinal.core._
import spinal.lib._
import spinal.lib.bus.avalon.AvalonMM
import spinal.lib.eda.altera.{InterruptReceiverTag, QSysify, ResetEmitterTag}
import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig}
import vexriscv.plugin._
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
/**
* Created by spinalvm on 14.07.17.
*/
//class VexRiscvAvalon(debugClockDomain : ClockDomain) extends Component{
//
//}
// make clean run DBUS=CACHED_WISHBONE IBUS=CACHED_WISHBONE MMU=no CSR=no DEBUG_PLUGIN=no
object VexRiscvCachedWishboneForSim{
def main(args: Array[String]) {
val report = SpinalVerilog{
//CPU configuration
val cpuConfig = VexRiscvConfig(
plugins = List(
new PcManagerSimplePlugin(0x00000000l, false),
// new IBusSimplePlugin(
// interfaceKeepData = false,
// catchAccessFault = false
// ),
// new DBusSimplePlugin(
// catchAddressMisaligned = false,
// catchAccessFault = false
// ),
new IBusCachedPlugin(
prediction = STATIC,
config = InstructionCacheConfig(
cacheSize = 4096,
bytePerLine =32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true
)
// askMemoryTranslation = true,
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4
// )
),
new DBusCachedPlugin(
config = new DataCacheConfig(
cacheSize = 4096,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchAccessError = true,
catchIllegal = true,
catchUnaligned = true,
catchMemoryTranslationMiss = true
),
memoryTranslatorPortConfig = null
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 6
// )
),
new StaticMemoryTranslatorPlugin(
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 FullBarrielShifterPlugin,
new MulPlugin,
new DivPlugin,
new HazardSimplePlugin(
bypassExecute = true,
bypassMemory = true,
bypassWriteBack = true,
bypassWriteBackBuffer = true,
pessimisticUseSrc = false,
pessimisticWriteRegFile = false,
pessimisticAddressMatch = false
),
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin(
earlyBranch = false,
catchAddressMisaligned = true
),
new CsrPlugin(
config = CsrPluginConfig.small(mtvecInit = 0x80000020l)
),
new YamlPlugin("cpu0.yaml")
)
)
//CPU instanciation
val cpu = new VexRiscv(cpuConfig)
//CPU modifications to be an Avalon one
//cpu.setDefinitionName("VexRiscvAvalon")
cpu.rework {
for (plugin <- cpuConfig.plugins) plugin match {
// case plugin: IBusSimplePlugin => {
// plugin.iBus.asDirectionLess() //Unset IO properties of iBus
// iBus = master(plugin.iBus.toAvalon())
// .setName("iBusAvalon")
// .addTag(ClockDomainTag(ClockDomain.current)) //Specify a clock domain to the iBus (used by QSysify)
// }
case plugin: IBusCachedPlugin => {
plugin.iBus.asDirectionLess() //Unset IO properties of iBus
master(plugin.iBus.toWishbone()).setName("iBusWishbone")
}
// case plugin: DBusSimplePlugin => {
// plugin.dBus.asDirectionLess()
// master(plugin.dBus.toAvalon())
// .setName("dBusAvalon")
// .addTag(ClockDomainTag(ClockDomain.current))
// }
case plugin: DBusCachedPlugin => {
plugin.dBus.asDirectionLess()
master(plugin.dBus.toWishbone()).setName("dBusWishbone")
}
// case plugin: DebugPlugin => {
// plugin.io.bus.asDirectionLess()
// slave(plugin.io.bus.fromAvalon())
// .setName("debugBusAvalon")
// .addTag(ClockDomainTag(plugin.debugClockDomain))
// .parent = null //Avoid the io bundle to be interpreted as a QSys conduit
// plugin.io.resetOut
// .addTag(ResetEmitterTag(plugin.debugClockDomain))
// .parent = null //Avoid the io bundle to be interpreted as a QSys conduit
// }
case _ =>
}
}
cpu
}
//Generate the QSys TCL script to integrate the CPU
QSysify(report.toplevel)
}
}

View File

@ -3,9 +3,9 @@ package vexriscv.ip
import vexriscv._
import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba4.axi.{Axi4Shared, Axi4Config}
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4Shared}
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
case class DataCacheConfig( cacheSize : Int,
bytePerLine : Int,
@ -46,6 +46,21 @@ case class DataCacheConfig( cacheSize : Int,
useResponse = true,
maximumPendingReadTransactions = 2
)
def getWishboneConfig() = WishboneConfig(
addressWidth = 30,
dataWidth = 32,
selWidth = 4,
useSTALL = false,
useLOCK = false,
useERR = true,
useRTY = false,
tgaWidth = 0,
tgcWidth = 0,
tgdWidth = 0,
useBTE = true,
useCTI = true
)
}
@ -285,6 +300,48 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
mm
}
def toWishbone(): Wishbone = {
val wishboneConfig = p.getWishboneConfig()
val bus = Wishbone(wishboneConfig)
val counter = Reg(UInt(log2Up(p.burstSize) bits)) init(0)
val cmdBridge = Stream (DataCacheMemCmd(p))
val isBurst = cmdBridge.length =/= 0
cmdBridge.valid := cmd.valid
cmdBridge.address := (isBurst ? (cmd.address(31 downto widthOf(counter) + 2) @@ counter @@ "00") | (cmd.address(31 downto 2) @@ "00"))
cmdBridge.wr := cmd.wr
cmdBridge.mask := cmd.mask
cmdBridge.data := cmd.data
cmdBridge.length := cmd.length
cmdBridge.last := counter === cmd.length
cmd.ready := cmdBridge.ready && (cmdBridge.wr || cmdBridge.last)
when(cmdBridge.fire){
counter := counter + 1
when(cmdBridge.last){
counter := 0
}
}
bus.ADR := cmdBridge.address >> 2
bus.CTI := Mux(isBurst, cmdBridge.last ? B"111" | B"010", B"000")
bus.BTE := "00"
bus.SEL := cmdBridge.wr ? cmdBridge.mask | "1111"
bus.WE := cmdBridge.wr
bus.DAT_MOSI := cmdBridge.data
cmdBridge.ready := cmdBridge.valid && bus.ACK
bus.CYC := cmdBridge.valid
bus.STB := cmdBridge.valid
rsp.valid := RegNext(cmdBridge.valid && !bus.WE && bus.ACK) init(False)
rsp.data := RegNext(bus.DAT_MISO)
rsp.error := False //TODO
bus
}
}

View File

@ -3,8 +3,9 @@ package vexriscv.ip
import vexriscv._
import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba4.axi.{Axi4ReadOnly, Axi4Config}
import spinal.lib.bus.avalon.{AvalonMMConfig, AvalonMM}
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4ReadOnly}
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
case class InstructionCacheConfig( cacheSize : Int,
@ -44,6 +45,20 @@ case class InstructionCacheConfig( cacheSize : Int,
constantBurstBehavior = true
)
def getWishboneConfig() = WishboneConfig(
addressWidth = 30,
dataWidth = 32,
selWidth = 4,
useSTALL = false,
useLOCK = false,
useERR = true,
useRTY = false,
tgaWidth = 0,
tgcWidth = 0,
tgdWidth = 0,
useBTE = true,
useCTI = true
)
}
@ -162,6 +177,36 @@ case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle wit
rsp.error := mm.response =/= AvalonMM.Response.OKAY
mm
}
def toWishbone(): Wishbone = {
val wishboneConfig = p.getWishboneConfig()
val bus = Wishbone(wishboneConfig)
val counter = Reg(UInt(log2Up(p.burstSize) bits)) init(0)
val pending = counter =/= 0
val lastCycle = counter === counter.maxValue
bus.ADR := (cmd.address >> widthOf(counter) + 2) @@ counter
bus.CTI := lastCycle ? B"111" | B"010"
bus.BTE := "00"
bus.SEL := "1111"
bus.WE := False
bus.DAT_MOSI.assignDontCare()
bus.CYC := False
bus.STB := False
when(cmd.valid || pending){
bus.CYC := True
bus.STB := True
when(bus.ACK){
counter := counter + 1
}
}
cmd.ready := cmd.valid && bus.ACK
rsp.valid := RegNext(bus.CYC && bus.ACK) init(False)
rsp.data := RegNext(bus.DAT_MISO)
rsp.error := False //TODO
bus
}
}

View File

@ -312,7 +312,8 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
val base = Reg(UInt(2 bits)) init(U"01") allowUnsetRegToAvoidLatch
val extensions = Reg(Bits(26 bits)) init(misaExtensionsInit) allowUnsetRegToAvoidLatch
}
val mtvec = RegInit(U(mtvecInit,xlen bits)) allowUnsetRegToAvoidLatch
val mtvec = Reg(UInt(xlen bits)).allowUnsetRegToAvoidLatch
if(mtvecInit != null) mtvec init(mtvecInit)
val mepc = Reg(UInt(xlen bits))
val mstatus = new Area{
val MIE, MPIE = RegInit(False)

View File

@ -18,7 +18,9 @@ class DAxiCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
}
}
class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv]{
class DBusCachedPlugin(config : DataCacheConfig,
memoryTranslatorPortConfig : Any = null,
csrInfo : Boolean = false) extends Plugin[VexRiscv]{
import config._
var dBus : DataCacheMemBus = null
var mmuBus : MemoryTranslatorBus = null
@ -214,7 +216,12 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
when(arbitration.isValid && input(MEMORY_ENABLE)) {
output(REGFILE_WRITE_DATA) := rspFormated
}
}
}
if(csrInfo){
val csr = service(classOf[CsrPlugin])
csr.r(0xCC0, 0 -> U(cacheSize/wayCount), 20 -> U(bytePerLine))
}
}
}

View File

@ -0,0 +1,21 @@
package vexriscv.plugin
import spinal.core._
import vexriscv.VexRiscv
class ExternalInterruptArrayPlugin(arrayWidth : Int = 32) extends Plugin[VexRiscv]{
var externalInterruptArray : Bits = null
override def setup(pipeline: VexRiscv): Unit = {
externalInterruptArray = in(Bits(arrayWidth bits)).setName("externalInterruptArray")
}
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.asDirectionLess() := pendings.orR
csr.rw(0x330, mask)
csr.r(0x360, pendings)
}
}

View File

@ -22,6 +22,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
var prefetchExceptionPort : Flow[ExceptionCause] = null
var decodePrediction : DecodePredictionBus = null
var fetchPrediction : FetchPredictionBus = null
var externalResetVector : UInt = null
assert(cmdToRspStageCount >= 1)
assert(!(cmdToRspStageCount == 1 && !injectorStage))
assert(!(compressedGen && !decodePcGen))
@ -58,6 +59,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
if(catchAccessFault) {
val exceptionService = pipeline.service(classOf[ExceptionService])
}
if(resetVector == null) externalResetVector = in(UInt(32 bits).setName("externalResetVector"))
pipeline(RVC_GEN) = compressedGen
@ -105,7 +107,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
val fetchPc = if(relaxedPcCalculation) new PcFetch {
//PC calculation without Jump
val pcReg = Reg(UInt(32 bits)) init (resetVector) addAttribute (Verilator.public)
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
val pcPlus4 = pcReg + 4
if (keepPcPlus4) KeepAttribute(pcPlus4)
when(preOutput.fire) {
@ -133,7 +136,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
preOutput.payload := pcReg
} else new PcFetch{
//PC calculation without Jump
val pcReg = Reg(UInt(32 bits)) init(resetVector) addAttribute(Verilator.public)
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
val inc = RegInit(False)
val pc = pcReg + (inc ## B"00").asUInt
@ -178,7 +181,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
val decodePc = ifGen(decodePcGen)(new Area {
//PC calculation without Jump
val pcReg = Reg(UInt(32 bits)) init (resetVector) addAttribute (Verilator.public)
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
val pcPlus = if(compressedGen)
pcReg + ((decode.input(IS_RVC)) ? U(2) | U(4))
else

View File

@ -442,8 +442,6 @@ public:
top->eval();
dump(i + 1);
if(top->VexRiscv->writeBack_arbitration_isFiring){
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
@ -463,6 +461,8 @@ public:
for(SimElement* simElement : simElements) simElement->preCycle();
dump(i + 1);
#ifndef COMPRESSED
if(withInstructionReadCheck){
if(top->VexRiscv->decode_arbitration_isValid && !top->VexRiscv->decode_arbitration_haltItself && !top->VexRiscv->decode_arbitration_flushAll){
@ -713,6 +713,48 @@ public:
};
#endif
#ifdef IBUS_CACHED_WISHBONE
#include <queue>
class IBusCachedWishbone : public SimElement{
public:
Workspace *ws;
VVexRiscv* top;
IBusCachedWishbone(Workspace* ws){
this->ws = ws;
this->top = ws->top;
}
virtual void onReset(){
top->iBusWishbone_ACK = !ws->iStall;
top->iBusWishbone_ERR = 0;
}
virtual void preCycle(){
top->iBusWishbone_DAT_MISO = VL_RANDOM_I(32);
if (top->iBusWishbone_CYC && top->iBusWishbone_STB && top->iBusWishbone_ACK) {
if(top->iBusWishbone_WE){
} else {
bool error;
ws->iBusAccess(top->iBusWishbone_ADR << 2,&top->iBusWishbone_DAT_MISO,&error);
top->iBusWishbone_ERR = error;
}
}
}
virtual void postCycle(){
if(ws->iStall)
top->iBusWishbone_ACK = VL_RANDOM_I(7) < 100;
}
};
#endif
#ifdef DBUS_SIMPLE
class DBusSimple : public SimElement{
public:
@ -809,8 +851,47 @@ public:
};
#endif
#ifdef DBUS_CACHED_WISHBONE
#include <queue>
class DBusCachedWishbone : public SimElement{
public:
Workspace *ws;
VVexRiscv* top;
DBusCachedWishbone(Workspace* ws){
this->ws = ws;
this->top = ws->top;
}
virtual void onReset(){
top->dBusWishbone_ACK = !ws->iStall;
top->dBusWishbone_ERR = 0;
}
virtual void preCycle(){
top->dBusWishbone_DAT_MISO = VL_RANDOM_I(32);
if (top->dBusWishbone_CYC && top->dBusWishbone_STB && top->dBusWishbone_ACK) {
if(top->dBusWishbone_WE){
bool dummy;
ws->dBusAccess(top->dBusWishbone_ADR << 2 ,1,2,top->dBusWishbone_SEL,&top->dBusWishbone_DAT_MOSI,&dummy);
} else {
bool error;
ws->dBusAccess(top->dBusWishbone_ADR << 2,0,2,0xF,&top->dBusWishbone_DAT_MISO,&error);
top->dBusWishbone_ERR = error;
}
}
}
virtual void postCycle(){
if(ws->iStall)
top->dBusWishbone_ACK = VL_RANDOM_I(7) < 100;
}
};
#endif
#ifdef DBUS_CACHED
//#include "VVexRiscv_DataCache.h"
@ -1243,6 +1324,9 @@ void Workspace::fillSimELements(){
#ifdef IBUS_CACHED_AVALON
simElements.push_back(new IBusCachedAvalon(this));
#endif
#ifdef IBUS_CACHED_WISHBONE
simElements.push_back(new IBusCachedWishbone(this));
#endif
#ifdef DBUS_SIMPLE
simElements.push_back(new DBusSimple(this));
#endif
@ -1255,6 +1339,9 @@ void Workspace::fillSimELements(){
#ifdef DBUS_CACHED_AVALON
simElements.push_back(new DBusCachedAvalon(this));
#endif
#ifdef DBUS_CACHED_WISHBONE
simElements.push_back(new DBusCachedWishbone(this));
#endif
#ifdef DEBUG_PLUGIN_STD
simElements.push_back(new DebugPluginStd(this));
#endif