goldenmodel now pass more machine mode CSR tests
This commit is contained in:
parent
ee402ec5dc
commit
3c66f7c58a
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue