goldenmodel now pass more machine mode CSR tests

This commit is contained in:
Dolu1990 2019-03-20 11:46:27 +01:00
parent ee402ec5dc
commit 3c66f7c58a
1 changed files with 121 additions and 42 deletions

View File

@ -192,7 +192,7 @@ class success : public std::exception { };
class RiscvGolden { class RiscvGolden {
public: public:
int32_t pc; int32_t pc, lastPc;
int32_t regs[32]; int32_t regs[32];
union status { union status {
@ -273,7 +273,7 @@ public:
status.raw = 0; status.raw = 0;
mip.raw = 0; mip.raw = 0;
mie.raw = 0; mie.raw = 0;
mtvec.raw = 0; mtvec.raw = 0x80000020;
mcause.raw = 0; mcause.raw = 0;
mbadaddr = 0; mbadaddr = 0;
mepc = 0; mepc = 0;
@ -286,7 +286,12 @@ public:
} }
virtual void pcWrite(int32_t target) { virtual void pcWrite(int32_t target) {
pc = target; if(isPcAligned(target)){
lastPc = pc;
pc = target;
} else {
exception(0, 0);
}
} }
uint32_t mbadaddr; uint32_t mbadaddr;
uint32_t mepc; uint32_t mepc;
@ -305,6 +310,11 @@ public:
if(interrupt) livenessInterrupt = 0; if(interrupt) livenessInterrupt = 0;
//status.MPP := privilege //status.MPP := privilege
if(!interrupt) step(); //As VexRiscv instruction which trap do not reach writeback stage fire
}
void ilegalInstruction(){
exception(0, 2);
} }
virtual void fail() { virtual void fail() {
@ -361,6 +371,15 @@ public:
} }
bool isPcAligned(uint32_t pc){
#ifdef COMPRESSED
return (pc & 1) == 0;
#else
return (pc & 3) == 0;
#endif
}
virtual void step() { virtual void step() {
livenessStep = 0; livenessStep = 0;
@ -393,15 +412,24 @@ public:
uint32_t i; uint32_t i;
uint32_t u32Buf; uint32_t u32Buf;
if (pc & 2) { if (pc & 2) {
iRead(pc - 2, &i); if(iRead(pc - 2, &i)){
exception(0, 1);
return;
}
i >>= 16; i >>= 16;
if (i & 3 == 3) { if (i & 3 == 3) {
uint32_t u32Buf; uint32_t u32Buf;
iRead(pc + 2, &u32Buf); if(iRead(pc + 2, &u32Buf)){
exception(0, 1);
return;
}
i |= u32Buf << 16; i |= u32Buf << 16;
} }
} else { } else {
iRead(pc, &i); if(iRead(pc, &i)){
exception(0, 1);
return;
}
} }
if ((i & 0x3) == 0x3) { if ((i & 0x3) == 0x3) {
//32 bit //32 bit
@ -411,7 +439,7 @@ public:
case 0x6F:rfWrite(rd32, pc + 4);pcWrite(pc + (iBits(21, 10) << 1) + (iBits(20, 1) << 11) + (iBits(12, 8) << 12) + (iSign() << 20));break; //JAL case 0x6F:rfWrite(rd32, pc + 4);pcWrite(pc + (iBits(21, 10) << 1) + (iBits(20, 1) << 11) + (iBits(12, 8) << 12) + (iSign() << 20));break; //JAL
case 0x67:{ case 0x67:{
uint32_t target = (i32_rs1 + i32_i_imm) & ~1; uint32_t target = (i32_rs1 + i32_i_imm) & ~1;
rfWrite(rd32, pc + 4); if(isPcAligned(target)) rfWrite(rd32, pc + 4);
pcWrite(target); pcWrite(target);
} break; //JALR } break; //JALR
case 0x63: case 0x63:
@ -424,24 +452,36 @@ public:
case 0x7:if (uint32_t(i32_rs1) >= uint32_t(i32_rs2))pcWrite(pc + i32_sb_imm); else pcWrite(pc + 4);break; case 0x7:if (uint32_t(i32_rs1) >= uint32_t(i32_rs2))pcWrite(pc + i32_sb_imm); else pcWrite(pc + 4);break;
} }
break; break;
case 0x03: //LOADS case 0x03:{ //LOADS
uint32_t data; uint32_t data;
dRead(i32_rs1 + i32_i_imm, 1 << ((i >> 12) & 0x3), &data); uint32_t address = i32_rs1 + i32_i_imm;
switch ((i >> 12) & 0x7) { uint32_t size = 1 << ((i >> 12) & 0x3);
case 0x0:rfWrite(rd32, int8_t(data));pcWrite(pc + 4);break; if(address & (size-1)){
case 0x1:rfWrite(rd32, int16_t(data));pcWrite(pc + 4);break; exception(0, 4);
case 0x2:rfWrite(rd32, int32_t(data));pcWrite(pc + 4);break; } else {
case 0x4:rfWrite(rd32, uint8_t(data));pcWrite(pc + 4);break; if(dRead(address, size, &data)){
case 0x5:rfWrite(rd32, uint16_t(data));pcWrite(pc + 4);break; exception(0, 5);
} else {
switch ((i >> 12) & 0x7) {
case 0x0:rfWrite(rd32, int8_t(data));pcWrite(pc + 4);break;
case 0x1:rfWrite(rd32, int16_t(data));pcWrite(pc + 4);break;
case 0x2:rfWrite(rd32, int32_t(data));pcWrite(pc + 4);break;
case 0x4:rfWrite(rd32, uint8_t(data));pcWrite(pc + 4);break;
case 0x5:rfWrite(rd32, uint16_t(data));pcWrite(pc + 4);break;
}
}
} }
break; }break;
case 0x23: //STORE case 0x23: { //STORE
switch ((i >> 12) & 0x7) { uint32_t address = i32_rs1 + i32_s_imm;
case 0x0:dWrite(i32_rs1 + i32_s_imm, 1, i32_rs2);pcWrite(pc + 4);break; uint32_t size = 1 << ((i >> 12) & 0x3);
case 0x1:dWrite(i32_rs1 + i32_s_imm, 2, i32_rs2);pcWrite(pc + 4);break; if(address & (size-1)){
case 0x2:dWrite(i32_rs1 + i32_s_imm, 4, i32_rs2);pcWrite(pc + 4);break; exception(0, 6);
} else {
dWrite(address, size, i32_rs2);
pcWrite(pc + 4);
} }
break; }break;
case 0x13: //ALUi case 0x13: //ALUi
switch ((i >> 12) & 0x7) { switch ((i >> 12) & 0x7) {
case 0x0:rfWrite(rd32, i32_rs1 + i32_i_imm);pcWrite(pc + 4);break; case 0x0:rfWrite(rd32, i32_rs1 + i32_i_imm);pcWrite(pc + 4);break;
@ -500,13 +540,21 @@ public:
break; break;
case 0x73:{ case 0x73:{
if(i32_func3 == 0){ if(i32_func3 == 0){
switch(i){ switch(i){
case 0x30200073:{ //MRET case 0x30200073:{ //MRET
status.mie = status.mpie; status.mie = status.mpie;
//privilege := mstatus.MPP //privilege := mstatus.MPP
pcWrite(mepc); pcWrite(mepc);
}break; }break;
case 0x00000073:{ //ECALL
exception(0, 11);
}break;
case 0x10500073:{ //WFI
pcWrite(pc + 4);
}break;
default:
ilegalInstruction();
break;
} }
} else { } else {
//CSR //CSR
@ -533,11 +581,26 @@ public:
case 0: rfWrite(i16_addr2, rf_sp + i16_addi4spn_imm); pcWrite(pc + 2); break; case 0: rfWrite(i16_addr2, rf_sp + i16_addi4spn_imm); pcWrite(pc + 2); break;
case 2: { case 2: {
uint32_t data; uint32_t data;
dRead(i16_rf1 + i16_lw_imm, 4, &data); uint32_t address = i16_rf1 + i16_lw_imm;
rfWrite(i16_addr2, data); pcWrite(pc + 2); if(address & 0x3){
break; exception(0, 4);
} } else {
case 6: dWrite(i16_rf1 + i16_lw_imm, 4, i16_rf2); pcWrite(pc + 2); break; if(dRead(i16_rf1 + i16_lw_imm, 4, &data)) {
exception(1, 5);
} else {
rfWrite(i16_addr2, data); pcWrite(pc + 2);
}
}
} break;
case 6: {
uint32_t address = i16_rf1 + i16_lw_imm;
if(address & 0x3){
exception(0, 6);
} else {
dWrite(address, 4, i16_rf2);
pcWrite(pc + 2);
}
}break;
case 8: rfWrite(rd32, regs[rd32] + i16_imm); pcWrite(pc + 2); break; case 8: rfWrite(rd32, regs[rd32] + i16_imm); pcWrite(pc + 2); break;
case 9: rfWrite(1, pc + 2);pcWrite(pc + i16_j_imm); break; case 9: rfWrite(1, pc + 2);pcWrite(pc + i16_j_imm); break;
case 10: rfWrite(rd32, i16_imm);pcWrite(pc + 2); break; case 10: rfWrite(rd32, i16_imm);pcWrite(pc + 2); break;
@ -565,9 +628,17 @@ public:
case 16: rfWrite(rd32, regs[rd32] << i16_zimm); pcWrite(pc + 2); break; case 16: rfWrite(rd32, regs[rd32] << i16_zimm); pcWrite(pc + 2); break;
case 18:{ case 18:{
uint32_t data; uint32_t data;
dRead(rf_sp + i16_lwsp_imm, 4, &data); uint32_t address = rf_sp + i16_lwsp_imm;
rfWrite(rd32, data); pcWrite(pc + 2); break; if(address & 0x3){
} exception(0, 4);
} else {
if(dRead(address, 4, &data)){
exception(1, 5);
} else {
rfWrite(rd32, data); pcWrite(pc + 2);
}
}
}break;
case 20: case 20:
if(i & 0x1000){ if(i & 0x1000){
if(iBits(2,10) == 0){ if(iBits(2,10) == 0){
@ -585,7 +656,14 @@ public:
} }
} }
break; break;
case 22: dWrite(rf_sp + i16_swsp_imm, 4, regs[iBits(2,5)]); pcWrite(pc + 2); break; case 22: {
uint32_t address = rf_sp + i16_swsp_imm;
if(address & 3){
exception(0,6);
} else {
dWrite(address, 4, regs[iBits(2,5)]); pcWrite(pc + 2);
}
}break;
} }
} }
} }
@ -681,9 +759,9 @@ public:
virtual bool iRead(int32_t address, uint32_t *data){ virtual bool iRead(int32_t address, uint32_t *data){
mem.read(address, 4, (uint8_t*)data);
bool error; bool error;
ws->iBusAccessPatch(address,data,&error); ws->iBusAccess(address, data, &error);
// ws->iBusAccessPatch(address,data,&error);
return error; return error;
} }
@ -700,6 +778,7 @@ public:
} }
*data = t.data; *data = t.data;
periphRead.pop(); periphRead.pop();
return t.error;
}else { }else {
mem.read(address, size, (uint8_t*)data); mem.read(address, size, (uint8_t*)data);
} }
@ -1032,11 +1111,6 @@ public:
} }
#endif #endif
if(top->VexRiscv->writeBack_arbitration_isFiring){ if(top->VexRiscv->writeBack_arbitration_isFiring){
if(riscvRefEnable && top->VexRiscv->writeBack_PC != riscvRef.pc){
cout << " pc missmatch " << top->VexRiscv->writeBack_PC << " should be " << riscvRef.pc << endl;
fail();
}
if(riscvRefEnable) { if(riscvRefEnable) {
riscvRef.step(); riscvRef.step();
bool mIntTimer = false; bool mIntTimer = false;
@ -1053,6 +1127,10 @@ public:
riscvRef.liveness(mIntTimer, mIntExt); riscvRef.liveness(mIntTimer, mIntExt);
} }
if(riscvRefEnable && top->VexRiscv->writeBack_PC != riscvRef.lastPc){
cout << hex << " pc missmatch " << top->VexRiscv->writeBack_PC << " should be " << riscvRef.lastPc << dec << endl;
fail();
}
bool rfWriteValid = false; bool rfWriteValid = false;
@ -2687,6 +2765,7 @@ int main(int argc, char **argv, char **env) {
printf("BOOT\n"); printf("BOOT\n");
timespec startedAt = timer_start(); timespec startedAt = timer_start();
for(int idx = 0;idx < 1;idx++){ for(int idx = 0;idx < 1;idx++){
#if defined(DEBUG_PLUGIN_EXTERNAL) || defined(RUN_HEX) #if defined(DEBUG_PLUGIN_EXTERNAL) || defined(RUN_HEX)