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
// 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<int>(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;

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
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)) {

View File

@ -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; }