diff --git a/.github/workflows/emu.yml b/.github/workflows/emu.yml index 326ccff73b2c0af2d4c0eace27494b52764e4869..68f7c783bd7c1261abb6fa0d573f650a5c8d9ce5 100644 --- a/.github/workflows/emu.yml +++ b/.github/workflows/emu.yml @@ -36,7 +36,7 @@ jobs: t=${test%.c} echo $t make -C $CPU_TEST_DIR ALL=$t ARCH=riscv64-noop AM_HOME=$AM_HOME NEMU_HOME=$NEMU_HOME NOOP_HOME=$NOOP_HOME run 2>/dev/null | grep "HIT GOOD TRAP" - if [[ $? == 1 ]]; + if [[ $? != 0 ]]; then echo $t fail ret=1 diff --git a/debug/cputest.sh b/debug/cputest.sh index 5510d73acde11dc1fc7b94c3c5fdbb2104111d84..79e89a1edae647d155bf632f504187420014c09a 100755 --- a/debug/cputest.sh +++ b/debug/cputest.sh @@ -7,8 +7,8 @@ do t=${test%.c} echo -n -e "\x1b[0m $t: " make -C $TEST_HOME ARCH=riscv64-noop E=0 ALL=$t run 2>/dev/null | grep -E "HIT GOOD TRAP|IPC" - if [[ $? == 1 ]]; + if [[ $? != 0 ]]; then - echo -e "\x1b[31mfail" + echo -e "\x1b[31mfail: trap code $?" fi done diff --git a/src/main/scala/xiangshan/backend/brq/Brq.scala b/src/main/scala/xiangshan/backend/brq/Brq.scala index c78df257923146521b7a706bb2ddd959f5602b23..aa5a6ce94528765d3349f0850d1d4ce7de898028 100644 --- a/src/main/scala/xiangshan/backend/brq/Brq.scala +++ b/src/main/scala/xiangshan/backend/brq/Brq.scala @@ -125,7 +125,7 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { io.brTags(i) := brTag when (io.enqReqs(i).fire()) { brQueue(idx).ptrFlag := brTag.flag - brQueue(idx).exuOut.brUpdate.pc := io.enqReqs(i).bits.cf.brUpdate.pc + brQueue(idx).exuOut.brUpdate.pc := io.enqReqs(i).bits.cf.pc brQueue(idx).exuOut.brUpdate.pnpc := io.enqReqs(i).bits.cf.brUpdate.pnpc brQueue(idx).exuOut.brUpdate.fetchIdx := io.enqReqs(i).bits.cf.brUpdate.fetchIdx brQueue(idx).exuOut.brUpdate.pd := io.enqReqs(i).bits.cf.brUpdate.pd diff --git a/src/main/scala/xiangshan/cache/dtlb.scala b/src/main/scala/xiangshan/cache/dtlb.scala index 52c0f2bb9e99c682116fc8a1e656e514d385ef05..9f764e6952cf79495693a48de038efa84cfdadf0 100644 --- a/src/main/scala/xiangshan/cache/dtlb.scala +++ b/src/main/scala/xiangshan/cache/dtlb.scala @@ -141,7 +141,7 @@ class TlbEntires(num: Int, tagLen: Int) extends TlbBundle { } def hit(vpn: UInt) = { - (tag === tagClip(vpn, level)) && vs(idxClip(vpn, level)) + (tag === tagClip(vpn, level)) && vs(idxClip(vpn, level)) && (level === 2.U) } def genEntries(data: UInt, level: UInt, vpn: UInt): TlbEntires = { diff --git a/src/main/scala/xiangshan/cache/ptw.scala b/src/main/scala/xiangshan/cache/ptw.scala index cb5ef389d36cade6c225a3981757bfbf4cb76e27..035a97ee4ec93a5c25a1f6e6eacf6daa50762e24 100644 --- a/src/main/scala/xiangshan/cache/ptw.scala +++ b/src/main/scala/xiangshan/cache/ptw.scala @@ -455,7 +455,7 @@ class PTWImp(outer: PTW) extends PtwModule(outer){ l2g := (l2g & ~UIntToOH(refillIdx)) | Mux(Cat(memPtes.map(_.perm.g)).andR, UIntToOH(refillIdx), 0.U) XSDebug(p"ptwl2 RefillIdx:${Hexadecimal(refillIdx)} ps:${ps}\n") } - when (memPte.isLeaf()) { + when (memPte.isLeaf() && (level===2.U)) { val refillIdx = genTlbL2Idx(req.vpn)//getVpnn(req.vpn, 0)(log2Up(TlbL2EntrySize)-1, 0) //TODO: check why the old refillIdx is right diff --git a/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala b/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala index b5877785d70d73fa2f82876b25616650a1fa2cc8..c50dd763af73ee04edaf9b0fac2bf8c5b8b4da5a 100644 --- a/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala +++ b/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala @@ -292,6 +292,17 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue assert(io.sbuffer(0).fire()) } } + if (!env.FPGAPlatform) { + val storeCommit = PopCount(io.sbuffer.map(_.fire())) + val waddr = VecInit(io.sbuffer.map(req => SignExt(req.bits.addr, 64))) + val wdata = VecInit(io.sbuffer.map(req => req.bits.data & MaskExpand(req.bits.mask))) + val wmask = VecInit(io.sbuffer.map(_.bits.mask)) + + ExcitingUtils.addSource(RegNext(storeCommit), "difftestStoreCommit", ExcitingUtils.Debug) + ExcitingUtils.addSource(RegNext(waddr), "difftestStoreAddr", ExcitingUtils.Debug) + ExcitingUtils.addSource(RegNext(wdata), "difftestStoreData", ExcitingUtils.Debug) + ExcitingUtils.addSource(RegNext(wmask), "difftestStoreMask", ExcitingUtils.Debug) + } // Read vaddr for mem exception io.exceptionAddr.vaddr := dataModule.io.rdata(io.exceptionAddr.lsIdx.sqIdx.value).vaddr diff --git a/src/test/csrc/difftest.cpp b/src/test/csrc/difftest.cpp index 74db9a59ccacca71894a54defa9f14d23a1ce975..2f3815beda49ea23e8f163e3db0c6ddd3b3832e7 100644 --- a/src/test/csrc/difftest.cpp +++ b/src/test/csrc/difftest.cpp @@ -21,6 +21,7 @@ void (*ref_difftest_set_mastatus)(const void *s) = NULL; void (*ref_difftest_get_csr)(void *c) = NULL; void (*ref_difftest_set_csr)(const void *c) = NULL; vaddr_t (*ref_disambiguate_exec)(void *disambiguate_para) = NULL; +int (*ref_difftest_store_commit)(uint64_t *saddr, uint64_t *sdata, uint8_t *smask) = NULL; static void (*ref_difftest_exec)(uint64_t n) = NULL; static void (*ref_difftest_raise_intr)(uint64_t NO) = NULL; static void (*ref_isa_reg_display)(void) = NULL; @@ -77,6 +78,9 @@ void init_difftest() { ref_disambiguate_exec = (vaddr_t (*)(void *))dlsym(handle, "disambiguate_exec"); assert(ref_disambiguate_exec); + ref_difftest_store_commit = (int (*)(uint64_t*, uint64_t*, uint8_t*))dlsym(handle, "difftest_store_commit"); + assert(ref_difftest_store_commit); + ref_difftest_exec = (void (*)(uint64_t))dlsym(handle, "difftest_exec"); assert(ref_difftest_exec); @@ -249,3 +253,7 @@ int difftest_step(DiffState *s) { } return 0; } + +int difftest_store_step(uint64_t *saddr, uint64_t *sdata, uint8_t *smask) { + return ref_difftest_store_commit(saddr, sdata, smask); +} diff --git a/src/test/csrc/difftest.h b/src/test/csrc/difftest.h index 6f4d201c34b53fea824f0778cfa734b873cd096b..3fecfcfa6b7c5d889499080e7144e85abb87e812 100644 --- a/src/test/csrc/difftest.h +++ b/src/test/csrc/difftest.h @@ -67,6 +67,11 @@ struct DiffState { // lrscValid needs to be synced as nemu does not know // how many cycles were used to finish a lr/sc pair, // this will lead to different sc results. + + int store_commit; + uint64_t store_addr[2]; + uint64_t store_data[2]; + uint8_t store_mask[2]; }; struct DisambiguationState { @@ -84,9 +89,11 @@ extern void (*ref_difftest_set_mastatus)(const void *s); extern void (*ref_difftest_get_csr)(void *c); extern void (*ref_difftest_set_csr)(const void *c); extern vaddr_t (*ref_disambiguate_exec)(void *disambiguate_para); +extern int (*ref_difftest_store_commit)(uint64_t *saddr, uint64_t *sdata, uint8_t *smask); void init_difftest(); int difftest_step(DiffState *s); +int difftest_store_step(uint64_t *saddr, uint64_t *sdata, uint8_t *smask); void difftest_display(uint8_t mode); #endif diff --git a/src/test/csrc/emu.cpp b/src/test/csrc/emu.cpp index b0ce0789ed950bc597b71115bc19db7b0eb42395..0bbc7bf080c175da3553c73b31c7fc6db568e65f 100644 --- a/src/test/csrc/emu.cpp +++ b/src/test/csrc/emu.cpp @@ -184,6 +184,15 @@ inline void Emulator::read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wds dut_ptr_wpc(5); dut_ptr_wdata(5); dut_ptr_wdst(5); } +inline void Emulator::read_store_info(uint64_t *saddr, uint64_t *sdata, uint8_t *smask) { +#define dut_ptr_saddr(x) saddr[x] = dut_ptr->io_difftest_storeAddr_##x +#define dut_ptr_sdata(x) sdata[x] = dut_ptr->io_difftest_storeData_##x +#define dut_ptr_smask(x) smask[x] = dut_ptr->io_difftest_storeMask_##x + dut_ptr_saddr(0); dut_ptr_saddr(1); + dut_ptr_sdata(0); dut_ptr_sdata(1); + dut_ptr_smask(0); dut_ptr_smask(1); +} + inline void Emulator::reset_ncycles(size_t cycles) { for(int i = 0; i < cycles; i++) { dut_ptr->reset = 1; @@ -317,6 +326,25 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) { max_instr -= diff.commit; } + if (dut_ptr->io_difftest_storeCommit) { + read_store_info(diff.store_addr, diff.store_data, diff.store_mask); + + for (int i = 0; i < dut_ptr->io_difftest_storeCommit; i++) { + auto addr = diff.store_addr[i]; + auto data = diff.store_data[i]; + auto mask = diff.store_mask[i]; + if (difftest_store_step(&addr, &data, &mask)) { + difftest_display(dut_ptr->io_difftest_priviledgeMode); + printf("Mismatch for store commits: \n"); + printf("REF commits addr 0x%lx, data 0x%lx, mask 0x%x\n", addr, data, mask); + printf("DUT commits addr 0x%lx, data 0x%lx, mask 0x%x\n", + diff.store_addr[i], diff.store_data[i], diff.store_mask[i]); + trapCode = STATE_ABORT; + break; + } + } + } + uint32_t t = uptime(); if (t - lasttime_poll > 100) { poll_event(); @@ -447,10 +475,10 @@ void Emulator::snapshot_save(const char *filename) { uint64_t nemu_this_pc = get_nemu_this_pc(); stream.unbuf_write(&nemu_this_pc, sizeof(nemu_this_pc)); - char *buf = new char[size]; + char *buf = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); ref_difftest_memcpy_from_ref(buf, 0x80000000, size); stream.unbuf_write(buf, size); - delete [] buf; + munmap(buf, size); struct SyncState sync_mastate; ref_difftest_get_mastatus(&sync_mastate); @@ -488,10 +516,10 @@ void Emulator::snapshot_load(const char *filename) { stream.read(&nemu_this_pc, sizeof(nemu_this_pc)); set_nemu_this_pc(nemu_this_pc); - char *buf = new char[size]; + char *buf = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); stream.read(buf, size); ref_difftest_memcpy_from_dut(0x80000000, buf, size); - delete [] buf; + munmap(buf, size); struct SyncState sync_mastate; stream.read(&sync_mastate, sizeof(struct SyncState)); diff --git a/src/test/csrc/emu.h b/src/test/csrc/emu.h index ae4ba88eaf71fdebe0b499b563acf908614cef77..60ec241a5ab7a9bcd6a07c6cf5c4d0ea93981bf3 100644 --- a/src/test/csrc/emu.h +++ b/src/test/csrc/emu.h @@ -40,9 +40,9 @@ class Emulator { enum { STATE_GOODTRAP = 0, - STATE_BADTRAP, - STATE_ABORT, - STATE_LIMIT_EXCEEDED, + STATE_BADTRAP = 1, + STATE_ABORT = 2, + STATE_LIMIT_EXCEEDED = 3, STATE_RUNNING = -1 }; @@ -53,6 +53,7 @@ class Emulator { inline void read_emu_regs(uint64_t *r); inline void read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst); + inline void read_store_info(uint64_t *saddr, uint64_t *sdata, uint8_t *smask); inline void reset_ncycles(size_t cycles); inline void single_cycle(); void display_trapinfo(); @@ -73,4 +74,5 @@ public: uint64_t get_cycles() const { return cycles; } EmuArgs get_args() const { return args; } bool is_good_trap() { return trapCode == STATE_GOODTRAP; }; + int get_trapcode() { return trapCode; } }; diff --git a/src/test/csrc/main.cpp b/src/test/csrc/main.cpp index 1d9299ac96d2e053544d9f98eca46bf7f7eec416..a471c91f2dba3a4070a63836d0cdf11fd364148e 100644 --- a/src/test/csrc/main.cpp +++ b/src/test/csrc/main.cpp @@ -21,6 +21,7 @@ int main(int argc, const char** argv) { auto args = emu->get_args(); uint64_t cycles = emu->execute(args.max_cycles, args.max_instr); bool is_good_trap = emu->is_good_trap(); + int trapcode = emu->get_trapcode(); delete emu; extern uint32_t uptime(void); @@ -30,5 +31,6 @@ int main(int argc, const char** argv) { " (this will be different from cycleCnt if emu loads a snapshot)\n" ANSI_COLOR_RESET, args.seed, cycles); eprintf(ANSI_COLOR_BLUE "Host time spent: %dms\n" ANSI_COLOR_RESET, ms); - return !is_good_trap; + // return !is_good_trap; + return trapcode; } diff --git a/src/test/csrc/ram.h b/src/test/csrc/ram.h index c2d59f0864057885574b86ab2462cca0f7fccc47..342036085c1b7dc361f3291b7783ffe4dd37b2ec 100644 --- a/src/test/csrc/ram.h +++ b/src/test/csrc/ram.h @@ -4,6 +4,7 @@ #include "common.h" #define EMU_RAM_SIZE (256 * 1024 * 1024UL) +// #define EMU_RAM_SIZE (8 * 1024 * 1024 * 1024UL) void init_ram(const char *img); void ram_finish(); diff --git a/src/test/scala/top/XSSim.scala b/src/test/scala/top/XSSim.scala index aa21be4d042c805c5afb2eec0222075efd4408d5..13c82e6ca80e7d5be4e99da7ace39e863467d20b 100644 --- a/src/test/scala/top/XSSim.scala +++ b/src/test/scala/top/XSSim.scala @@ -48,6 +48,11 @@ class DiffTestIO extends XSBundle { val medeleg = Output(UInt(64.W)) val scFailed = Output(Bool()) + + val storeCommit = Output(UInt(2.W)) + val storeAddr = Output(Vec(2, UInt(64.W))) + val storeData = Output(Vec(2, UInt(64.W))) + val storeMask = Output(Vec(2, UInt(8.W))) } class LogCtrlIO extends Bundle { @@ -154,6 +159,10 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul ExcitingUtils.addSink(difftest.mideleg, "difftestMideleg", Debug) ExcitingUtils.addSink(difftest.medeleg, "difftestMedeleg", Debug) ExcitingUtils.addSink(difftest.scFailed, "difftestScFailed", Debug) + ExcitingUtils.addSink(difftest.storeCommit, "difftestStoreCommit", Debug) + ExcitingUtils.addSink(difftest.storeAddr, "difftestStoreAddr", Debug) + ExcitingUtils.addSink(difftest.storeData, "difftestStoreData", Debug) + ExcitingUtils.addSink(difftest.storeMask, "difftestStoreMask", Debug) } // BoringUtils.addSink(difftest.lrscAddr, "difftestLrscAddr")