From c7507465d48f4e8370e7ab1b81eddf85c6df4d4a Mon Sep 17 00:00:00 2001 From: klin02 Date: Thu, 22 Feb 2024 00:08:27 +0800 Subject: [PATCH] Support GoldenMem store log Now we has 3 Memory, DUT REF Golden. When Squash replay, DUT will transmit unsquashed DiffState which are already generated and stored, and we will reset REF and Golden Memory to process these states. Overall, DUT memory doesn't need to restore. REF and Golden Memory will be restored by store_log. --- config/config.h | 3 +- src/test/csrc/difftest/difftest.cpp | 15 ++++++--- src/test/csrc/difftest/difftest.h | 3 +- src/test/csrc/difftest/goldenmem.cpp | 48 ++++++++++++++++++++++++++-- src/test/csrc/difftest/goldenmem.h | 5 +++ src/test/csrc/difftest/refproxy.cpp | 4 +-- src/test/csrc/difftest/refproxy.h | 14 ++++++++ 7 files changed, 79 insertions(+), 13 deletions(-) diff --git a/config/config.h b/config/config.h index dd444128b..003d0b0d1 100644 --- a/config/config.h +++ b/config/config.h @@ -113,7 +113,7 @@ extern unsigned long EMU_FLASH_SIZE; // whether to check l2tlb response // #define DEBUG_L2TLB -// whether to enable REF record origin data of memory and restore +// whether to enable REF/GoldenMemory record origin data of memory and restore #ifdef CONFIG_DIFFTEST_SQUASH_REPLAY #define ENABLE_STORE_LOG #endif // CONFIG_DIFFTEST_SQUASH_REPLAY @@ -157,7 +157,6 @@ extern unsigned long EMU_FLASH_SIZE; #define DEBUG_MEM_BASE 0x38020000 #endif - // ----------------------------------------------------------------------- // Do not touch // ----------------------------------------------------------------------- diff --git a/src/test/csrc/difftest/difftest.cpp b/src/test/csrc/difftest/difftest.cpp index 162bd6f69..1beeb9903 100644 --- a/src/test/csrc/difftest/difftest.cpp +++ b/src/test/csrc/difftest/difftest.cpp @@ -161,8 +161,8 @@ Difftest::~Difftest() { } #ifdef CONFIG_DIFFTEST_SQUASH_REPLAY free(state_ss); - if (proxy_ss) { - free(proxy_ss); + if (proxy_reg_ss) { + free(proxy_reg_ss); } #endif // CONFIG_DIFFTEST_SQUASH_REPLAY } @@ -170,7 +170,8 @@ Difftest::~Difftest() { void Difftest::update_nemuproxy(int coreid, size_t ram_size = 0) { proxy = new REF_PROXY(coreid, ram_size); #ifdef CONFIG_DIFFTEST_SQUASH_REPLAY - proxy_ss = (REF_PROXY*)malloc(sizeof(REF_PROXY)); + proxy_reg_size = proxy->get_reg_size(); + proxy_reg_ss = (uint8_t*)malloc(proxy_reg_size); #endif // CONFIG_DIFFTEST_SQUASH_REPLAY } @@ -185,20 +186,23 @@ bool Difftest::squash_check() { void Difftest::squash_snapshot() { memcpy(state_ss, state, sizeof(DiffState)); - memcpy(proxy_ss, proxy, sizeof(REF_PROXY)); + memcpy(proxy_reg_ss, &proxy->regs_int, proxy_reg_size); proxy->ref_csrcpy(squash_csr_buf, REF_TO_DUT); proxy->ref_store_log_reset(); proxy->set_store_log(true); + goldenmem_store_log_reset(); + goldenmem_set_store_log(true); } void Difftest::squash_replay() { inReplay = true; replay_idx = squash_idx; memcpy(state, state_ss, sizeof(DiffState)); - memcpy(proxy, proxy_ss, sizeof(REF_PROXY)); + memcpy(&proxy->regs_int, proxy_reg_ss, proxy_reg_size); proxy->ref_regcpy(&proxy->regs_int, DUT_TO_REF, false); proxy->ref_csrcpy(squash_csr_buf, DUT_TO_REF); proxy->ref_store_log_restore(); + goldenmem_store_log_restore(); difftest_squash_replay(replay_idx); } #endif // CONFIG_DIFFTEST_SQUASH_REPLAY @@ -217,6 +221,7 @@ int Difftest::step() { squash_snapshot(); } else { proxy->set_store_log(false); + goldenmem_set_store_log(false); } #endif // CONFIG_DIFFTEST_SQUASH_REPLAY diff --git a/src/test/csrc/difftest/difftest.h b/src/test/csrc/difftest/difftest.h index 48acd9ead..50b21dbd8 100644 --- a/src/test/csrc/difftest/difftest.h +++ b/src/test/csrc/difftest/difftest.h @@ -366,7 +366,8 @@ class Difftest { int replay_idx; DiffState *state_ss = NULL; - REF_PROXY *proxy_ss = NULL; + int proxy_reg_size = 0; + uint8_t *proxy_reg_ss = NULL; uint64_t squash_csr_buf[4096]; bool squash_check(); void squash_snapshot(); diff --git a/src/test/csrc/difftest/goldenmem.cpp b/src/test/csrc/difftest/goldenmem.cpp index 38dd7cd5a..eb1ac168a 100644 --- a/src/test/csrc/difftest/goldenmem.cpp +++ b/src/test/csrc/difftest/goldenmem.cpp @@ -97,6 +97,44 @@ static inline void pmem_write(uint64_t addr, word_t data, int len) { } } +// Golden Memory Store Log +#ifdef ENABLE_STORE_LOG +#define GOLDENMEM_STORE_LOG_SIZE 1024 +struct store_log { + uint64_t addr; + word_t org_data; +} goldenmem_store_log_buf[GOLDENMEM_STORE_LOG_SIZE]; + +bool goldenmem_store_log_enable = false; +int goldenmem_store_log_ptr = 0; + +void goldenmem_set_store_log(bool enable) { + goldenmem_store_log_enable = enable; +} + +void goldenmem_store_log_reset() { + goldenmem_store_log_ptr = 0; +} + +void pmem_record_store(uint64_t addr) { + if (goldenmem_store_log_enable) { + // align to 8 byte + addr = (addr >> 3) << 3; + word_t rdata = pmem_read(addr, 8); + goldenmem_store_log_buf[goldenmem_store_log_ptr].addr = addr; + goldenmem_store_log_buf[goldenmem_store_log_ptr].org_data = rdata; + ++goldenmem_store_log_ptr; + if (goldenmem_store_log_ptr >= GOLDENMEM_STORE_LOG_SIZE) assert(0); + } +} + +void goldenmem_store_log_restore() { + for (int i = goldenmem_store_log_ptr - 1; i >= 0; i--) { + pmem_write(goldenmem_store_log_buf[i].addr, goldenmem_store_log_buf[i].org_data, 8); + } +} +#endif // ENABLE_STORE_LOG + /* Memory accessing interfaces */ inline word_t paddr_read(uint64_t addr, int len) { @@ -109,6 +147,10 @@ inline word_t paddr_read(uint64_t addr, int len) { } inline void paddr_write(uint64_t addr, word_t data, int len) { - if (in_pmem(addr)) pmem_write(addr, data, len); - else panic("write not in pmem!"); -} \ No newline at end of file + if (in_pmem(addr)) { +#ifdef ENABLE_STORE_LOG + if (goldenmem_store_log_enable) pmem_record_store(addr); +#endif // ENABLE_STORE_LOG + pmem_write(addr, data, len); + } else panic("write not in pmem!"); +} diff --git a/src/test/csrc/difftest/goldenmem.h b/src/test/csrc/difftest/goldenmem.h index c49a9b0ff..667748aff 100644 --- a/src/test/csrc/difftest/goldenmem.h +++ b/src/test/csrc/difftest/goldenmem.h @@ -45,4 +45,9 @@ void paddr_write(uint64_t addr, word_t data, int len); bool is_sfence_safe(uint64_t addr, int len); bool in_pmem(uint64_t addr); +#ifdef ENABLE_STORE_LOG +void goldenmem_set_store_log(bool enable); +void goldenmem_store_log_reset(); +void goldenmem_store_log_restore(); +#endif #endif diff --git a/src/test/csrc/difftest/refproxy.cpp b/src/test/csrc/difftest/refproxy.cpp index 387cbcdcf..b8e1f6866 100644 --- a/src/test/csrc/difftest/refproxy.cpp +++ b/src/test/csrc/difftest/refproxy.cpp @@ -72,10 +72,10 @@ AbstractRefProxy::AbstractRefProxy(int coreid, size_t ram_size, const char *env, ref_set_ramsize(ram_size); } -#ifdef CONFIG_DIFFTEST_SQUASH_REPLAY +#ifdef ENABLE_STORE_LOG check_and_assert(ref_store_log_reset); check_and_assert(ref_store_log_restore); -#endif // CONFIG_DIFFTEST_SQUASH_REPLAY +#endif // ENABLE_STORE_LOG ref_init(); } diff --git a/src/test/csrc/difftest/refproxy.h b/src/test/csrc/difftest/refproxy.h index 8a4e2bfb1..e8dc6593a 100644 --- a/src/test/csrc/difftest/refproxy.h +++ b/src/test/csrc/difftest/refproxy.h @@ -222,6 +222,20 @@ class RefProxy : public AbstractRefProxy { } #endif // ENABLE_STORE_LOG + inline int get_reg_size() { + return sizeof(DifftestArchIntRegState) + sizeof(DifftestCSRState) + sizeof(uint64_t) +#ifdef CONFIG_DIFFTEST_ARCHFPREGSTATE + + sizeof(DifftestArchFpRegState) +#endif // CONFIG_DIFFTEST_ARCHFPREGSTATE +#ifdef CONFIG_DIFFTEST_ARCHVECREGSTATE + + sizeof(DifftestArchVecRegState) +#endif // CONFIG_DIFFTEST_ARCHVECREGSTATE +#ifdef CONFIG_DIFFTEST_VECCSRSTATE + + sizeof(DifftestVecCSRState) +#endif // CONFIG_DIFFTEST_VECCSRSTATE + ; + } + inline int get_status() { return ref_status ? ref_status() : 0; }