From 0255f51cc53be867a513a0ef3b088a6fced5d97e Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 24 Aug 2018 12:20:14 +0200 Subject: [PATCH] Add unpipelined Wishbone support for uncached version --- .../demo/VexRiscvCachedWishboneForSim.scala | 40 +++------ .../vexriscv/plugin/DBusSimplePlugin.scala | 48 ++++++++++- .../vexriscv/plugin/IBusSimplePlugin.scala | 39 +++++++++ src/test/cpp/regression/main.cpp | 84 ++++++++++++------- 4 files changed, 152 insertions(+), 59 deletions(-) diff --git a/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala b/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala index ac72b40..35cad08 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvCachedWishboneForSim.scala @@ -24,16 +24,16 @@ object VexRiscvCachedWishboneForSim{ //CPU configuration val cpuConfig = VexRiscvConfig( plugins = List( - new PcManagerSimplePlugin(0x00000000l, false), // new IBusSimplePlugin( -// interfaceKeepData = false, -// catchAccessFault = false +// resetVector = 0x80000000l, +// prediction = STATIC // ), // new DBusSimplePlugin( // catchAddressMisaligned = false, // catchAccessFault = false // ), new IBusCachedPlugin( + resetVector = 0x80000000l, prediction = STATIC, config = InstructionCacheConfig( cacheSize = 4096, @@ -79,7 +79,7 @@ object VexRiscvCachedWishboneForSim{ ), new RegFilePlugin( regFileReadyKind = plugin.SYNC, - zeroBoot = false + zeroBoot = true ), new IntAluPlugin, new SrcPlugin( @@ -117,36 +117,22 @@ object VexRiscvCachedWishboneForSim{ //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 => { + case plugin: IBusSimplePlugin => { 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: IBusCachedPlugin => { + plugin.iBus.asDirectionLess() + master(plugin.iBus.toWishbone()).setName("iBusWishbone") + } + case plugin: DBusSimplePlugin => { + plugin.dBus.asDirectionLess() + master(plugin.dBus.toWishbone()).setName("dBusWishbone") + } 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 _ => } } diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index 060dcca..94bd560 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -4,7 +4,9 @@ import vexriscv._ import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba4.axi._ -import spinal.lib.bus.avalon.{AvalonMMConfig, AvalonMM} +import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig} +import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig} +import vexriscv.ip.DataCacheMemCmd case class DBusSimpleCmd() extends Bundle{ @@ -45,6 +47,21 @@ object DBusSimpleBus{ useResponse = true, maximumPendingReadTransactions = 1 ) + + def getWishboneConfig() = WishboneConfig( + addressWidth = 30, + dataWidth = 32, + selWidth = 4, + useSTALL = false, + useLOCK = false, + useERR = true, + useRTY = false, + tgaWidth = 0, + tgcWidth = 0, + tgdWidth = 0, + useBTE = true, + useCTI = true + ) } case class DBusSimpleBus() extends Bundle with IMasterSlave{ @@ -133,6 +150,35 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ mm } + + def toWishbone(): Wishbone = { + val wishboneConfig = DBusSimpleBus.getWishboneConfig() + val bus = Wishbone(wishboneConfig) + val cmdStage = cmd.halfPipe() + + bus.ADR := cmdStage.address >> 2 + bus.CTI :=B"000" + bus.BTE := "00" + bus.SEL := (cmdStage.size.mux ( + U(0) -> B"0001", + U(1) -> B"0011", + default -> B"1111" + ) << cmdStage.address(1 downto 0)).resized + when(!cmdStage.wr) { + bus.SEL := "1111" + } + bus.WE := cmdStage.wr + bus.DAT_MOSI := cmdStage.data + + cmdStage.ready := cmdStage.valid && bus.ACK + bus.CYC := cmdStage.valid + bus.STB := cmdStage.valid + + rsp.ready := cmdStage.valid && !bus.WE && bus.ACK + rsp.data := bus.DAT_MISO + rsp.error := False //TODO + bus + } } diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index 57dbdff..523a2ef 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -5,6 +5,7 @@ import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba4.axi._ import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig} +import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig} @@ -43,6 +44,21 @@ object IBusSimpleBus{ useResponse = true, maximumPendingReadTransactions = 8 ) + + def getWishboneConfig() = WishboneConfig( + addressWidth = 30, + dataWidth = 32, + selWidth = 4, + useSTALL = false, + useLOCK = false, + useERR = true, + useRTY = false, + tgaWidth = 0, + tgcWidth = 0, + tgdWidth = 0, + useBTE = true, + useCTI = true + ) } @@ -96,6 +112,29 @@ case class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMaste mm } + + def toWishbone(): Wishbone = { + val wishboneConfig = IBusSimpleBus.getWishboneConfig() + val bus = Wishbone(wishboneConfig) + val cmdPipe = cmd.stage() + + bus.ADR := (cmdPipe.pc >> 2) + bus.CTI := B"000" + bus.BTE := "00" + bus.SEL := "1111" + bus.WE := False + bus.DAT_MOSI.assignDontCare() + bus.CYC := cmdPipe.valid + bus.STB := cmdPipe.valid + + + cmdPipe.ready := cmdPipe.valid && bus.ACK + rsp.valid := bus.CYC && bus.ACK + rsp.inst := bus.DAT_MISO + rsp.error := False //TODO + bus + } + } diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 3c7f677..40478de 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -624,6 +624,8 @@ public: bool error; }; + uint32_t periphWriteTimer = 0; + queue periphWritesGolden; queue periphWrites; queue periphRead; Workspace *ws; @@ -663,11 +665,11 @@ public: } virtual void dWrite(int32_t address, int32_t size, uint32_t data){ if((address & 0xF0000000) == 0xF0000000){ - MemWrite t = periphWrites.front(); - if(t.address != address || t.size != size || t.data != data){ - fail(); - } - periphWrites.pop(); + MemWrite w; + w.address = address; + w.size = size; + w.data = data; + periphWritesGolden.push(w); }else { mem.write(address, size, (uint8_t*)&data); } @@ -677,6 +679,23 @@ public: void step() { rfWriteValid = false; RiscvGolden::step(); + + switch(periphWrites.empty() + uint32_t(periphWritesGolden.empty())*2){ + case 3: periphWriteTimer = 0; break; + case 1: case 2: if(periphWriteTimer++ == 20){ cout << "periphWrite timout" << endl; fail();} break; + case 0: + MemWrite t = periphWrites.front(); + MemWrite t2 = periphWritesGolden.front(); + if(t.address != t2.address || t.size != t2.size || t.data != t2.data){ + cout << "periphWrite missmatch" << endl; + fail(); + } + periphWrites.pop(); + periphWritesGolden.pop(); + break; + } + + } }; @@ -903,7 +922,7 @@ public: if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc; #else if(bootPc != -1) { - #ifdef IBUS_SIMPLE + #if defined(IBUS_SIMPLE) || defined(IBUS_SIMPLE_WISHBONE) top->VexRiscv->IBusSimplePlugin_fetchPc_pcReg = bootPc; #ifdef COMPRESSED top->VexRiscv->IBusSimplePlugin_decodePc_pcReg = bootPc; @@ -1261,10 +1280,9 @@ public: #endif -#ifdef IBUS_CACHED_WISHBONE +#if defined(IBUS_CACHED_WISHBONE) || defined(IBUS_SIMPLE_WISHBONE) #include - class IBusCachedWishbone : public SimElement{ public: @@ -1282,21 +1300,24 @@ public: } virtual void preCycle(){ - top->iBusWishbone_DAT_MISO = VL_RANDOM_I(32); - if (top->iBusWishbone_CYC && top->iBusWishbone_STB && top->iBusWishbone_ACK) { - if(top->iBusWishbone_WE){ - } else { - bool error; - ws->iBusAccess(top->iBusWishbone_ADR << 2,&top->iBusWishbone_DAT_MISO,&error); - top->iBusWishbone_ERR = error; - } - } } virtual void postCycle(){ + if(ws->iStall) top->iBusWishbone_ACK = VL_RANDOM_I(7) < 100; + + top->iBusWishbone_DAT_MISO = VL_RANDOM_I(32); + if (top->iBusWishbone_CYC && top->iBusWishbone_STB && top->iBusWishbone_ACK) { + if(top->iBusWishbone_WE){ + + } else { + bool error; + ws->iBusAccess(top->iBusWishbone_ADR << 2,&top->iBusWishbone_DAT_MISO,&error); + top->iBusWishbone_ERR = error; + } + } } }; #endif @@ -1398,7 +1419,7 @@ public: }; #endif -#ifdef DBUS_CACHED_WISHBONE +#if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE) #include @@ -1419,22 +1440,23 @@ public: } virtual void preCycle(){ - top->dBusWishbone_DAT_MISO = VL_RANDOM_I(32); - if (top->dBusWishbone_CYC && top->dBusWishbone_STB && top->dBusWishbone_ACK) { - if(top->dBusWishbone_WE){ - bool dummy; - ws->dBusAccess(top->dBusWishbone_ADR << 2 ,1,2,top->dBusWishbone_SEL,&top->dBusWishbone_DAT_MOSI,&dummy); - } else { - bool error; - ws->dBusAccess(top->dBusWishbone_ADR << 2,0,2,0xF,&top->dBusWishbone_DAT_MISO,&error); - top->dBusWishbone_ERR = error; - } - } + } virtual void postCycle(){ if(ws->iStall) top->dBusWishbone_ACK = VL_RANDOM_I(7) < 100; + top->dBusWishbone_DAT_MISO = VL_RANDOM_I(32); + if (top->dBusWishbone_CYC && top->dBusWishbone_STB && top->dBusWishbone_ACK) { + if(top->dBusWishbone_WE){ + bool dummy; + ws->dBusAccess(top->dBusWishbone_ADR << 2 ,1,2,top->dBusWishbone_SEL,&top->dBusWishbone_DAT_MOSI,&dummy); + } else { + bool error; + ws->dBusAccess(top->dBusWishbone_ADR << 2,0,2,0xF,&top->dBusWishbone_DAT_MISO,&error); + top->dBusWishbone_ERR = error; + } + } } }; #endif @@ -1871,7 +1893,7 @@ void Workspace::fillSimELements(){ #ifdef IBUS_CACHED_AVALON simElements.push_back(new IBusCachedAvalon(this)); #endif - #ifdef IBUS_CACHED_WISHBONE + #if defined(IBUS_CACHED_WISHBONE) || defined(IBUS_SIMPLE_WISHBONE) simElements.push_back(new IBusCachedWishbone(this)); #endif #ifdef DBUS_SIMPLE @@ -1886,7 +1908,7 @@ void Workspace::fillSimELements(){ #ifdef DBUS_CACHED_AVALON simElements.push_back(new DBusCachedAvalon(this)); #endif - #ifdef DBUS_CACHED_WISHBONE + #if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE) simElements.push_back(new DBusCachedWishbone(this)); #endif #ifdef DEBUG_PLUGIN_STD