diff --git a/src/test/csrc/difftest/difftest.cpp b/src/test/csrc/difftest/difftest.cpp index 220e680cb..538577c99 100644 --- a/src/test/csrc/difftest/difftest.cpp +++ b/src/test/csrc/difftest/difftest.cpp @@ -250,9 +250,12 @@ int Difftest::step() { return 1; } do_first_instr_commit(); - if (do_store_check()) { - return 1; - } + + // Each cycle is checked for an store event, and recorded in queue. + // It is checked every time an instruction is committed and queue has content. +#ifdef CONFIG_DIFFTEST_STOREEVENT + store_event_record(); +#endif #ifdef DEBUG_GOLDENMEM if (do_golden_memory_update()) { @@ -314,6 +317,9 @@ int Difftest::step() { if (do_instr_commit(i)) { return 1; } + if (do_store_check()) { + return 1; + } dut->commit[i].valid = 0; num_commit += 1 + dut->commit[i].nFused; } @@ -611,13 +617,13 @@ void Difftest::do_first_instr_commit() { int Difftest::do_store_check() { #ifdef CONFIG_DIFFTEST_STOREEVENT - for (int i = 0; i < CONFIG_DIFF_STORE_WIDTH; i++) { - if (!dut->store[i].valid) { - return 0; - } - auto addr = dut->store[i].addr; - auto data = dut->store[i].data; - auto mask = dut->store[i].mask; + while (!store_event_queue.empty()) { + auto store_event = store_event_queue.front(); + + auto addr = store_event.addr; + auto data = store_event.data; + auto mask = store_event.mask; + if (proxy->store_commit(&addr, &data, &mask)) { #ifdef FUZZING if (in_disambiguation_state()) { @@ -626,13 +632,15 @@ int Difftest::do_store_check() { } #endif display(); - printf("Mismatch for store commits %d: \n", i); + 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", dut->store[i].addr, dut->store[i].data, - dut->store[i].mask); + printf(" DUT commits addr 0x%lx, data 0x%lx, mask 0x%x\n", store_event.addr, store_event.data, store_event.mask); + + store_event_queue.pop(); return 1; } - dut->store[i].valid = 0; + + store_event_queue.pop(); } #endif // CONFIG_DIFFTEST_STOREEVENT return 0; @@ -1044,6 +1052,19 @@ int Difftest::do_golden_memory_update() { } #endif +#ifdef CONFIG_DIFFTEST_STOREEVENT +void Difftest::store_event_record() { + for (int i = 0; i < CONFIG_DIFF_STORE_WIDTH; i++) { + if (dut->store[i].valid) { + store_event_t event{dut->store[i].addr, dut->store[i].data, dut->store[i].mask}; + store_event_queue.push(event); + + dut->store[i].valid = 0; + } + } +} +#endif + int Difftest::check_timeout() { // check whether there're any commits since the simulation starts if (!has_commit && ticks > last_commit + firstCommit_limit) { diff --git a/src/test/csrc/difftest/difftest.h b/src/test/csrc/difftest/difftest.h index 93b871405..22e01b0a6 100644 --- a/src/test/csrc/difftest/difftest.h +++ b/src/test/csrc/difftest/difftest.h @@ -21,6 +21,7 @@ #include "difftrace.h" #include "golden.h" #include "refproxy.h" +#include #include #ifdef FUZZING #include "emu.h" @@ -62,6 +63,13 @@ enum retire_mem_type { RET_STORE }; +class store_event_t { +public: + uint64_t addr; + uint64_t data; + uint8_t mask; +}; + class CommitTrace { public: uint64_t pc; @@ -302,6 +310,10 @@ class Difftest { uint64_t track_instr = 0; #endif +#ifdef CONFIG_DIFFTEST_STOREEVENT + std::queue store_event_queue; + void store_event_record(); +#endif void update_last_commit() { last_commit = ticks; } @@ -318,6 +330,7 @@ class Difftest { int do_l1tlb_check(); int do_l2tlb_check(); int do_golden_memory_update(); + inline uint64_t get_commit_data(int i) { #ifdef CONFIG_DIFFTEST_ARCHFPREGSTATE if (dut->commit[i].fpwen) {