diff --git a/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala b/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala new file mode 100644 index 0000000..3663098 --- /dev/null +++ b/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala @@ -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_AVALON IBUS=CACHED_AVALON MMU=no CSR=no DEBUG_PLUGIN=AVALON + +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( + 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, + prediction = STATIC + ), + 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) + } +} \ No newline at end of file diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 231dd8c..bde7b6f 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -334,10 +334,8 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave bus.DAT_MOSI := cmdBridge.data cmdBridge.ready := bus.ACK - when(cmdBridge.valid) { - bus.CYC := True - bus.STB := True - } + bus.CYC := cmdBridge.valid + bus.STB := cmdBridge.valid rsp.valid := RegNext(bus.WE && bus.ACK) init(False) rsp.data := RegNext(bus.DAT_MISO) diff --git a/src/main/scala/vexriscv/ip/InstructionCache.scala b/src/main/scala/vexriscv/ip/InstructionCache.scala index 03b6f2c..62b9709 100644 --- a/src/main/scala/vexriscv/ip/InstructionCache.scala +++ b/src/main/scala/vexriscv/ip/InstructionCache.scala @@ -178,6 +178,8 @@ case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle wit 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