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:
Dolu1990 2019-03-24 10:52:56 +01:00
parent 0656a49332
commit 6c0608f0dd
3 changed files with 278 additions and 134 deletions

View File

@ -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{

View File

@ -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,24 +1161,40 @@ 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(isPerifRegion(addr)){
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);
}
} else {
if(wr){
memTraces <<
#ifdef TRACE_WITH_TIME
@ -1169,41 +1211,6 @@ public:
*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++){
@ -1211,19 +1218,6 @@ public:
*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
@ -1235,24 +1229,26 @@ public:
" : 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);
// }
// }
if((addr & 0xF0000000) == 0xF0000000){
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
}

View File

@ -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