From 98037cad56b67eac08982bc9af75cc5a24cfc3d4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 28 Nov 2021 14:00:19 -0500 Subject: [PATCH] Internals: Optimize VL_RANDOM to have unclean output --- include/verilated.cpp | 12 ++++++------ include/verilated_funcs.h | 7 ++++--- src/V3AstNodes.h | 9 +++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/include/verilated.cpp b/include/verilated.cpp index b3cca5256..96ad788e4 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -312,23 +312,23 @@ vluint64_t vl_rand64() VL_MT_SAFE { // VL_RANDOM_W currently unused as $random always 32 bits, left for backwards compatibility // LCOV_EXCL_START WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE { - for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = vl_rand64(); - outwp[VL_WORDS_I(obits) - 1] = vl_rand64() & VL_MASK_E(obits); + for (int i = 0; i < VL_WORDS_I(obits); ++i) outwp[i] = vl_rand64(); + // Last word is unclean return outwp; } // LCOV_EXCL_STOP #endif -IData VL_RANDOM_SEEDED_II(int obits, IData seed) VL_MT_SAFE { +IData VL_RANDOM_SEEDED_II(IData seed) VL_MT_SAFE { Verilated::threadContextp()->randSeed(static_cast(seed)); - return VL_RANDOM_I(obits); + return VL_RANDOM_I(); } IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { if (Verilated::threadContextp()->randReset() == 0) return 0; IData data = ~0; if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize - data = VL_RANDOM_I(obits); + data = VL_RANDOM_I(); } data &= VL_MASK_I(obits); return data; @@ -337,7 +337,7 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE { if (Verilated::threadContextp()->randReset() == 0) return 0; QData data = ~0ULL; if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize - data = VL_RANDOM_Q(obits); + data = VL_RANDOM_Q(); } data &= VL_MASK_Q(obits); return data; diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index a825163ea..5442260cf 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -73,12 +73,13 @@ extern void VL_PRINTF_MT(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE; /// Print a debug message from internals with standard prefix, with printf style format extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE; -inline IData VL_RANDOM_I(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_I(obits); } -inline QData VL_RANDOM_Q(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_Q(obits); } +// EMIT_RULE: VL_RANDOM: oclean=dirty +inline IData VL_RANDOM_I() VL_MT_SAFE { return vl_rand64(); } +inline QData VL_RANDOM_Q() VL_MT_SAFE { return vl_rand64(); } #ifndef VL_NO_LEGACY extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); #endif -extern IData VL_RANDOM_SEEDED_II(int obits, IData seed) VL_MT_SAFE; +extern IData VL_RANDOM_SEEDED_II(IData seed) VL_MT_SAFE; inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) { const vluint64_t rnd = vl_rand64(); if (VL_LIKELY(hi > lo)) { diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index dce0fa34e..3524454d4 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -5471,11 +5471,12 @@ public: : (m_urandom ? "%f$urandom()" : "%f$random()"); } virtual string emitC() override { - return m_reset ? "VL_RAND_RESET_%nq(%nw, %P)" - : seedp() ? "VL_RANDOM_SEEDED_%nq%lq(%nw, %P, %li)" - : "VL_RANDOM_%nq(%nw, %P)"; + return m_reset ? "VL_RAND_RESET_%nq(%nw, %P)" + : seedp() ? "VL_RANDOM_SEEDED_%nq%lq(%li)" + : isWide() ? "VL_RANDOM_%nq(%nw, %P)" // + : "VL_RANDOM_%nq()"; } - virtual bool cleanOut() const override { return true; } + virtual bool cleanOut() const override { return false; } virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual int instrCount() const override { return INSTR_COUNT_PLI; }