Commit 06ce9f00 authored by logan's avatar logan
Browse files

new tests + better arch

parent a08862f9
Pipeline #272275 failed with stages
in 2 minutes and 43 seconds
......@@ -31,14 +31,14 @@ riscv-compliance:
stage: compliance
script:
- export PATH=$PATH:/opt/riscvToolchains/rv32im/bin
- git clone --recursive https://github.com/riscv/riscv-compliance.git
- cp ./tests/riscv-compliance/Makefile.include ./riscv-compliance/Makefile.include
- cp -rf ./tests/riscv-compliance/riscv-target/comet/ ./riscv-compliance/riscv-target/
- git clone --recursive https://github.com/riscv/riscv-arch-test.git
- cp ./tests/riscv-compliance/Makefile.include ./riscv-arch-test/Makefile.include
- cp -rf ./tests/riscv-compliance/riscv-target/comet/ ./riscv-arch-test/riscv-target/
- export COMET_DIR=/udd/srokicki/builds/dQ-WesJC/0/srokicki/Comet/build/bin
- cd ./riscv-compliance
- cd ./riscv-arch-test
- make clean && make compile
- make simulate
- make verify | grep -q "8/8 RISCV_TARGET=comet RISCV_DEVICE=M XLEN=32"
- make verify | grep -q "38/38 RISCV_TARGET=comet RISCV_DEVICE=I XLEN=32"
comet-perf:
stage: performance
......
......@@ -83,7 +83,7 @@ public:
for (int oneSetElement = 0; oneSetElement < SET_SIZE; oneSetElement++) {
for (int oneSet = 0; oneSet < ASSOCIATIVITY; oneSet++) {
cacheMemory[oneSetElement][oneSet] = 0;
age[oneSetElement][oneSet] = 0;
age[oneSetElement][oneSet] = ac_int<40, false>(0);
dataValid[oneSetElement][oneSet] = 0;
dirtyBit[oneSetElement][oneSet] = 0;
}
......@@ -133,10 +133,10 @@ public:
ac_int<1, false> valid3 = dataValid[place][2];
ac_int<1, false> valid4 = dataValid[place][3];
ac_int<40, false> age1 = age[place][0];
ac_int<40, false> age2 = age[place][1];
ac_int<40, false> age3 = age[place][2];
ac_int<40, false> age4 = age[place][3];
ac_int<16, false> age1 = age[place][0];
ac_int<16, false> age2 = age[place][1];
ac_int<16, false> age3 = age[place][2];
ac_int<16, false> age4 = age[place][3];
ac_int<1, false> dirty1 = dirtyBit[place][0];
ac_int<1, false> dirty2 = dirtyBit[place][1];
......@@ -149,14 +149,12 @@ public:
nextLevelOpType = opType;
nextLevelDataIn = dataIn;
cacheState = 2; // avoid the first "if" statement
// printf("** CLINT %x %x **\n", (unsigned int)addr>>2, (unsigned
// int)dataIn);
//printf("** CLINT %x %c **\n", (unsigned int)addr>>2, (char)dataIn);
} else if (cacheState == 2 && addr_superior && addr_inferior) {
cacheState = 0;
dataOut = nextLevelDataOut;
nextLevelOpType = NONE; // avoid a memory call
//printf("** END_CLINT %x %x **\n", (unsigned int)dataOut, (unsigned
//int)addr>>2);
//printf("** END_CLINT %x %x **\n", (unsigned int)dataOut, (unsigned int)addr>>2);
} else if (cacheState == 0) {
numberAccess++;
......@@ -173,29 +171,29 @@ public:
ac_int<LOG_ASSOCIATIVITY, false> set = 0;
ac_int<LINE_SIZE * 8, false> selectedValue;
ac_int<TAG_SIZE, false> tag;
ac_int<TAG_SIZE, false> selectedTag;
if (hit1) {
selectedValue = val1.template slc<LINE_SIZE * 8>(TAG_SIZE);
tag = tag1;
selectedTag = tag1;
set = 0;
}
if (hit2) {
selectedValue = val2.template slc<LINE_SIZE * 8>(TAG_SIZE);
tag = tag2;
selectedTag = tag2;
set = 1;
}
if (hit3) {
selectedValue = val3.template slc<LINE_SIZE * 8>(TAG_SIZE);
tag = tag3;
selectedTag = tag3;
set = 2;
}
if (hit4) {
selectedValue = val4.template slc<LINE_SIZE * 8>(TAG_SIZE);
tag = tag4;
selectedTag = tag4;
set = 3;
}
......@@ -206,7 +204,7 @@ public:
if (hit) {
ac_int<LINE_SIZE * 8 + TAG_SIZE, false> localValStore = 0;
localValStore.set_slc(TAG_SIZE, selectedValue);
localValStore.set_slc(0, tag);
localValStore.set_slc(0, selectedTag);
// First we handle the store
if (opType == STORE) {
......
......@@ -294,8 +294,7 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
nextLevelOpType = opType;
nextLevelDataIn = dataIn;
cacheState = 2; // avoid the first "if" statement
// printf("** CLINT %x %x **\n", (unsigned int)addr>>2, (unsigned
// int)dataIn);
//printf("**L2 %d CLINT %x %c **\n", (unsigned int)hartid, (unsigned int)addr>>2, (unsigned int)dataIn);
} else if (cacheState == 2 && addr_superior && addr_inferior) {
cacheState = 0;
bufferIn.dataLoad = nextLevelDataOut;
......@@ -531,7 +530,7 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
bufferIn.dataLoad = dataOut;
bufferIn.releaseAck = 1;
//printf("[CacheL2] Hit Read/AMO_LR %x @(%x) \n", dataOut, addr);
//printf("[CacheL2] AMO_LR %x @(%x) \n", dataOut, addr);
} else {
cacheStateMissRequest = NB_CORES+1;
}
......@@ -547,7 +546,7 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
ac_int<INTERFACE_SIZE * 8, false> dataOut = selectedValue.template slc<INTERFACE_SIZE * 8>(4 * 8 * offset);
dataOutStore = dataOut;
cacheStateMissRequest = 0;
//printf("[CacheL2] Hit Read/AMO_LR %x @(%x) \n", dataOut, addr);
//printf("[CacheL2] Hit AMO_LR %x @(%x) \n", dataOut, addr);
} else if (cacheStateMissRequest-2 != int(hartid) && directoryStateHit.sharers[cacheStateMissRequest-2] == 1) {
bool need_writeback = (directoryStateHit.cacheStateDir == MODIFIED);
......@@ -568,7 +567,7 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
cacheStateMissRequest--;
}
} else if(opType == END_MISS) {
// printf("END_MISS \n");
//printf("END_MISS \n");
placeStore = place_current;
setStore = set;
busyCore[hartid] = 0;
......@@ -594,31 +593,32 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
// nothing to do...
directoryStore.sharers[hartid] = 1;
busyCore[hartid] = 1;
// who is the owner ?
directoryStore.owner = (directoryStateHit.cacheStateDir == INVALID)
? (int)hartid : (int)directoryStateHit.owner;
directoryStore.cacheStateDir = (directoryStateHit.cacheStateDir == INVALID)
? EXCLUSIVE : SHARED;
// need to write a new directory status
wasStore = true;
cacheModif = false;
// who is the owner ?
directoryStore.owner = (directoryStateHit.cacheStateDir == INVALID)
? (int)hartid : (int)directoryStateHit.owner;
directoryStore.cacheStateDir = (directoryStateHit.cacheStateDir == INVALID)
? EXCLUSIVE : SHARED;
// need to write a new directory status
wasStore = true;
cacheModif = false;
directoryModified = true;
isCycleModified = true;
// Have we issued the instruction ? Not yet
//printf("MISS WRITE/RD nothing todo (%d,%d) \n", (int)directoryStore.sharers[0], (int)directoryStore.sharers[1]);
} else {
cacheStateMissRequest = NB_CORES+1;
//printf("MISS WRITE/RD must do @(%x,%x) (%d,%d) \n", place_current, set, (int)directoryStore.sharers[0], (int)directoryStore.sharers[1]);
//printf("%d MISS WRITE/RD must do @(%x,%x) (%d,%d) \n", cache, place_current, set, (int)directoryStore.sharers[0], (int)directoryStore.sharers[1]);
}
} else if (opType == MISS_WRITE || opType == MISS_READ) {
// Two ways to get a releaseAck equal to true --> Miss Write (all invalidated) or Miss Read for all sharers
// None_DIR --> directory status is not in the Modified state (change thanks to a writeback)
if (cacheStateMissRequest == 1) {
directoryStore.sharers[hartid] = 1;
//printf("[CacheL2] The miss can be released after a directory write...\n");
directoryStore.owner = (directoryStateHit.cacheStateDir == INVALID || opType == MISS_WRITE) ?
// None_DIR --> directory status is not in the Modified state (change thanks to a writeback)
if (cacheStateMissRequest == 1) {
directoryStore.sharers[hartid] = 1;
//printf("[CacheL2] The miss can be released after a directory write...\n");
directoryStore.owner = (directoryStateHit.cacheStateDir == INVALID || opType == MISS_WRITE) ?
(int)hartid : (int)directoryStateHit.owner;
directoryStore.cacheStateDir = (directoryStateHit.cacheStateDir == INVALID && opType == MISS_READ)
directoryStore.cacheStateDir = (directoryStateHit.cacheStateDir == INVALID && opType == MISS_READ)
? EXCLUSIVE
: ((directoryStateHit.cacheStateDir == EXCLUSIVE ||
directoryStateHit.cacheStateDir == SHARED) && opType == MISS_READ)
......@@ -633,31 +633,31 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
//printf("MISS WRITE/RD granted status(%d,%d) \n", (int)directoryStore.sharers[0], (int)directoryStore.sharers[1]);
} else if (directoryStateHit.sharers[cacheStateMissRequest-2] == 1) {
protocolMiss = 1;
// We can't send a directory request to a core that is already in a busy state
// core cacheStateMissRequest will never need core hartid to become available
bool need_writeback = directoryStateHit.cacheStateDir == MODIFIED;
// We can't send a directory request to a core that is already in a busy state
// core cacheStateMissRequest will never need core hartid to become available
bool need_writeback = directoryStateHit.cacheStateDir == MODIFIED;
directoryOpType interfaceRequest = (need_writeback && opType == MISS_READ)
directoryOpType interfaceRequest = (need_writeback && opType == MISS_READ)
? REQ_DATATRANSFER_SHARED
: (need_writeback && opType == MISS_WRITE)
? REQ_DATATRANSFER_INV
: (opType == MISS_WRITE) ? REQ_INV : NONE_DIR;
if(interfaceRequest != NONE_DIR){
// SEND Req to core cacheStateMissRequest ! Optimized !
instructionQueue newInstruction;
newInstruction.hartid = cacheStateMissRequest-2;
newInstruction.cache = directoryStateHit.cache;
newInstruction.interfaceRequest = interfaceRequest;
newInstruction.addr = addr;
pushInstruction(newInstruction, fifoInstruction);
//fifoInstruction.push_back(newInstruction);
directoryStore.sharers[cacheStateMissRequest-2] = (interfaceRequest==REQ_DATATRANSFER_SHARED) ? 1 : 0;
}
//printf("// Special addr(%x) @(%x,%x) status(%d,%d) %x %d MISS Request \n", addr, place_current, set, (int)directoryStore.sharers[0], (int)directoryStore.sharers[1], interfaceRequest, cacheStateMissRequest-2);
cacheStateMissRequest--;
} else {
if(interfaceRequest != NONE_DIR){
// SEND Req to core cacheStateMissRequest ! Optimized !
instructionQueue newInstruction;
newInstruction.hartid = cacheStateMissRequest-2;
newInstruction.cache = directoryStateHit.cache;
newInstruction.interfaceRequest = interfaceRequest;
newInstruction.addr = addr;
pushInstruction(newInstruction, fifoInstruction);
//fifoInstruction.push_back(newInstruction);
directoryStore.sharers[cacheStateMissRequest-2] = (interfaceRequest==REQ_DATATRANSFER_SHARED) ? 1 : 0;
}
//printf("// %d Special addr(%x) @(%x,%x) status(%d,%d) %x %d MISS Request \n", cache, addr, place_current, set, (int)directoryStore.sharers[0], (int)directoryStore.sharers[1], interfaceRequest, (cacheStateMissRequest-2) );
cacheStateMissRequest--;
} else {
cacheStateMissRequest--;
}
}
} else if(opType == WRITEHIT && cacheStateMissRequest == 0){
// Which cores need to be updated ?
// two cores can't process the same directory at the same time : sequential processing
......@@ -665,7 +665,7 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
bool isExclusive = (directoryStateHit.cacheStateDir == EXCLUSIVE) && (directoryStateHit.sharers[hartid] == 1);
placeStore = place_current;
setStore = set;
transferDirectoryStruct(directoryStateHit, directoryStore);
transferDirectoryStruct(directoryStateHit, directoryStore);
if(isExclusive){
directoryStore.cacheStateDir = MODIFIED;
......@@ -708,7 +708,7 @@ void CacheMemoryL2<INTERFACE_SIZE, LINE_SIZE, SET_SIZE>::processL2(cacheL2Direct
//printf("[CacheL2] Entering in a miss... place(%x) addr(%x)\n", place_current, addr);
}
} else {
// printf("Miss %d\n", (unsigned int)cacheState);
//printf("Miss %d\n", (unsigned int)cacheState);
bool doMiss = true;
if (cacheState == STATE_CACHE_MISS) {
newVal = tag;
......
......@@ -291,10 +291,10 @@ public:
ac_int<LINE_SIZE * 8 + TAG_SIZE, false> val3 = cacheMemory[place_current][2];
ac_int<LINE_SIZE * 8 + TAG_SIZE, false> val4 = cacheMemory[place_current][3];
ac_int<16, false> age1 = age[place_current][0];
ac_int<16, false> age2 = age[place_current][1];
ac_int<16, false> age3 = age[place_current][2];
ac_int<16, false> age4 = age[place_current][3];
ac_int<40, false> age1 = age[place_current][0];
ac_int<40, false> age2 = age[place_current][1];
ac_int<40, false> age3 = age[place_current][2];
ac_int<40, false> age4 = age[place_current][3];
cacheStatus multicoreCacheState1 = (placeDirMem==place_current && setStoreDir==0 && forwardCacheState) ? valStateDir : multicoreCacheState[place_current][0];
cacheStatus multicoreCacheState2 = (placeDirMem==place_current && setStoreDir==1 && forwardCacheState) ? valStateDir : multicoreCacheState[place_current][1];
......@@ -309,7 +309,7 @@ public:
nextLevelDataIn = dataIn;
nextLevelMask = mask;
cacheState = 2; // avoid the first "if" statement
//printf("** CLINT %x %x **\n", (unsigned int)addr>>2, (unsigned int)dataIn);
//printf("**L1 %d CLINT %x %c **\n",(unsigned int) hartid, (unsigned int)addr>>2, (unsigned int)dataIn);
} else if (cacheState == 2 && addrSuperior && addrInferior && !enter_directory_request) {
// CLINT data acquisition
cacheState = 0;
......@@ -480,7 +480,7 @@ public:
//printf("// Core: %d waiting for a Miss grant... addr(%x) opType(%x) %x %d \n", (unsigned int)hartid, (unsigned int)addr, (unsigned int)opType, (unsigned int) place_current, multicoreCacheState3);
}
} else {
// printf("%d Miss %d %d\n", hartid, (unsigned int)cacheState, cacheStateDir);
//printf("%d Miss %d %d\n", hartid, (unsigned int)cacheState, cacheStateDir);
if (cacheState == STATE_CACHE_MISS && !data_req) {
......@@ -625,7 +625,7 @@ public:
dataOut = newVal.template slc<INTERFACE_SIZE * 8>(4 * 8 * offset);
break;
}
// printf("After Miss read %x at %x\n", (unsigned int)dataOut.slc<32>(0), (unsigned int)addr);
//printf("After Miss read %x at %x\n", (unsigned int)dataOut.template slc<32>(0), (unsigned int)addr);
dataOutStore = dataOut;
}
}
......
......@@ -291,10 +291,10 @@ public:
ac_int<LINE_SIZE * 8 + TAG_SIZE, false> val3 = cacheMemory[place_current][2];
ac_int<LINE_SIZE * 8 + TAG_SIZE, false> val4 = cacheMemory[place_current][3];
ac_int<16, false> age1 = age[place_current][0];
ac_int<16, false> age2 = age[place_current][1];
ac_int<16, false> age3 = age[place_current][2];
ac_int<16, false> age4 = age[place_current][3];
ac_int<40, false> age1 = age[place_current][0];
ac_int<40, false> age2 = age[place_current][1];
ac_int<40, false> age3 = age[place_current][2];
ac_int<40, false> age4 = age[place_current][3];
cacheStatus multicoreCacheState1 = (placeDirMem==place_current && setStoreDir==0 && forwardCacheState) ? valStateDir : multicoreCacheState[place_current][0];
cacheStatus multicoreCacheState2 = (placeDirMem==place_current && setStoreDir==1 && forwardCacheState) ? valStateDir : multicoreCacheState[place_current][1];
......
......@@ -385,6 +385,7 @@ public:
case RISCV_SYSTEM_ENV_ECALL:
// ECALL jumps to the IRQ handler code, whose adress is stored in mtvec lower bits
this->mepc = dctoEx.pc;
this->mstatus[7] = this->mstatus[3];
this->mcause = 11; // environment call from machine mode 0x00000 -> exception
result_reg = mtvec;
setPC_reg = true & HAS_KERNEL_SYSCALL_HANDLER;
......@@ -396,7 +397,7 @@ public:
// We change interrupt enable bits (MIE = MPIE and MPIE = 1)
//if (!stall_cpu) {
this->mstatus[3] = this->mstatus[7];
this->mstatus[7] = 1;
this->mstatus[7] = 0;
break;
case RISCV_SYSTEM_ENV_EBREAK:
this->mepc = dctoEx.pc;
......
......@@ -60,6 +60,7 @@ struct cacheDirectoryInterfaceBase {
typedef struct cacheDirectoryInterfaceOut : public cacheDirectoryInterfaceBase {
memOpType interfaceRequest;
ac_int<32, false> bufferIn;
} cacheDirectoryInterfaceOut;
typedef struct cacheDirectoryInterfaceIn : public cacheDirectoryInterfaceBase {
......@@ -261,7 +262,7 @@ public:
*/
#ifndef __HLS__
if (opType == STORE && addr == ac_int<32, false>(UART_RXTX) && !SMP) {
if (opType == STORE && addr == ac_int<32, false>(UART_RXTX)) {
// UART
pendingWrite = 0;
waitOut = false;
......@@ -311,9 +312,9 @@ public:
} else if (this->wait) {
waitOut = !bufferOut->releaseAck;
bufferOut->interfaceAck = !bufferOut->releaseAck;
dataOut = bufferIn->buffer;
dataOut = bufferOut->bufferIn;
this->wait = !bufferOut->releaseAck;
//if(!this->wait){printf("//Directory response... %x %x %d\n", bufferOut->addr, bufferIn->buffer,
//if(!this->wait){printf("//Directory response... %x %x %d\n", bufferOut->addr, bufferOut->bufferIn,
// bufferOut->releaseAck );}
} else if (opType != NONE) {
bufferOut->addr = addr;
......@@ -331,7 +332,7 @@ public:
}
#ifndef __HLS__
if (PRINT_CONSOLE && opType == STORE && addr == UART_RXTX && printIO) {
if (PRINT_CONSOLE && opType == STORE && addr == UART_RXTX && !SMP) {
// UART
if (dataIn != 0x1B) {
printf("%c", (char)dataIn);
......@@ -348,9 +349,9 @@ public:
if (this->wait) {
waitOut = !bufferOut->releaseAck;
bufferOut->interfaceAck = !bufferOut->releaseAck;
dataOut = bufferIn->buffer;
dataOut = bufferOut->bufferIn;
this->wait = !bufferOut->releaseAck;
//if(!this->wait){printf("//Directory response... %x %x %d\n", bufferOut->addr, bufferIn->buffer,
//if(!this->wait){printf("//Directory response... %x %x %d\n", bufferOut->addr, bufferOut->bufferIn,
// bufferOut->releaseAck );}
} else if (opType != NONE) {
bufferOut->addr = addr;
......
......@@ -14,13 +14,13 @@ void doUART(std::vector<ac_int<32, false> >& mem);
void amoManagement(int& index, reservationSet reservationAMO[], const int nbCores);
// Directory protocol multicore
void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool enable[],
cacheDirectoryInterfaceIn bufferIn[][2], cacheDirectoryInterfaceOut bufferOut[][4],
cacheDirectoryInterfaceIn bufferIn[][2], cacheDirectoryInterfaceOut bufferOut[][3],
reservationSet reservationAMO[]);
// Round-Robin Bus
void doSharedBus(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2);
void doSharedBus(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][3], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2);
// Directory Bus
void doDirectoryRequestAnswers(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int coreID, int cacheID);
void doDirectoryRequestSend(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int& coreID, int& cacheID);
void doDirectoryRequestAnswers(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][3], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int coreID, int cacheID);
void doDirectoryRequestSend(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][3], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int& coreID, int& cacheID);
class Simulator {
protected:
......@@ -47,7 +47,7 @@ protected:
int reservationIndex = 0;
// Multi-core directory cache coherence
cacheDirectoryInterfaceIn interfaceIn[NB_CORES][2];
cacheDirectoryInterfaceOut interfaceOut[NB_CORES][4];
cacheDirectoryInterfaceOut interfaceOut[NB_CORES][3];
bool waitDirBus = false;
int coreIDDirBus = 0;
......
......@@ -47,6 +47,8 @@ BasicSimulator::BasicSimulator(std::string binaryFile,
interfaceIn[i][1].buffer = 0;
interfaceOut[i][0].buffer = 0;
interfaceOut[i][1].buffer = 0;
interfaceOut[i][0].bufferIn = 0;
interfaceOut[i][1].bufferIn = 0;
// Init Core PC
core[i].regFile[2] = STACK_INIT;
......@@ -61,8 +63,8 @@ BasicSimulator::BasicSimulator(std::string binaryFile,
core[i].dm = new CacheMemory<4, 16, 64>(dmInterface, false);
#else
// Multi-core
core[i].im = new CacheMemoryMulticoreInst<4, 16, 64>(new MulticoreMemory<4>(&interfaceIn[i][0], &interfaceOut[i][0], &interfaceOut[i][2]), false);
core[i].dm = new CacheMemoryMulticore<4, 16, 64>(new MulticoreMemory<4>(&interfaceIn[i][1], &interfaceOut[i][1], &interfaceOut[i][3]), false);
core[i].im = new CacheMemoryMulticoreInst<4, 16, 64>(new MulticoreMemory<4>(&interfaceIn[i][0], &interfaceOut[i][0], NULL), false);
core[i].dm = new CacheMemoryMulticore<4, 16, 64>(new MulticoreMemory<4>(&interfaceIn[i][1], &interfaceOut[i][1], &interfaceOut[i][2]), false);
#endif
clint.ir_timer[i] = 0;
......@@ -241,7 +243,7 @@ void BasicSimulator::printCycle() {
}
// Dual Core Debug : hartid one
/*
if (SMP && !core[1].stallSignals[1] && !core[1].stallIm && !core[1].stallDm) {
printf("Hartid 1 --> Debug trace : %x [%x] ", (unsigned int)core[1].dctoEx.pc,
(unsigned int)core[1].dctoEx.we);
......@@ -250,7 +252,6 @@ void BasicSimulator::printCycle() {
printf("%x ", (unsigned int)reg);
std::cout << std::endl;
}
*/
}
}
......
......@@ -751,7 +751,7 @@ void doCycle(struct Core& core, // Core containing all values
if (((core.csrUnit.mip[IR_M_TIMER] && core.csrUnit.mie[IR_M_TIMER]) ||
(core.csrUnit.mip[IR_M_SOFT] && core.csrUnit.mie[IR_M_SOFT])) &&
core.csrUnit.mstatus[MSTATUS_MIE]) {
//printf("trap %d %d %d\n", core.memtoWB.we, core.extoMem.we, core.dctoEx.we);
// flushing strategy
if (!core.flushing) {
core.csrUnit.mepc = extoMem_temp.isBranch ? extoMem_temp.nextPC : (core.ftoDC.we ? core.ftoDC.pc : core.pc);
......@@ -770,8 +770,7 @@ void doCycle(struct Core& core, // Core containing all values
core.csrUnit.mstatus[MSTATUS_MPIE] = core.csrUnit.mstatus[MSTATUS_MIE];
core.csrUnit.mstatus[MSTATUS_MIE] = 0;
core.flushing = false;
core.csrUnit.mcause =
0x80000000 | ((core.csrUnit.mip[IR_M_TIMER] && core.csrUnit.mie[IR_M_TIMER]) ? IR_M_TIMER : IR_M_SOFT);
core.csrUnit.mcause = 0x80000000 | ((core.csrUnit.mip[IR_M_TIMER] && core.csrUnit.mie[IR_M_TIMER]) ? IR_M_TIMER : IR_M_SOFT);
ftoDC_temp.nextPCFetch = core.csrUnit.mtvec;
}
}
......
......@@ -61,7 +61,7 @@ void memoryStoreLoad(ac_int<32, false>* data, ac_int<32, false> addr, memMask ma
}
void doSharedBus(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2) {
void doSharedBus(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][3], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2) {
static int tokencore = 1;
static int tokencache = 1;
......@@ -73,7 +73,7 @@ void doSharedBus(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4],
if(wait){
wait = !bufferInL2.releaseAck && !bufferInL2.rejection;
bufferOut[tokencore][tokencache].releaseAck = bufferInL2.releaseAck && !bufferInL2.rejection;
bufferIn[tokencore][tokencache].buffer = bufferInL2.dataLoad;
bufferOut[tokencore][tokencache].bufferIn = bufferInL2.dataLoad;
bufferIn[tokencore][tokencache].protocolMiss = bufferInL2.protocolMiss;
bufferInL2.interfaceAck = !bufferInL2.releaseAck && !bufferInL2.rejection;
//printf("[RRB] Directory (core=%d,cache=%d) current instruction issued ? %d \n", tokencore, tokencache, wait);
......@@ -152,7 +152,7 @@ void doSharedBus(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4],
}
}
void doDirectoryRequestAnswers(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int coreID, int cacheID){
void doDirectoryRequestAnswers(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][3], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int coreID, int cacheID){
if(wait){
// When a directory request is sent to a particular core
// the core can answer by sending some instructions to the cache l2.
......@@ -163,19 +163,19 @@ void doDirectoryRequestAnswers(const int nb_cores, cacheDirectoryInterfaceOut bu
bufferOutL2.releaseAck = bufferIn[coreID][cacheID].releaseAck;
// During a request to a core (REQ_INV/ REQ_DATATRANSFER_X)
// the core can answer back with some instructions (WB)
if(bufferOut[coreID][3].interfaceAck) {
if(bufferOut[coreID][2].interfaceAck) {
//bufferInL2.interfaceAckWB = bufferOut[coreID][3].interfaceAck;
bufferOut[coreID][3].releaseAck = bufferInL2.releaseAckWB;
bufferOut[coreID][2].releaseAck = bufferInL2.releaseAckWB;
bufferInL2.interfaceAckWB = !bufferInL2.releaseAckWB;
bufferInL2.addrWB = bufferOut[coreID][3].addr;
bufferInL2.bufferWB = bufferOut[coreID][3].buffer;
bufferInL2.addrWB = bufferOut[coreID][2].addr;
bufferInL2.bufferWB = bufferOut[coreID][2].buffer;
}
//if(!wait){printf("[DirectoryRequestBus] Instruction done. \n");}
//if(bufferInL2.interfaceAckWB){printf("[DirectoryRequestBus] Writeback sent to the cache L2. %x \n", bufferInL2.bufferWB);}
}
}
void doDirectoryRequestSend(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][4], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int& coreID, int& cacheID) {
void doDirectoryRequestSend(const int nb_cores, cacheDirectoryInterfaceOut bufferOut[][3], cacheDirectoryInterfaceIn bufferIn[][2], cacheL2DirectoryInterfaceIn& bufferInL2, cacheL2DirectoryInterfaceOut& bufferOutL2, bool& wait, int& coreID, int& cacheID) {
if (!wait && bufferOutL2.interfaceAck){
//printf("[DirectoryRequestBus] Issuing an instruction...\n");
......@@ -190,7 +190,7 @@ void doDirectoryRequestSend(const int nb_cores, cacheDirectoryInterfaceOut buffe
}
void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool enable[],
cacheDirectoryInterfaceIn bufferIn[][2], cacheDirectoryInterfaceOut bufferOut[][4],
cacheDirectoryInterfaceIn bufferIn[][2], cacheDirectoryInterfaceOut bufferOut[][3],
reservationSet reservationAMO[])
{
// Directory Architecture
......@@ -209,12 +209,12 @@ void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool
bool cacheWait = false;
for (unsigned int i = 0; i < nb_cores; i++) { // i is the id of the core
if (bufferOut[i][3].interfaceRequest == WRITEBACK && bufferOut[i][3].interfaceAck) {
if (bufferOut[i][2].interfaceRequest == WRITEBACK && bufferOut[i][2].interfaceAck) {
// cache L2 update
ac_int<32, false> dataOut_temp = 0;
//printf("%d dirBus WRITEBACK: %x %x\n", i, bufferOut[i][3].addr, bufferOut[i][3].buffer);
memoryStoreLoad(p_mem, bufferOut[i][3].addr, WORD, STORE, bufferOut[i][3].buffer, dataOut_temp, cacheWait);
bufferOut[i][3].releaseAck = 1;
//printf("%d dirBus WRITEBACK: %x %x\n", i, bufferOut[i][2].addr, bufferOut[i][2].buffer);
memoryStoreLoad(p_mem, bufferOut[i][2].addr, WORD, STORE, bufferOut[i][2].buffer, dataOut_temp, cacheWait);
bufferOut[i][2].releaseAck = 1;
}
for (unsigned int j = 0; j < 2; j++) { // 0: IM ; 1: DM
......@@ -244,11 +244,11 @@ void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool
} else if (bufferOut[i][j].interfaceRequest == LOAD) { // CLINT-UART - Cache L2 data acquisition
// cache L2 call
ac_int<32, false> dataIn_temp = 0;
bufferIn[i][j].buffer = 0;
bufferOut[i][j].bufferIn = 0;
memoryStoreLoad(p_mem, bufferOut[i][j].addr, bufferOut[i][j].mask, bufferOut[i][j].interfaceRequest,
dataIn_temp, bufferIn[i][j].buffer, cacheWait);
dataIn_temp, bufferOut[i][j].bufferIn , cacheWait);
bufferOut[i][j].releaseAck = cacheWait;
//printf("%d %d ACQ/LOAD: %x %x\n", i, j, bufferOut[i][j].addr, bufferIn[i][j].buffer);
//printf("%d %d ACQ/LOAD: %x %x\n", i, j, bufferOut[i][j].addr, bufferOut[i][j].bufferIn );
} else if (bufferOut[i][j].interfaceRequest == AMO_SC) {
if (reservationAMO[i].valid && reservationAMO[i].address == bufferOut[i][j].addr) {
ac_int<32, false> dataOut_temp = 0;
......@@ -257,13 +257,13 @@ void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool
bufferOut[i][j].releaseAck = cacheWait;
if(cacheWait)
reservationAMO[i].valid = 0;
bufferIn[i][j].buffer = 0; // success !
bufferOut[i][j].bufferIn = 0; // success !
} else {
bufferIn[i][j].buffer = 1; // try again !
bufferOut[i][j].bufferIn = 1; // try again !
bufferOut[i][j].releaseAck = 1;
reservationAMO[i].valid = 0;
}
// printf("END AMO_SC addr(%x) output(%x) data(%x)\n", bufferOut[i][j].addr, bufferIn[i][j].buffer,
// printf("END AMO_SC addr(%x) output(%x) data(%x)\n", bufferOut[i][j].addr, bufferOut[i][j].bufferIn ,
// bufferOut[i][j].buffer);
} else if (bufferOut[i][j].interfaceRequest == AMO_LR) {
// printf("AMO_LR addr(%x) %x sharer(%d %d) %d %d \n", bufferOut[i][j].addr,
......@@ -310,12 +310,12 @@ void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool
reservationAMO[i].valid = 1;
reservationAMO[i].address = bufferOut[i][j].addr;
ac_int<32, false> dataIn_temp = 0;
bufferIn[i][j].buffer = 0;
memoryStoreLoad(p_mem, bufferOut[i][j].addr, WORD, LOAD, dataIn_temp, bufferIn[i][j].buffer, cacheWait);
bufferOut[i][j].bufferIn = 0;
memoryStoreLoad(p_mem, bufferOut[i][j].addr, WORD, LOAD, dataIn_temp, bufferOut[i][j].bufferIn , cacheWait);
bufferOut[i][j].releaseAck = cacheWait;
// printf("END AMO_LR addr(%x) sharer(%d %d) %x data(%x)\n", bufferOut[i][j].addr,
// directory[addr_request].sharers.slc<1>(0), directory[addr_request].sharers.slc<1>(1),
// directory[addr_request].cacheStateDir, bufferIn[i][j].buffer);
// directory[addr_request].cacheStateDir, bufferOut[i][j].bufferIn);
}
}
} else if (bufferOut[i][j].interfaceRequest == AMO_SWAPW) {
......@@ -363,12 +363,12 @@ void doDirectory(std::vector<ac_int<32, false> >& mem, const int nb_cores, bool
if (releaseAck) {