Add unpipelined Wishbone support for uncached version
This commit is contained in:
parent
304c8156a0
commit
0255f51cc5
|
@ -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 _ =>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -624,6 +624,8 @@ public:
|
|||
bool error;
|
||||
};
|
||||
|
||||
uint32_t periphWriteTimer = 0;
|
||||
queue<MemWrite> periphWritesGolden;
|
||||
queue<MemWrite> periphWrites;
|
||||
queue<MemRead> 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 <queue>
|
||||
|
||||
|
||||
class IBusCachedWishbone : public SimElement{
|
||||
public:
|
||||
|
||||
|
@ -1282,6 +1300,14 @@ public:
|
|||
}
|
||||
|
||||
virtual void preCycle(){
|
||||
|
||||
}
|
||||
|
||||
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){
|
||||
|
@ -1293,11 +1319,6 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void postCycle(){
|
||||
if(ws->iStall)
|
||||
top->iBusWishbone_ACK = VL_RANDOM_I(7) < 100;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1398,7 +1419,7 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef DBUS_CACHED_WISHBONE
|
||||
#if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE)
|
||||
#include <queue>
|
||||
|
||||
|
||||
|
@ -1419,6 +1440,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void preCycle(){
|
||||
|
||||
}
|
||||
|
||||
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){
|
||||
|
@ -1431,11 +1458,6 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void postCycle(){
|
||||
if(ws->iStall)
|
||||
top->dBusWishbone_ACK = VL_RANDOM_I(7) < 100;
|
||||
}
|
||||
};
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue