Internals: Optimize VL_RANDOM to have unclean output

This commit is contained in:
Wilson Snyder 2021-11-28 14:00:19 -05:00
parent 61e3536163
commit 98037cad56
3 changed files with 15 additions and 13 deletions

View File

@ -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 // VL_RANDOM_W currently unused as $random always 32 bits, left for backwards compatibility
// LCOV_EXCL_START // LCOV_EXCL_START
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE { 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(); for (int i = 0; i < VL_WORDS_I(obits); ++i) outwp[i] = vl_rand64();
outwp[VL_WORDS_I(obits) - 1] = vl_rand64() & VL_MASK_E(obits); // Last word is unclean
return outwp; return outwp;
} }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
#endif #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<int>(seed)); Verilated::threadContextp()->randSeed(static_cast<int>(seed));
return VL_RANDOM_I(obits); return VL_RANDOM_I();
} }
IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
if (Verilated::threadContextp()->randReset() == 0) return 0; if (Verilated::threadContextp()->randReset() == 0) return 0;
IData data = ~0; IData data = ~0;
if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize
data = VL_RANDOM_I(obits); data = VL_RANDOM_I();
} }
data &= VL_MASK_I(obits); data &= VL_MASK_I(obits);
return data; return data;
@ -337,7 +337,7 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
if (Verilated::threadContextp()->randReset() == 0) return 0; if (Verilated::threadContextp()->randReset() == 0) return 0;
QData data = ~0ULL; QData data = ~0ULL;
if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize
data = VL_RANDOM_Q(obits); data = VL_RANDOM_Q();
} }
data &= VL_MASK_Q(obits); data &= VL_MASK_Q(obits);
return data; return data;

View File

@ -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 /// 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; 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); } // EMIT_RULE: VL_RANDOM: oclean=dirty
inline QData VL_RANDOM_Q(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_Q(obits); } 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 #ifndef VL_NO_LEGACY
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp);
#endif #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) { inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) {
const vluint64_t rnd = vl_rand64(); const vluint64_t rnd = vl_rand64();
if (VL_LIKELY(hi > lo)) { if (VL_LIKELY(hi > lo)) {

View File

@ -5471,11 +5471,12 @@ public:
: (m_urandom ? "%f$urandom()" : "%f$random()"); : (m_urandom ? "%f$urandom()" : "%f$random()");
} }
virtual string emitC() override { virtual string emitC() override {
return m_reset ? "VL_RAND_RESET_%nq(%nw, %P)" return m_reset ? "VL_RAND_RESET_%nq(%nw, %P)"
: seedp() ? "VL_RANDOM_SEEDED_%nq%lq(%nw, %P, %li)" : seedp() ? "VL_RANDOM_SEEDED_%nq%lq(%li)"
: "VL_RANDOM_%nq(%nw, %P)"; : 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 isGateOptimizable() const override { return false; }
virtual bool isPredictOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; }
virtual int instrCount() const override { return INSTR_COUNT_PLI; } virtual int instrCount() const override { return INSTR_COUNT_PLI; }