diff --git a/src/main/scala/vexriscv/demo/VexRiscvAvalon.scala b/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala similarity index 94% rename from src/main/scala/vexriscv/demo/VexRiscvAvalon.scala rename to src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala index 8e9637c..ed49d4d 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvAvalon.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala @@ -18,14 +18,22 @@ import spinal.lib.eda.altera.{ResetEmitterTag, InterruptReceiverTag, QSysify} //} -object VexRiscvAvalon{ +object VexRiscvAvalonForSim{ def main(args: Array[String]) { - val report = SpinalVhdl{ + 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( config = InstructionCacheConfig( cacheSize = 4096, @@ -127,7 +135,7 @@ object VexRiscvAvalon{ val cpu = new VexRiscv(cpuConfig) //CPU modifications to be an Avalon one - cpu.setDefinitionName("VexRiscvAvalon") + //cpu.setDefinitionName("VexRiscvAvalon") cpu.rework { var iBus : AvalonMM = null for (plugin <- cpuConfig.plugins) plugin match { diff --git a/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala b/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala new file mode 100644 index 0000000..a23b2df --- /dev/null +++ b/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala @@ -0,0 +1,192 @@ +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{ +// +//} + + +object VexRiscvAvalonWithIntegratedJtag{ + 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( + config = InstructionCacheConfig( + cacheSize = 4096, + bytePerLine =32, + wayCount = 1, + wrappedMemAccess = true, + addressWidth = 32, + cpuDataWidth = 32, + memDataWidth = 32, + catchIllegalAccess = true, + catchAccessFault = true, + catchMemoryTranslationMiss = true, + asyncTagMemory = false, + twoStageLogic = 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, + prediction = STATIC + ), + 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, + wfiGen = 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.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 + 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.asDirectionLess() + master(plugin.dBus.toAvalon()) + .setName("dBusAvalon") + .addTag(ClockDomainTag(ClockDomain.current)) + } + case plugin: DBusCachedPlugin => { + plugin.dBus.asDirectionLess() + master(plugin.dBus.toAvalon()) + .setName("dBusAvalon") + .addTag(ClockDomainTag(ClockDomain.current)) + } + case plugin: DebugPlugin => { + plugin.io.bus.asDirectionLess() + val jtag = slave(new Jtag()) + .setName("jtag") + jtag <> plugin.io.bus.fromJtag() + 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) + } +} \ No newline at end of file diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index 56fd577..64cd5ce 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -73,7 +73,7 @@ case class DebugExtensionBus() extends Bundle with IMasterSlave{ debugger.io.mem.cmd.valid <> cmd.valid debugger.io.mem.cmd.ready <> cmd.ready debugger.io.mem.cmd.wr <> cmd.wr - debugger.io.mem.cmd.address.resized <> cmd.address + cmd.address := debugger.io.mem.cmd.address.resized debugger.io.mem.cmd.data <> cmd.data debugger.io.mem.rsp.valid <> RegNext(cmd.fire).init(False) debugger.io.mem.rsp.payload <> rsp.data