commit
abb7bd99ab
|
@ -7,8 +7,8 @@ lazy val root = (project in file(".")).
|
||||||
version := "2.0.0"
|
version := "2.0.0"
|
||||||
)),
|
)),
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.3",
|
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.4",
|
||||||
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.3",
|
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.4",
|
||||||
"org.scalatest" % "scalatest_2.11" % "2.2.1",
|
"org.scalatest" % "scalatest_2.11" % "2.2.1",
|
||||||
"org.yaml" % "snakeyaml" % "1.8"
|
"org.yaml" % "snakeyaml" % "1.8"
|
||||||
),
|
),
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
package vexriscv.demo
|
||||||
|
|
||||||
|
|
||||||
|
import spinal.core._
|
||||||
|
import spinal.lib._
|
||||||
|
import spinal.lib.bus.avalon.AvalonMM
|
||||||
|
import spinal.lib.com.jtag.Jtag
|
||||||
|
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=SIMPLE_AHBLITE3 IBUS=SIMPLE_AHBLITE3 MMU=no CSR=no DEBUG_PLUGIN=STD
|
||||||
|
|
||||||
|
object VexRiscvAhbLite3{
|
||||||
|
def main(args: Array[String]) {
|
||||||
|
val report = SpinalConfig(mode = if(args.contains("--vhdl")) VHDL else Verilog).generate{
|
||||||
|
|
||||||
|
//CPU configuration
|
||||||
|
val cpuConfig = VexRiscvConfig(
|
||||||
|
plugins = List(
|
||||||
|
new IBusSimplePlugin(
|
||||||
|
resetVector = 0x80000000l,
|
||||||
|
cmdForkOnSecondStage = false,
|
||||||
|
cmdForkPersistence = true,
|
||||||
|
prediction = STATIC,
|
||||||
|
catchAccessFault = false,
|
||||||
|
compressedGen = false
|
||||||
|
),
|
||||||
|
new DBusSimplePlugin(
|
||||||
|
catchAddressMisaligned = false,
|
||||||
|
catchAccessFault = false
|
||||||
|
),
|
||||||
|
// new IBusCachedPlugin(
|
||||||
|
// 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 FullBarrelShifterPlugin,
|
||||||
|
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(
|
||||||
|
catchIllegalAccess = false,
|
||||||
|
mvendorid = null,
|
||||||
|
marchid = null,
|
||||||
|
mimpid = null,
|
||||||
|
mhartid = null,
|
||||||
|
misaExtensionsInit = 66,
|
||||||
|
misaAccess = CsrAccess.NONE,
|
||||||
|
mtvecAccess = CsrAccess.NONE,
|
||||||
|
mtvecInit = 0x00000020l,
|
||||||
|
mepcAccess = CsrAccess.READ_WRITE,
|
||||||
|
mscratchGen = false,
|
||||||
|
mcauseAccess = CsrAccess.READ_ONLY,
|
||||||
|
mbadaddrAccess = CsrAccess.READ_ONLY,
|
||||||
|
mcycleAccess = CsrAccess.NONE,
|
||||||
|
minstretAccess = CsrAccess.NONE,
|
||||||
|
ecallGen = false,
|
||||||
|
wfiGenAsWait = false,
|
||||||
|
ucycleAccess = CsrAccess.NONE
|
||||||
|
)
|
||||||
|
),
|
||||||
|
new YamlPlugin("cpu0.yaml")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
//CPU instanciation
|
||||||
|
val cpu = new VexRiscv(cpuConfig)
|
||||||
|
|
||||||
|
//CPU modifications to be an AhbLite3 one
|
||||||
|
cpu.rework {
|
||||||
|
for (plugin <- cpuConfig.plugins) plugin match {
|
||||||
|
case plugin: IBusSimplePlugin => {
|
||||||
|
plugin.iBus.setAsDirectionLess() //Unset IO properties of iBus
|
||||||
|
master(plugin.iBus.toAhbLite3Master()).setName("iBusAhbLite3")
|
||||||
|
}
|
||||||
|
case plugin: DBusSimplePlugin => {
|
||||||
|
plugin.dBus.setAsDirectionLess()
|
||||||
|
master(plugin.dBus.toAhbLite3Master(avoidWriteToReadHazard = true)).setName("dBusAhbLite3")
|
||||||
|
}
|
||||||
|
// case plugin: IBusCachedPlugin => {
|
||||||
|
// plugin.iBus.setAsDirectionLess() //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: DBusCachedPlugin => {
|
||||||
|
// plugin.dBus.setAsDirectionLess()
|
||||||
|
// master(plugin.dBus.toAvalon())
|
||||||
|
// .setName("dBusAvalon")
|
||||||
|
// .addTag(ClockDomainTag(ClockDomain.current))
|
||||||
|
// }
|
||||||
|
case plugin: DebugPlugin if args.contains("--jtag")=> plugin.debugClockDomain {
|
||||||
|
plugin.io.bus.setAsDirectionLess()
|
||||||
|
val jtag = slave(new Jtag()).setName("jtag")
|
||||||
|
jtag <> plugin.io.bus.fromJtag()
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package vexriscv.plugin
|
||||||
import vexriscv._
|
import vexriscv._
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
import spinal.lib.bus.amba3.ahblite.{AhbLite3Config, AhbLite3Master}
|
||||||
import spinal.lib.bus.amba4.axi._
|
import spinal.lib.bus.amba4.axi._
|
||||||
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
||||||
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
|
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
|
||||||
|
@ -71,6 +72,10 @@ object DBusSimpleBus{
|
||||||
dataWidth = 32
|
dataWidth = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def getAhbLite3Config() = AhbLite3Config(
|
||||||
|
addressWidth = 32,
|
||||||
|
dataWidth = 32
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
|
@ -82,7 +87,14 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
slave(rsp)
|
slave(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
def toAxi4Shared(stageCmd : Boolean = true): Axi4Shared = {
|
def cmdS2mPipe() : DBusSimpleBus = {
|
||||||
|
val s = DBusSimpleBus()
|
||||||
|
s.cmd << this.cmd.s2mPipe()
|
||||||
|
this.rsp := s.rsp
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
def toAxi4Shared(stageCmd : Boolean = false): Axi4Shared = {
|
||||||
val axi = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
val axi = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
||||||
val pendingWritesMax = 7
|
val pendingWritesMax = 7
|
||||||
val pendingWrites = CounterUpDown(
|
val pendingWrites = CounterUpDown(
|
||||||
|
@ -92,7 +104,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
)
|
)
|
||||||
|
|
||||||
val cmdPreFork = if (stageCmd) cmd.stage.stage().s2mPipe() else cmd
|
val cmdPreFork = if (stageCmd) cmd.stage.stage().s2mPipe() else cmd
|
||||||
val (cmdFork, dataFork) = StreamFork2(cmdPreFork.haltWhen((pendingWrites =/= 0 && !cmdPreFork.wr) || pendingWrites === pendingWritesMax))
|
val (cmdFork, dataFork) = StreamFork2(cmdPreFork.haltWhen((pendingWrites =/= 0 && cmdPreFork.valid && !cmdPreFork.wr) || pendingWrites === pendingWritesMax))
|
||||||
axi.sharedCmd.arbitrationFrom(cmdFork)
|
axi.sharedCmd.arbitrationFrom(cmdFork)
|
||||||
axi.sharedCmd.write := cmdFork.wr
|
axi.sharedCmd.write := cmdFork.wr
|
||||||
axi.sharedCmd.prot := "010"
|
axi.sharedCmd.prot := "010"
|
||||||
|
@ -117,16 +129,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
|
|
||||||
axi.r.ready := True
|
axi.r.ready := True
|
||||||
axi.b.ready := True
|
axi.b.ready := True
|
||||||
|
axi
|
||||||
|
|
||||||
//TODO remove
|
|
||||||
val axi2 = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
|
||||||
axi.arw >-> axi2.arw
|
|
||||||
axi.w >> axi2.w
|
|
||||||
axi.r << axi2.r
|
|
||||||
axi.b << axi2.b
|
|
||||||
// axi2 << axi
|
|
||||||
axi2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def toAxi4(stageCmd : Boolean = true) = this.toAxi4Shared(stageCmd).toAxi4()
|
def toAxi4(stageCmd : Boolean = true) = this.toAxi4Shared(stageCmd).toAxi4()
|
||||||
|
@ -204,6 +207,37 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
|
|
||||||
bus
|
bus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def toAhbLite3Master(avoidWriteToReadHazard : Boolean): AhbLite3Master = {
|
||||||
|
val bus = AhbLite3Master(DBusSimpleBus.getAhbLite3Config())
|
||||||
|
bus.HADDR := this.cmd.address
|
||||||
|
bus.HWRITE := this.cmd.wr
|
||||||
|
bus.HSIZE := B(this.cmd.size, 3 bits)
|
||||||
|
bus.HBURST := 0
|
||||||
|
bus.HPROT := "1111"
|
||||||
|
bus.HTRANS := this.cmd.valid ## B"0"
|
||||||
|
bus.HMASTLOCK := False
|
||||||
|
bus.HWDATA := RegNextWhen(this.cmd.data, bus.HREADY)
|
||||||
|
this.cmd.ready := bus.HREADY
|
||||||
|
|
||||||
|
val pending = RegInit(False) clearWhen(bus.HREADY) setWhen(this.cmd.fire && !this.cmd.wr)
|
||||||
|
this.rsp.ready := bus.HREADY && pending
|
||||||
|
this.rsp.data := bus.HRDATA
|
||||||
|
this.rsp.error := bus.HRESP
|
||||||
|
|
||||||
|
if(avoidWriteToReadHazard) {
|
||||||
|
val writeDataPhase = RegNextWhen(bus.HTRANS === 2 && bus.HWRITE, bus.HREADY) init (False)
|
||||||
|
val potentialHazard = this.cmd.valid && !this.cmd.wr && writeDataPhase
|
||||||
|
when(potentialHazard) {
|
||||||
|
bus.HTRANS := 0
|
||||||
|
this.cmd.ready := False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bus
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package vexriscv.plugin
|
||||||
import vexriscv._
|
import vexriscv._
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
import spinal.lib.bus.amba3.ahblite.{AhbLite3, AhbLite3Config, AhbLite3Master}
|
||||||
import spinal.lib.bus.amba4.axi._
|
import spinal.lib.bus.amba4.axi._
|
||||||
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
||||||
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
|
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
|
||||||
|
@ -65,10 +66,15 @@ object IBusSimpleBus{
|
||||||
addressWidth = 32,
|
addressWidth = 32,
|
||||||
dataWidth = 32
|
dataWidth = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def getAhbLite3Config() = AhbLite3Config(
|
||||||
|
addressWidth = 32,
|
||||||
|
dataWidth = 32
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case class IBusSimpleBus(interfaceKeepData : Boolean = false) extends Bundle with IMasterSlave {
|
case class IBusSimpleBus(cmdIsPersistente : Boolean = false) extends Bundle with IMasterSlave {
|
||||||
var cmd = Stream(IBusSimpleCmd())
|
var cmd = Stream(IBusSimpleCmd())
|
||||||
var rsp = Flow(IBusSimpleRsp())
|
var rsp = Flow(IBusSimpleRsp())
|
||||||
|
|
||||||
|
@ -78,8 +84,16 @@ case class IBusSimpleBus(interfaceKeepData : Boolean = false) extends Bundle wit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def cmdS2mPipe() : IBusSimpleBus = {
|
||||||
|
val s = IBusSimpleBus()
|
||||||
|
s.cmd << this.cmd.s2mPipe()
|
||||||
|
this.rsp << s.rsp
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def toAxi4ReadOnly(): Axi4ReadOnly = {
|
def toAxi4ReadOnly(): Axi4ReadOnly = {
|
||||||
assert(!interfaceKeepData)
|
assert(cmdIsPersistente)
|
||||||
val axi = Axi4ReadOnly(IBusSimpleBus.getAxi4Config())
|
val axi = Axi4ReadOnly(IBusSimpleBus.getAxi4Config())
|
||||||
|
|
||||||
axi.ar.valid := cmd.valid
|
axi.ar.valid := cmd.valid
|
||||||
|
@ -94,17 +108,11 @@ case class IBusSimpleBus(interfaceKeepData : Boolean = false) extends Bundle wit
|
||||||
rsp.error := !axi.r.isOKAY()
|
rsp.error := !axi.r.isOKAY()
|
||||||
axi.r.ready := True
|
axi.r.ready := True
|
||||||
|
|
||||||
|
axi
|
||||||
//TODO remove
|
|
||||||
val axi2 = Axi4ReadOnly(IBusSimpleBus.getAxi4Config())
|
|
||||||
axi.ar >-> axi2.ar
|
|
||||||
axi.r << axi2.r
|
|
||||||
// axi2 << axi
|
|
||||||
axi2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def toAvalon(): AvalonMM = {
|
def toAvalon(): AvalonMM = {
|
||||||
assert(!interfaceKeepData)
|
assert(cmdIsPersistente)
|
||||||
val avalonConfig = IBusSimpleBus.getAvalonConfig()
|
val avalonConfig = IBusSimpleBus.getAvalonConfig()
|
||||||
val mm = AvalonMM(avalonConfig)
|
val mm = AvalonMM(avalonConfig)
|
||||||
|
|
||||||
|
@ -154,6 +162,26 @@ case class IBusSimpleBus(interfaceKeepData : Boolean = false) extends Bundle wit
|
||||||
rsp.error := False
|
rsp.error := False
|
||||||
bus
|
bus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//cmdForkPersistence need to bet set
|
||||||
|
def toAhbLite3Master(): AhbLite3Master = {
|
||||||
|
val bus = AhbLite3Master(IBusSimpleBus.getAhbLite3Config())
|
||||||
|
bus.HADDR := this.cmd.pc
|
||||||
|
bus.HWRITE := False
|
||||||
|
bus.HSIZE := 2
|
||||||
|
bus.HBURST := 0
|
||||||
|
bus.HPROT := "1110"
|
||||||
|
bus.HTRANS := this.cmd.valid ## B"0"
|
||||||
|
bus.HMASTLOCK := False
|
||||||
|
bus.HWDATA.assignDontCare()
|
||||||
|
this.cmd.ready := bus.HREADY
|
||||||
|
|
||||||
|
val pending = RegInit(False) clearWhen(bus.HREADY) setWhen(this.cmd.fire)
|
||||||
|
this.rsp.valid := bus.HREADY && pending
|
||||||
|
this.rsp.inst := bus.HRDATA
|
||||||
|
this.rsp.error := bus.HRESP
|
||||||
|
bus
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,7 +227,7 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
|
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
super.setup(pipeline)
|
super.setup(pipeline)
|
||||||
iBus = master(IBusSimpleBus(false)).setName("iBus")
|
iBus = master(IBusSimpleBus(cmdForkPersistence)).setName("iBus")
|
||||||
|
|
||||||
val decoderService = pipeline.service(classOf[DecoderService])
|
val decoderService = pipeline.service(classOf[DecoderService])
|
||||||
decoderService.add(FENCE_I, Nil)
|
decoderService.add(FENCE_I, Nil)
|
||||||
|
|
|
@ -1475,7 +1475,7 @@ public:
|
||||||
if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc;
|
if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc;
|
||||||
#else
|
#else
|
||||||
if(bootPc != -1) {
|
if(bootPc != -1) {
|
||||||
#if defined(IBUS_SIMPLE) || defined(IBUS_SIMPLE_WISHBONE)
|
#if defined(IBUS_SIMPLE) || defined(IBUS_SIMPLE_WISHBONE) || defined(IBUS_SIMPLE_AHBLITE3)
|
||||||
top->VexRiscv->IBusSimplePlugin_fetchPc_pcReg = bootPc;
|
top->VexRiscv->IBusSimplePlugin_fetchPc_pcReg = bootPc;
|
||||||
#ifdef COMPRESSED
|
#ifdef COMPRESSED
|
||||||
top->VexRiscv->IBusSimplePlugin_decodePc_pcReg = bootPc;
|
top->VexRiscv->IBusSimplePlugin_decodePc_pcReg = bootPc;
|
||||||
|
@ -1924,6 +1924,52 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef IBUS_SIMPLE_AHBLITE3
|
||||||
|
class IBusSimpleAhbLite3 : public SimElement{
|
||||||
|
public:
|
||||||
|
Workspace *ws;
|
||||||
|
VVexRiscv* top;
|
||||||
|
|
||||||
|
uint32_t iBusAhbLite3_HRDATA;
|
||||||
|
bool iBusAhbLite3_HRESP;
|
||||||
|
bool pending;
|
||||||
|
|
||||||
|
IBusSimpleAhbLite3(Workspace* ws){
|
||||||
|
this->ws = ws;
|
||||||
|
this->top = ws->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onReset(){
|
||||||
|
pending = false;
|
||||||
|
top->iBusAhbLite3_HREADY = 1;
|
||||||
|
top->iBusAhbLite3_HRESP = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void preCycle(){
|
||||||
|
if (top->iBusAhbLite3_HTRANS == 2 && top->iBusAhbLite3_HREADY && !top->iBusAhbLite3_HWRITE) {
|
||||||
|
ws->iBusAccess(top->iBusAhbLite3_HADDR,&iBusAhbLite3_HRDATA,&iBusAhbLite3_HRESP);
|
||||||
|
pending = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void postCycle(){
|
||||||
|
if(ws->iStall)
|
||||||
|
top->iBusAhbLite3_HREADY = (!ws->iStall || VL_RANDOM_I(7) < 100);
|
||||||
|
|
||||||
|
if(pending && top->iBusAhbLite3_HREADY){
|
||||||
|
top->iBusAhbLite3_HRDATA = iBusAhbLite3_HRDATA;
|
||||||
|
top->iBusAhbLite3_HRESP = iBusAhbLite3_HRESP;
|
||||||
|
pending = false;
|
||||||
|
} else {
|
||||||
|
top->iBusAhbLite3_HRDATA = VL_RANDOM_I(32);
|
||||||
|
top->iBusAhbLite3_HRESP = VL_RANDOM_I(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef IBUS_CACHED
|
#ifdef IBUS_CACHED
|
||||||
class IBusCached : public SimElement{
|
class IBusCached : public SimElement{
|
||||||
public:
|
public:
|
||||||
|
@ -2171,6 +2217,60 @@ public:
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DBUS_SIMPLE_AHBLITE3
|
||||||
|
class DBusSimpleAhbLite3 : public SimElement{
|
||||||
|
public:
|
||||||
|
Workspace *ws;
|
||||||
|
VVexRiscv* top;
|
||||||
|
|
||||||
|
uint32_t dBusAhbLite3_HADDR, dBusAhbLite3_HSIZE, dBusAhbLite3_HTRANS, dBusAhbLite3_HWRITE;
|
||||||
|
|
||||||
|
DBusSimpleAhbLite3(Workspace* ws){
|
||||||
|
this->ws = ws;
|
||||||
|
this->top = ws->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onReset(){
|
||||||
|
top->dBusAhbLite3_HREADY = 1;
|
||||||
|
top->dBusAhbLite3_HRESP = 0;
|
||||||
|
dBusAhbLite3_HTRANS = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void preCycle(){
|
||||||
|
if(top->dBusAhbLite3_HREADY && dBusAhbLite3_HTRANS == 2 && dBusAhbLite3_HWRITE){
|
||||||
|
uint32_t data = top->dBusAhbLite3_HWDATA;
|
||||||
|
bool error;
|
||||||
|
ws->dBusAccess(dBusAhbLite3_HADDR, 1, dBusAhbLite3_HSIZE, ((1 << (1 << dBusAhbLite3_HSIZE))-1) << (dBusAhbLite3_HADDR & 0x3),&data,&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top->dBusAhbLite3_HREADY){
|
||||||
|
dBusAhbLite3_HADDR = top->dBusAhbLite3_HADDR ;
|
||||||
|
dBusAhbLite3_HSIZE = top->dBusAhbLite3_HSIZE ;
|
||||||
|
dBusAhbLite3_HTRANS = top->dBusAhbLite3_HTRANS ;
|
||||||
|
dBusAhbLite3_HWRITE = top->dBusAhbLite3_HWRITE ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void postCycle(){
|
||||||
|
if(ws->iStall)
|
||||||
|
top->dBusAhbLite3_HREADY = (!ws->iStall || VL_RANDOM_I(7) < 100);
|
||||||
|
|
||||||
|
top->dBusAhbLite3_HRDATA = VL_RANDOM_I(32);
|
||||||
|
top->dBusAhbLite3_HRESP = VL_RANDOM_I(1);
|
||||||
|
|
||||||
|
if(top->dBusAhbLite3_HREADY && dBusAhbLite3_HTRANS == 2 && !dBusAhbLite3_HWRITE){
|
||||||
|
|
||||||
|
bool error;
|
||||||
|
ws->dBusAccess(dBusAhbLite3_HADDR, 0, dBusAhbLite3_HSIZE, ((1 << (1 << dBusAhbLite3_HSIZE))-1) << (dBusAhbLite3_HADDR & 0x3),&top->dBusAhbLite3_HRDATA,&error);
|
||||||
|
top->dBusAhbLite3_HRESP = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE)
|
#if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE)
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
@ -2639,6 +2739,11 @@ void Workspace::fillSimELements(){
|
||||||
#ifdef IBUS_SIMPLE_AVALON
|
#ifdef IBUS_SIMPLE_AVALON
|
||||||
simElements.push_back(new IBusSimpleAvalon(this));
|
simElements.push_back(new IBusSimpleAvalon(this));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef IBUS_SIMPLE_AHBLITE3
|
||||||
|
simElements.push_back(new IBusSimpleAhbLite3(this));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef IBUS_CACHED
|
#ifdef IBUS_CACHED
|
||||||
simElements.push_back(new IBusCached(this));
|
simElements.push_back(new IBusCached(this));
|
||||||
#endif
|
#endif
|
||||||
|
@ -2659,6 +2764,9 @@ void Workspace::fillSimELements(){
|
||||||
#ifdef DBUS_SIMPLE_AVALON
|
#ifdef DBUS_SIMPLE_AVALON
|
||||||
simElements.push_back(new DBusSimpleAvalon(this));
|
simElements.push_back(new DBusSimpleAvalon(this));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DBUS_SIMPLE_AHBLITE3
|
||||||
|
simElements.push_back(new DBusSimpleAhbLite3(this));
|
||||||
|
#endif
|
||||||
#ifdef DBUS_CACHED
|
#ifdef DBUS_CACHED
|
||||||
simElements.push_back(new DBusCached(this));
|
simElements.push_back(new DBusCached(this));
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue