mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-04-24 14:07:54 -04:00
195 lines
6.9 KiB
Scala
195 lines
6.9 KiB
Scala
package vexriscv.demo
|
|
|
|
import vexriscv.plugin._
|
|
import vexriscv.{VexRiscv, plugin, VexRiscvConfig}
|
|
import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig}
|
|
import spinal.core._
|
|
import spinal.lib._
|
|
import spinal.lib.bus.amba3.apb.Apb3
|
|
import spinal.lib.bus.amba4.axi.{Axi4Shared, Axi4ReadOnly}
|
|
import spinal.lib.bus.avalon.AvalonMM
|
|
import spinal.lib.eda.altera.{ResetEmitterTag, InterruptReceiverTag, QSysify}
|
|
|
|
/**
|
|
* Created by spinalvm on 14.07.17.
|
|
*/
|
|
//class VexRiscvAvalon(debugClockDomain : ClockDomain) extends Component{
|
|
//
|
|
//}
|
|
|
|
//make clean run DBUS=CACHED_AVALON IBUS=CACHED_AVALON MMU=no CSR=no DEBUG_PLUGIN=AVALON
|
|
|
|
object VexRiscvAvalonForSim{
|
|
def main(args: Array[String]) {
|
|
val report = SpinalVerilog{
|
|
|
|
//CPU configuration
|
|
val cpuConfig = VexRiscvConfig(
|
|
plugins = List(
|
|
/* new IBusSimplePlugin(
|
|
resetVector = 0x00000000l,
|
|
cmdForkOnSecondStage = false,
|
|
cmdForkPersistence = false,
|
|
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,
|
|
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
|
|
),
|
|
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 Avalon one
|
|
//cpu.setDefinitionName("VexRiscvAvalon")
|
|
cpu.rework {
|
|
var iBus : AvalonMM = null
|
|
for (plugin <- cpuConfig.plugins) plugin match {
|
|
case plugin: IBusSimplePlugin => {
|
|
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: 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: DBusSimplePlugin => {
|
|
plugin.dBus.setAsDirectionLess()
|
|
master(plugin.dBus.toAvalon())
|
|
.setName("dBusAvalon")
|
|
.addTag(ClockDomainTag(ClockDomain.current))
|
|
}
|
|
case plugin: DBusCachedPlugin => {
|
|
plugin.dBus.setAsDirectionLess()
|
|
master(plugin.dBus.toAvalon())
|
|
.setName("dBusAvalon")
|
|
.addTag(ClockDomainTag(ClockDomain.current))
|
|
}
|
|
case plugin: DebugPlugin => plugin.debugClockDomain {
|
|
plugin.io.bus.setAsDirectionLess()
|
|
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 _ =>
|
|
}
|
|
for (plugin <- cpuConfig.plugins) plugin match {
|
|
case plugin: CsrPlugin => {
|
|
plugin.externalInterrupt
|
|
.addTag(InterruptReceiverTag(iBus, ClockDomain.current))
|
|
plugin.timerInterrupt
|
|
.addTag(InterruptReceiverTag(iBus, ClockDomain.current))
|
|
}
|
|
case _ =>
|
|
}
|
|
}
|
|
cpu
|
|
}
|
|
|
|
//Generate the QSys TCL script to integrate the CPU
|
|
QSysify(report.toplevel)
|
|
}
|
|
}
|
|
|