From d3dcfcec06e0468f3983687e071abe0e47cf172f Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Fri, 14 Jul 2017 18:04:41 +0200 Subject: [PATCH] Add toAvalon bridge to cached bus Add VexRiscvAvalon demo --- README.md | 2 + src/main/scala/VexRiscv/demo/Briey.scala | 2 + .../scala/VexRiscv/demo/VexRiscvAvalon.scala | 141 ++++++++++++++++++ src/main/scala/VexRiscv/ip/DataCache.scala | 30 ++++ .../scala/VexRiscv/ip/InstructionCache.scala | 23 +++ src/test/cpp/briey/main.cpp | 19 ++- src/test/cpp/briey/wip.gtkw | 68 ++------- 7 files changed, 232 insertions(+), 53 deletions(-) create mode 100644 src/main/scala/VexRiscv/demo/VexRiscvAvalon.scala diff --git a/README.md b/README.md index 8c0bcb8..0bbfbdc 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,9 @@ continue You can use the eclipse + zilin embedded CDT plugin to do it. ## Briey SoC + As a demonstrator, a SoC named Briey is implemented in src/main/scala/VexRiscv/demo/Briey.scala. This SoC is very similar to the Pinsec one : + diff --git a/src/main/scala/VexRiscv/demo/Briey.scala b/src/main/scala/VexRiscv/demo/Briey.scala index 332f0d7..83e7a85 100644 --- a/src/main/scala/VexRiscv/demo/Briey.scala +++ b/src/main/scala/VexRiscv/demo/Briey.scala @@ -391,6 +391,8 @@ object Briey{ 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) toplevel }) } diff --git a/src/main/scala/VexRiscv/demo/VexRiscvAvalon.scala b/src/main/scala/VexRiscv/demo/VexRiscvAvalon.scala new file mode 100644 index 0000000..0603174 --- /dev/null +++ b/src/main/scala/VexRiscv/demo/VexRiscvAvalon.scala @@ -0,0 +1,141 @@ +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} + +/** + * Created by spinalvm on 14.07.17. + */ +//class VexRiscvAvalon(debugClockDomain : ClockDomain) extends Component{ +// +//} + + +object VexRiscvAvalon{ + def main(args: Array[String]) { + SpinalVhdl{ + val configLight = VexRiscvConfig( + plugins = List( + new PcManagerSimplePlugin(0x00000000l, 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") + ) + ) + + val cpu = new VexRiscv(configLight) + + cpu.setDefinitionName("VexRiscvAvalon") + cpu.rework { + for (plugin <- configLight.plugins) plugin match { + case plugin: IBusCachedPlugin => { + plugin.iBus.asDirectionLess() + master(plugin.iBus.toAvalon()).setName("iBusAvalon") + } + case plugin: DBusCachedPlugin => { + plugin.dBus.asDirectionLess() + master(plugin.dBus.toAvalon()).setName("dBusAvalon") + } + case _ => + } + } + cpu + } + } +} \ 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 c262695..7c65371 100644 --- a/src/main/scala/VexRiscv/ip/DataCache.scala +++ b/src/main/scala/VexRiscv/ip/DataCache.scala @@ -4,6 +4,7 @@ import VexRiscv._ import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba4.axi.{Axi4Shared, Axi4Config} +import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig} case class DataCacheConfig( cacheSize : Int, @@ -32,6 +33,16 @@ case class DataCacheConfig( cacheSize : Int, useLock = false, useQos = false ) + + def getAvalonConfig() = AvalonMMConfig.bursted( + addressWidth = addressWidth, + dataWidth = memDataWidth, + burstCountWidth = log2Up(burstSize + 1)).copy( + useByteEnable = true, + constantBurstBehavior = true, + burstOnBurstBoundariesOnly = true, + maximumPendingReadTransactions = 2 + ) } @@ -249,6 +260,25 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave axi2 << axi axi2 } + + + def toAvalon(): AvalonMM = { + val avalonConfig = p.getAvalonConfig() + val mm = AvalonMM(avalonConfig) + mm.read := cmd.valid && !cmd.wr + mm.write := cmd.valid && cmd.wr + mm.address := cmd.address(cmd.address.high downto log2Up(p.memDataWidth/8)) @@ U(0,log2Up(p.memDataWidth/8) bits) + mm.burstCount := cmd.length + U(1, widthOf(mm.burstCount) bits) + mm.byteEnable := cmd.mask + mm.writeData := cmd.data + + cmd.ready := mm.waitRequestn + rsp.valid := mm.readDataValid + rsp.data := mm.readData + rsp.error := False + + mm + } } diff --git a/src/main/scala/VexRiscv/ip/InstructionCache.scala b/src/main/scala/VexRiscv/ip/InstructionCache.scala index eb70afd..63a5f5c 100644 --- a/src/main/scala/VexRiscv/ip/InstructionCache.scala +++ b/src/main/scala/VexRiscv/ip/InstructionCache.scala @@ -4,6 +4,7 @@ import VexRiscv._ import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba4.axi.{Axi4ReadOnly, Axi4Config} +import spinal.lib.bus.avalon.{AvalonMMConfig, AvalonMM} case class InstructionCacheConfig( cacheSize : Int, @@ -30,6 +31,15 @@ case class InstructionCacheConfig( cacheSize : Int, useQos = false, useSize = false ) + + def getAvalonConfig() = AvalonMMConfig.bursted( + addressWidth = addressWidth, + dataWidth = memDataWidth, + burstCountWidth = log2Up(burstSize + 1)).getReadOnlyConfig.copy( + linewrapBursts = wrappedMemAccess, + constantBurstBehavior = true + ) + } @@ -134,6 +144,19 @@ case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle wit mm.readRsp.ready := True mm } + + def toAvalon(): AvalonMM = { + val avalonConfig = p.getAvalonConfig() + val mm = AvalonMM(avalonConfig) + mm.read := cmd.valid + mm.burstCount := U(p.burstSize) + mm.address := cmd.address + cmd.ready := mm.waitRequestn + rsp.valid := mm.readDataValid + rsp.data := mm.readData + rsp.error := False + mm + } } diff --git a/src/test/cpp/briey/main.cpp b/src/test/cpp/briey/main.cpp index 04b1844..aaef9c3 100644 --- a/src/test/cpp/briey/main.cpp +++ b/src/test/cpp/briey/main.cpp @@ -1,5 +1,7 @@ #include "VBriey.h" #include "VBriey_Briey.h" +//#include "VBriey_Axi4VgaCtrl.h" +//#include "VBriey_VgaCtrl.h" #ifdef REF #include "VBriey_RiscvCore.h" #endif @@ -357,7 +359,7 @@ public: virtual void fail(){ throw std::exception();} virtual void fillSimELements(); - void dump(uint64_t i){ + virtual void dump(uint64_t i){ #ifdef TRACE if(i >= TRACE_START) tfp->dump(i); #endif @@ -834,6 +836,7 @@ public: SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); + memset(pixels, 0, width * height * sizeof(Uint32)); } virtual void postCycle(){ @@ -928,6 +931,20 @@ public: } + /*bool trigged = false; + uint32_t frameStartCounter = 0; + virtual void dump(uint64_t i){ + if(!trigged) { + if(top->Briey->axi_vgaCtrl->vga_ctrl->io_frameStart) { + frameStartCounter++; + if(frameStartCounter < 3*32) cout << "**\n" << endl; + } + if(top->Briey->axi_vgaCtrl->vga_ctrl->io_error && frameStartCounter > 3*32) trigged = true; + } + if(trigged)Workspace::dump(i); + }*/ + + }; diff --git a/src/test/cpp/briey/wip.gtkw b/src/test/cpp/briey/wip.gtkw index 29848a1..b26d6e2 100644 --- a/src/test/cpp/briey/wip.gtkw +++ b/src/test/cpp/briey/wip.gtkw @@ -1,66 +1,30 @@ [*] [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Sat Jul 8 21:52:29 2017 +[*] Sun Jul 9 22:38:21 2017 [*] [dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/briey/Briey.vcd" -[dumpfile_mtime] "Sat Jul 8 21:52:14 2017" -[dumpfile_size] 1407698718 +[dumpfile_mtime] "Sun Jul 9 22:38:03 2017" +[dumpfile_size] 1880556694 [savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/briey/wip.gtkw" -[timestart] 24655083000 +[timestart] 225385490000 [size] 1776 953 -[pos] -1 -1 -*-18.000000 24656341000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[pos] -775 -1 +*-24.000000 225374620001 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] TOP. [treeopen] TOP.Briey. [treeopen] TOP.Briey.axi_vgaCtrl. -[sst_width] 201 -[signals_width] 356 +[sst_width] 358 +[signals_width] 150 [sst_expanded] 1 [sst_vpaned_height] 279 -@23 -TOP.Briey.axi_vgaCtrl.io_apb_PADDR[7:0] @28 -TOP.Briey.axi_vgaCtrl.io_apb_PENABLE -@22 -TOP.Briey.axi_vgaCtrl.io_apb_PRDATA[31:0] -@28 -TOP.Briey.axi_vgaCtrl.io_apb_PREADY -TOP.Briey.axi_vgaCtrl.io_apb_PSEL[0] -@22 -TOP.Briey.axi_vgaCtrl.io_apb_PWDATA[31:0] -@28 -TOP.Briey.axi_vgaCtrl.io_apb_PWRITE -TOP.Briey.axi_vgaCtrl.io_axiClk -@22 -TOP.Briey.axi_vgaCtrl.io_axi_ar_payload_addr[31:0] -TOP.Briey.axi_vgaCtrl.io_axi_ar_payload_len[7:0] -@28 -TOP.Briey.axi_vgaCtrl.io_axi_ar_payload_size[2:0] -TOP.Briey.axi_vgaCtrl.io_axi_ar_ready -TOP.Briey.axi_vgaCtrl.io_axi_ar_valid -@22 -TOP.Briey.axi_vgaCtrl.io_axi_r_payload_data[31:0] -@28 -TOP.Briey.axi_vgaCtrl.io_axi_r_payload_last -TOP.Briey.axi_vgaCtrl.io_axi_r_ready -TOP.Briey.axi_vgaCtrl.io_axi_r_valid -TOP.Briey.axi_vgaCtrl.io_vgaClk -TOP.Briey.axi_vgaCtrl.io_vga_colorEn -@22 -TOP.Briey.axi_vgaCtrl.io_vga_color_b[4:0] -TOP.Briey.axi_vgaCtrl.io_vga_color_g[5:0] -TOP.Briey.axi_vgaCtrl.io_vga_color_r[4:0] -@28 -TOP.Briey.axi_vgaCtrl.io_vga_hSync -TOP.Briey.axi_vgaCtrl.io_vga_vSync -@22 -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_h_colorEnd[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_h_colorStart[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_h_syncEnd[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_h_syncStart[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_v_colorEnd[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_v_colorStart[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_v_syncEnd[11:0] -TOP.Briey.axi_vgaCtrl.vga_ctrl.io_timings_v_syncStart[11:0] +TOP.Briey.axi_vgaCtrl.vga_ctrl.io_frameStart +TOP.Briey.axi_vgaCtrl.vga_ctrl.io_pixels_ready +TOP.Briey.axi_vgaCtrl.vga_ctrl.io_pixels_valid +TOP.Briey.axi_vgaCtrl.vga_ctrl.io_softReset +TOP.Briey.axi_vgaCtrl.vga_ctrl.io_vgaClk +TOP.Briey.axi_vgaCtrl.vga_ctrl.io_vga_colorEn +@29 +TOP.Briey.axi_vgaCtrl.vga_run [pattern_trace] 1 [pattern_trace] 0