Add LitexSoC workspace / linux loading. Need to emulate peripherals and adapte the kernel now. Probably also need some machine mode emulation Software time !
This commit is contained in:
parent
0656a49332
commit
6c0608f0dd
|
@ -26,8 +26,25 @@ import vexriscv._
|
|||
import vexriscv.ip._
|
||||
import vexriscv.plugin._
|
||||
|
||||
/*
|
||||
Setup things =>
|
||||
git clone https://github.com/SpinalHDL/SpinalHDL.git -b dev
|
||||
git clone https://github.com/SpinalHDL/VexRiscv.git -b linux
|
||||
cd VexRiscv
|
||||
|
||||
Run regressions =>
|
||||
sbt "runMain vexriscv.demo.LinuxGen -r"
|
||||
cd src/test/cpp/regression
|
||||
make run DBUS=SIMPLE IBUS=SIMPLE DHRYSTONE=yes SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=10 TRACE=no
|
||||
|
||||
Run linux =>
|
||||
sbt "runMain vexriscv.demo.LinuxGen"
|
||||
cd src/test/cpp/regression
|
||||
make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes VMLINUX=/home/spinalvm/hdl/linuxDave/vmlinux.bin RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=no
|
||||
*/
|
||||
|
||||
object LinuxGen {
|
||||
def configFull(withMmu : Boolean = true) = {
|
||||
def configFull(litex : Boolean, withMmu : Boolean) = {
|
||||
val config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new IBusSimplePlugin(
|
||||
|
@ -171,15 +188,15 @@ object LinuxGen {
|
|||
)
|
||||
if(withMmu) config.plugins += new MmuPlugin(
|
||||
virtualRange = a => True,
|
||||
ioRange = _(31 downto 28) === 0xF,
|
||||
ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE else x(31 downto 28) === 0xF),
|
||||
allowUserIo = true
|
||||
)
|
||||
config
|
||||
}
|
||||
|
||||
|
||||
|
||||
def main(args: Array[String]) {
|
||||
|
||||
|
||||
|
||||
// import spinal.core.sim._
|
||||
// SimConfig.withConfig(SpinalConfig(mergeAsyncProcess = false, anonymSignalPrefix = "zz_")).allOptimisation.compile(new VexRiscv(configFull)).doSimUntilVoid{ dut =>
|
||||
// dut.clockDomain.forkStimulus(10)
|
||||
|
@ -199,7 +216,10 @@ object LinuxGen {
|
|||
SpinalConfig(mergeAsyncProcess = true).generateVerilog {
|
||||
|
||||
|
||||
val toplevel = new VexRiscv(configFull())
|
||||
val toplevel = new VexRiscv(configFull(
|
||||
litex = !args.contains("-r"),
|
||||
withMmu = true
|
||||
))
|
||||
// val toplevel = new VexRiscv(configLight)
|
||||
// val toplevel = new VexRiscv(configTest)
|
||||
|
||||
|
@ -288,13 +308,13 @@ object LinuxSyntesisBench extends App{
|
|||
val withoutMmu = new Rtl {
|
||||
override def getName(): String = "VexRiscv Without Mmu"
|
||||
override def getRtlPath(): String = "VexRiscvWithoutMmu.v"
|
||||
SpinalVerilog(new VexRiscv(LinuxGen.configFull(withMmu=false)).setDefinitionName(getRtlPath().split("\\.").head))
|
||||
SpinalVerilog(new VexRiscv(LinuxGen.configFull(litex = false, withMmu = false)).setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
val withMmu = new Rtl {
|
||||
override def getName(): String = "VexRiscv With Mmu"
|
||||
override def getRtlPath(): String = "VexRiscvWithMmu.v"
|
||||
SpinalVerilog(new VexRiscv(LinuxGen.configFull(withMmu=true)).setDefinitionName(getRtlPath().split("\\.").head))
|
||||
SpinalVerilog(new VexRiscv(LinuxGen.configFull(litex = false, withMmu = true)).setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
val rtls = List(withoutMmu, withMmu)
|
||||
|
@ -316,7 +336,7 @@ object LinuxSyntesisBench extends App{
|
|||
object LinuxSim extends App{
|
||||
import spinal.core.sim._
|
||||
|
||||
SimConfig.allOptimisation.compile(new VexRiscv(LinuxGen.configFull())).doSim{dut =>
|
||||
SimConfig.allOptimisation.compile(new VexRiscv(LinuxGen.configFull(litex = false, withMmu = true))).doSim{dut =>
|
||||
// dut.clockDomain.forkStimulus(10)
|
||||
// dut.clockDomain.forkSimSpeedPrinter()
|
||||
// dut.plugins.foreach{
|
||||
|
|
|
@ -151,6 +151,26 @@ void loadHexImpl(string path,Memory* mem) {
|
|||
delete [] content;
|
||||
}
|
||||
|
||||
void loadBinImpl(string path,Memory* mem, uint32_t offset) {
|
||||
FILE *fp = fopen(&path[0], "r");
|
||||
if(fp == 0){
|
||||
cout << path << " not found" << endl;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* content = new char[size];
|
||||
fread(content, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
for(int byteId = 0; byteId < size;byteId++){
|
||||
*(mem->get(offset + byteId)) = content[byteId];
|
||||
}
|
||||
|
||||
delete [] content;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define TEXTIFY(A) #A
|
||||
|
@ -965,8 +985,8 @@ public:
|
|||
uint32_t seed;
|
||||
|
||||
bool withInstructionReadCheck = true;
|
||||
void setIStall(bool enable) { iStall = enable; }
|
||||
void setDStall(bool enable) { dStall = enable; }
|
||||
Workspace* setIStall(bool enable) { iStall = enable; return this; }
|
||||
Workspace* setDStall(bool enable) { dStall = enable; return this; }
|
||||
|
||||
ofstream regTraces;
|
||||
ofstream memTraces;
|
||||
|
@ -1027,7 +1047,7 @@ public:
|
|||
}
|
||||
if(address & (size-1) != 0)
|
||||
cout << "Ref did a unaligned read" << endl;
|
||||
if((address & 0xF0000000) == 0xF0000000){
|
||||
if(ws->isPerifRegion(address)){
|
||||
MemRead t = periphRead.front();
|
||||
if(t.address != address || t.size != size){
|
||||
fail();
|
||||
|
@ -1043,7 +1063,7 @@ public:
|
|||
virtual void dWrite(int32_t address, int32_t size, uint32_t data){
|
||||
if(address & (size-1) != 0)
|
||||
cout << "Ref did a unaligned write" << endl;
|
||||
if((address & 0xF0000000) == 0xF0000000){
|
||||
if(ws->isPerifRegion(address)){
|
||||
MemWrite w;
|
||||
w.address = address;
|
||||
w.size = size;
|
||||
|
@ -1119,6 +1139,12 @@ public:
|
|||
return this;
|
||||
}
|
||||
|
||||
Workspace* loadBin(string path, uint32_t offset){
|
||||
loadBinImpl(path,&mem, offset);
|
||||
loadBinImpl(path,&riscvRef.mem, offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
Workspace* setCyclesPerSecond(double value){
|
||||
cyclesPerSecond = value;
|
||||
return this;
|
||||
|
@ -1135,108 +1161,25 @@ public:
|
|||
return this;
|
||||
}
|
||||
|
||||
void iBusAccess(uint32_t addr, uint32_t *data, bool *error) {
|
||||
virtual bool isPerifRegion(uint32_t addr) { return false; }
|
||||
|
||||
virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) {
|
||||
if(addr % 4 != 0) {
|
||||
//cout << "Warning, unaligned IBusAccess : " << addr << endl;
|
||||
// fail();
|
||||
cout << "Warning, unaligned IBusAccess : " << addr << endl;
|
||||
fail();
|
||||
}
|
||||
*data = ( (mem[addr + 0] << 0)
|
||||
| (mem[addr + 1] << 8)
|
||||
| (mem[addr + 2] << 16)
|
||||
| (mem[addr + 3] << 24));
|
||||
*error = addr == 0xF00FFF60u;
|
||||
iBusAccessPatch(addr,data,error);
|
||||
*error = false;
|
||||
}
|
||||
|
||||
virtual void iBusAccessPatch(uint32_t addr, uint32_t *data, bool *error){}
|
||||
|
||||
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
|
||||
assertEq(addr % (1 << size), 0);
|
||||
*error = addr == 0xF00FFF60u;
|
||||
if(wr){
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) <<
|
||||
#endif
|
||||
" : WRITE mem" << (1 << size) << "[" << addr << "] = " << *data << endl;
|
||||
for(uint32_t b = 0;b < (1 << size);b++){
|
||||
uint32_t offset = (addr+b)&0x3;
|
||||
if((mask >> offset) & 1 == 1)
|
||||
*mem.get(addr + b) = *data >> (offset*8);
|
||||
}
|
||||
|
||||
switch(addr){
|
||||
case 0xF0010000u: {
|
||||
cout << mem[0xF0010000u];
|
||||
logTraces << (char)mem[0xF0010000u];
|
||||
break;
|
||||
}
|
||||
#ifdef EXTERNAL_INTERRUPT
|
||||
case 0xF0011000u: top->externalInterrupt = *data & 1; break;
|
||||
#endif
|
||||
#ifdef SUPERVISOR
|
||||
case 0xF0012000u: top->externalInterruptS = *data & 1; break;
|
||||
#endif
|
||||
#ifdef CSR
|
||||
case 0xF0013000u: top->softwareInterrupt = *data & 1; break;
|
||||
#endif
|
||||
case 0xF00FFF00u: {
|
||||
cout << mem[0xF00FFF00u];
|
||||
logTraces << (char)mem[0xF00FFF00u];
|
||||
break;
|
||||
}
|
||||
#ifndef DEBUG_PLUGIN_EXTERNAL
|
||||
case 0xF00FFF20u:
|
||||
if(*data == 0)
|
||||
pass();
|
||||
else
|
||||
fail();
|
||||
break;
|
||||
case 0xF00FFF24u:
|
||||
cout << "TEST ERROR CODE " << *data << endl;
|
||||
fail();
|
||||
break;
|
||||
#endif
|
||||
case 0xF00FFF48u: mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data;break;
|
||||
case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); /*cout << "mTimeCmp <= " << mTimeCmp << endl; */break;
|
||||
}
|
||||
}else{
|
||||
*data = VL_RANDOM_I(32);
|
||||
for(uint32_t b = 0;b < (1 << size);b++){
|
||||
uint32_t offset = (addr+b)&0x3;
|
||||
*data &= ~(0xFF << (offset*8));
|
||||
*data |= mem[addr + b] << (offset*8);
|
||||
}
|
||||
switch(addr){
|
||||
case 0xF00FFF10u:
|
||||
*data = mTime;
|
||||
#ifdef REF_TIME
|
||||
mTime += 100000;
|
||||
#endif
|
||||
break;
|
||||
case 0xF00FFF40u: *data = mTime; break;
|
||||
case 0xF00FFF44u: *data = mTime >> 32; break;
|
||||
case 0xF00FFF48u: *data = mTimeCmp; break;
|
||||
case 0xF00FFF4Cu: *data = mTimeCmp >> 32; break;
|
||||
case 0xF0010004u: *data = ~0; break;
|
||||
}
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) <<
|
||||
#endif
|
||||
" : READ mem" << (1 << size) << "[" << addr << "] = " << *data << endl;
|
||||
|
||||
}
|
||||
|
||||
if((addr & 0xF0000000) == 0xF0000000){
|
||||
if(isPerifRegion(addr)){
|
||||
if(wr){
|
||||
CpuRef::MemWrite w;
|
||||
w.address = addr;
|
||||
|
@ -1251,8 +1194,61 @@ public:
|
|||
r.error = *error;
|
||||
riscvRef.periphRead.push(r);
|
||||
}
|
||||
} else {
|
||||
if(wr){
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) <<
|
||||
#endif
|
||||
" : WRITE mem" << (1 << size) << "[" << addr << "] = " << *data << endl;
|
||||
for(uint32_t b = 0;b < (1 << size);b++){
|
||||
uint32_t offset = (addr+b)&0x3;
|
||||
if((mask >> offset) & 1 == 1)
|
||||
*mem.get(addr + b) = *data >> (offset*8);
|
||||
}
|
||||
|
||||
}else{
|
||||
*data = VL_RANDOM_I(32);
|
||||
for(uint32_t b = 0;b < (1 << size);b++){
|
||||
uint32_t offset = (addr+b)&0x3;
|
||||
*data &= ~(0xFF << (offset*8));
|
||||
*data |= mem[addr + b] << (offset*8);
|
||||
}
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) <<
|
||||
#endif
|
||||
" : READ mem" << (1 << size) << "[" << addr << "] = " << *data << endl;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void periphAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error){
|
||||
// if(wr){
|
||||
// CpuRef::MemWrite w;
|
||||
// w.address = addr;
|
||||
// w.size = 1 << size;
|
||||
// w.data = *data;
|
||||
// riscvRef.periphWrites.push(w);
|
||||
// } else {
|
||||
// CpuRef::MemRead r;
|
||||
// r.address = addr;
|
||||
// r.size = 1 << size;
|
||||
// r.data = *data;
|
||||
// r.error = *error;
|
||||
// riscvRef.periphRead.push(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
virtual void postReset() {}
|
||||
virtual void checks(){}
|
||||
virtual void pass(){ throw success();}
|
||||
|
@ -1266,6 +1262,7 @@ public:
|
|||
}
|
||||
Workspace* run(uint64_t timeout = 5000){
|
||||
// cout << "Start " << name << endl;
|
||||
if(timeout == 0) timeout = 0x7FFFFFFFFFFFFFFF;
|
||||
|
||||
currentTime = 4;
|
||||
// init trace dump
|
||||
|
@ -1507,6 +1504,91 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class WorkspaceRegression : public Workspace {
|
||||
public:
|
||||
|
||||
WorkspaceRegression(string name) : Workspace(name){
|
||||
|
||||
}
|
||||
|
||||
virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xF0000000;}
|
||||
|
||||
|
||||
virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error){
|
||||
Workspace::iBusAccess(addr,data,error);
|
||||
*error = addr == 0xF00FFF60u;
|
||||
}
|
||||
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
|
||||
if(wr){
|
||||
switch(addr){
|
||||
case 0xF0010000u: {
|
||||
cout << (char)*data;
|
||||
logTraces << (char)*data;
|
||||
break;
|
||||
}
|
||||
#ifdef EXTERNAL_INTERRUPT
|
||||
case 0xF0011000u: top->externalInterrupt = *data & 1; break;
|
||||
#endif
|
||||
#ifdef SUPERVISOR
|
||||
case 0xF0012000u: top->externalInterruptS = *data & 1; break;
|
||||
#endif
|
||||
#ifdef CSR
|
||||
case 0xF0013000u: top->softwareInterrupt = *data & 1; break;
|
||||
#endif
|
||||
case 0xF00FFF00u: {
|
||||
cout << (char)*data;
|
||||
logTraces << (char)*data;
|
||||
break;
|
||||
}
|
||||
#ifndef DEBUG_PLUGIN_EXTERNAL
|
||||
case 0xF00FFF20u:
|
||||
if(*data == 0)
|
||||
pass();
|
||||
else
|
||||
fail();
|
||||
break;
|
||||
case 0xF00FFF24u:
|
||||
cout << "TEST ERROR CODE " << *data << endl;
|
||||
fail();
|
||||
break;
|
||||
#endif
|
||||
case 0xF00FFF48u: mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data;break;
|
||||
case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); /*cout << "mTimeCmp <= " << mTimeCmp << endl; */break;
|
||||
}
|
||||
}else{
|
||||
switch(addr){
|
||||
case 0xF00FFF10u:
|
||||
*data = mTime;
|
||||
#ifdef REF_TIME
|
||||
mTime += 100000;
|
||||
#endif
|
||||
break;
|
||||
case 0xF00FFF40u: *data = mTime; break;
|
||||
case 0xF00FFF44u: *data = mTime >> 32; break;
|
||||
case 0xF00FFF48u: *data = mTimeCmp; break;
|
||||
case 0xF00FFF4Cu: *data = mTimeCmp >> 32; break;
|
||||
case 0xF0010004u: *data = ~0; break;
|
||||
}
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) <<
|
||||
#endif
|
||||
" : READ mem" << (1 << size) << "[" << addr << "] = " << *data << endl;
|
||||
}
|
||||
|
||||
*error = addr == 0xF00FFF60u;
|
||||
Workspace::dBusAccess(addr,wr,size,mask,data,error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef IBUS_SIMPLE
|
||||
class IBusSimple : public SimElement{
|
||||
|
@ -2407,13 +2489,13 @@ uint32_t regFileWriteRefArray[][2] = {
|
|||
testA2ReagFileWriteRef
|
||||
};
|
||||
|
||||
class TestA : public Workspace{
|
||||
class TestA : public WorkspaceRegression{
|
||||
public:
|
||||
|
||||
|
||||
uint32_t regFileWriteRefIndex = 0;
|
||||
|
||||
TestA() : Workspace("testA") {
|
||||
TestA() : WorkspaceRegression("testA") {
|
||||
loadHex("../../resources/hex/testA.hex");
|
||||
}
|
||||
|
||||
|
@ -2431,13 +2513,13 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class TestX28 : public Workspace{
|
||||
class TestX28 : public WorkspaceRegression{
|
||||
public:
|
||||
uint32_t refIndex = 0;
|
||||
uint32_t *ref;
|
||||
uint32_t refSize;
|
||||
|
||||
TestX28(string name, uint32_t *ref, uint32_t refSize) : Workspace(name) {
|
||||
TestX28(string name, uint32_t *ref, uint32_t refSize) : WorkspaceRegression(name) {
|
||||
this->ref = ref;
|
||||
this->refSize = refSize;
|
||||
loadHex("../../resources/hex/" + name + ".hex");
|
||||
|
@ -2457,9 +2539,9 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class RiscvTest : public Workspace{
|
||||
class RiscvTest : public WorkspaceRegression{
|
||||
public:
|
||||
RiscvTest(string name) : Workspace(name) {
|
||||
RiscvTest(string name) : WorkspaceRegression(name) {
|
||||
loadHex("../../resources/hex/" + name + ".hex");
|
||||
bootAt(0x800000bcu);
|
||||
}
|
||||
|
@ -2494,16 +2576,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void iBusAccessPatch(uint32_t addr, uint32_t *data, bool *error){
|
||||
virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error){
|
||||
WorkspaceRegression::iBusAccess(addr,data,error);
|
||||
if(*data == 0x0ff0000f) *data = 0x00000013;
|
||||
if(*data == 0x00000073) *data = 0x00000013;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
class Dhrystone : public Workspace{
|
||||
class Dhrystone : public WorkspaceRegression{
|
||||
public:
|
||||
string hexName;
|
||||
Dhrystone(string name,string hexName,bool iStall, bool dStall) : Workspace(name) {
|
||||
Dhrystone(string name,string hexName,bool iStall, bool dStall) : WorkspaceRegression(name) {
|
||||
setIStall(iStall);
|
||||
setDStall(dStall);
|
||||
withRiscvRef();
|
||||
|
@ -2543,12 +2626,12 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class Compliance : public Workspace{
|
||||
class Compliance : public WorkspaceRegression{
|
||||
public:
|
||||
string name;
|
||||
ofstream out32;
|
||||
int out32Counter = 0;
|
||||
Compliance(string name) : Workspace(name) {
|
||||
Compliance(string name) : WorkspaceRegression(name) {
|
||||
withRiscvRef();
|
||||
loadHex("../../resources/hex/" + name + ".elf.hex");
|
||||
out32.open (name + ".out32");
|
||||
|
@ -2558,12 +2641,11 @@ public:
|
|||
|
||||
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
|
||||
Workspace::dBusAccess(addr,wr,size,mask,data,error);
|
||||
if(wr && addr == 0xF00FFF2C){
|
||||
out32 << hex << setw(8) << std::setfill('0') << *data << dec;
|
||||
if(++out32Counter % 4 == 0) out32 << "\n";
|
||||
*error = 0;
|
||||
}
|
||||
WorkspaceRegression::dBusAccess(addr,wr,size,mask,data,error);
|
||||
}
|
||||
|
||||
virtual void checks(){
|
||||
|
@ -2621,7 +2703,7 @@ public:
|
|||
#define RISCV_SPINAL_FLAGS_RESET_CLEAR 1<<24
|
||||
#define RISCV_SPINAL_FLAGS_HALT_CLEAR 1<<25
|
||||
|
||||
class DebugPluginTest : public Workspace{
|
||||
class DebugPluginTest : public WorkspaceRegression{
|
||||
public:
|
||||
pthread_t clientThreadId;
|
||||
char buffer[1024];
|
||||
|
@ -2761,7 +2843,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
DebugPluginTest() : Workspace("DebugPluginTest") {
|
||||
DebugPluginTest() : WorkspaceRegression("DebugPluginTest") {
|
||||
loadHex("../../resources/hex/debugPlugin.hex");
|
||||
pthread_create(&clientThreadId, NULL, &clientThreadWrapper, this);
|
||||
noInstructionReadCheck();
|
||||
|
@ -2779,6 +2861,28 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LITEX
|
||||
class LitexSoC : public Workspace{
|
||||
public:
|
||||
|
||||
LitexSoC(string name) : Workspace(name) {
|
||||
|
||||
}
|
||||
|
||||
virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xB0000000 || (addr & 0xF0000000) == 0xE0000000;}
|
||||
|
||||
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
|
||||
switch(addr){
|
||||
//TODO Emulate peripherals here
|
||||
}
|
||||
|
||||
Workspace::dBusAccess(addr,wr,size,mask,data,error);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
string riscvTestMain[] = {
|
||||
//"rv32ui-p-simple",
|
||||
"rv32ui-p-lui",
|
||||
|
@ -3045,17 +3149,30 @@ int main(int argc, char **argv, char **env) {
|
|||
printf("BOOT\n");
|
||||
timespec startedAt = timer_start();
|
||||
|
||||
|
||||
#ifdef LITEX
|
||||
LitexSoC("linux")
|
||||
.withRiscvRef()
|
||||
->loadBin(VMLINUX, 0xc0000000)
|
||||
->loadBin(RAMDISK, 0xc2000000)
|
||||
->setIStall(false) //TODO It currently improve speed but should be removed later
|
||||
->setDStall(false)
|
||||
->bootAt(0xc0000000)
|
||||
->run(0);
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
// #ifdef MMU
|
||||
// redo(REDO,Workspace("mmu").withRiscvRef()->loadHex("../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
// redo(REDO,WorkspaceRegression("mmu").withRiscvRef()->loadHex("../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
// #endif
|
||||
// redo(REDO,Workspace("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
// redo(REDO,WorkspaceRegression("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
// return 0;
|
||||
|
||||
for(int idx = 0;idx < 1;idx++){
|
||||
|
||||
#if defined(DEBUG_PLUGIN_EXTERNAL) || defined(RUN_HEX)
|
||||
{
|
||||
Workspace w("run");
|
||||
WorkspaceRegression w("run");
|
||||
#ifdef RUN_HEX
|
||||
//w.loadHex("/home/spinalvm/hdl/zephyr/zephyrSpinalHdl/samples/synchronization/build/zephyr/zephyr.hex");
|
||||
w.loadHex(RUN_HEX);
|
||||
|
@ -3154,10 +3271,10 @@ int main(int argc, char **argv, char **env) {
|
|||
// #endif
|
||||
|
||||
#ifdef MMU
|
||||
redo(REDO,Workspace("mmu").withRiscvRef()->loadHex("../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
redo(REDO,WorkspaceRegression("mmu").withRiscvRef()->loadHex("../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
#endif
|
||||
#ifdef SUPERVISOR
|
||||
redo(REDO,Workspace("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
redo(REDO,WorkspaceRegression("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3););
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_PLUGIN
|
||||
|
@ -3166,16 +3283,16 @@ int main(int argc, char **argv, char **env) {
|
|||
#endif
|
||||
|
||||
#ifdef CUSTOM_SIMD_ADD
|
||||
redo(REDO,Workspace("custom_simd_add").loadHex("../custom/simd_add/build/custom_simd_add.hex")->bootAt(0x00000000u)->run(50e3););
|
||||
redo(REDO,WorkspaceRegression("custom_simd_add").loadHex("../custom/simd_add/build/custom_simd_add.hex")->bootAt(0x00000000u)->run(50e3););
|
||||
#endif
|
||||
|
||||
#ifdef CUSTOM_CSR
|
||||
redo(REDO,Workspace("custom_csr").loadHex("../custom/custom_csr/build/custom_csr.hex")->bootAt(0x00000000u)->run(50e3););
|
||||
redo(REDO,WorkspaceRegression("custom_csr").loadHex("../custom/custom_csr/build/custom_csr.hex")->bootAt(0x00000000u)->run(50e3););
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ATOMIC
|
||||
redo(REDO,Workspace("atomic").loadHex("../custom/atomic/build/atomic.hex")->bootAt(0x00000000u)->run(10e3););
|
||||
redo(REDO,WorkspaceRegression("atomic").loadHex("../custom/atomic/build/atomic.hex")->bootAt(0x00000000u)->run(10e3););
|
||||
#endif
|
||||
|
||||
#ifdef DHRYSTONE
|
||||
|
@ -3206,22 +3323,22 @@ int main(int argc, char **argv, char **env) {
|
|||
#ifdef SEED
|
||||
srand48(SEED);
|
||||
#endif
|
||||
//redo(1,Workspace("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);)
|
||||
//redo(1,WorkspaceRegression("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);)
|
||||
vector <std::function<void()>> tasks;
|
||||
|
||||
/*for(int redo = 0;redo < 4;redo++)*/{
|
||||
for(const string &name : freeRtosTests){
|
||||
tasks.push_back([=]() { Workspace(name + "_rv32i_O0").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32i_O0.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
tasks.push_back([=]() { Workspace(name + "_rv32i_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32i_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
tasks.push_back([=]() { WorkspaceRegression(name + "_rv32i_O0").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32i_O0.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
tasks.push_back([=]() { WorkspaceRegression(name + "_rv32i_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32i_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
#ifdef COMPRESSED
|
||||
tasks.push_back([=]() { Workspace(name + "_rv32ic_O0").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32ic_O0.hex")->bootAt(0x80000000u)->run(5e6*15);});
|
||||
tasks.push_back([=]() { Workspace(name + "_rv32ic_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32ic_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
tasks.push_back([=]() { WorkspaceRegression(name + "_rv32ic_O0").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32ic_O0.hex")->bootAt(0x80000000u)->run(5e6*15);});
|
||||
tasks.push_back([=]() { WorkspaceRegression(name + "_rv32ic_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32ic_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
#endif
|
||||
#if defined(MUL) && defined(DIV)
|
||||
#ifdef COMPRESSED
|
||||
tasks.push_back([=]() { Workspace(name + "_rv32imac_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32imac_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
tasks.push_back([=]() { WorkspaceRegression(name + "_rv32imac_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32imac_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
#else
|
||||
tasks.push_back([=]() { Workspace(name + "_rv32im_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32im_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
tasks.push_back([=]() { WorkspaceRegression(name + "_rv32im_O3").withRiscvRef()->loadHex("../../resources/freertos/" + name + "_rv32im_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -48,6 +48,13 @@ else
|
|||
endif
|
||||
|
||||
|
||||
|
||||
ifeq ($(LITEX),yes)
|
||||
ADDCFLAGS += -CFLAGS -DLITEX
|
||||
ADDCFLAGS += -CFLAGS -DVMLINUX='\"$(VMLINUX)\"'
|
||||
ADDCFLAGS += -CFLAGS -DRAMDISK='\"$(RAMDISK)\"'
|
||||
endif
|
||||
|
||||
ifneq ($(shell grep timerInterrupt ../../../../VexRiscv.v -w),)
|
||||
ADDCFLAGS += -CFLAGS -DTIMER_INTERRUPT
|
||||
endif
|
||||
|
|
Loading…
Reference in New Issue