Fix $random not updating seed (#3238). [Julie Schwartz]

This commit is contained in:
Wilson Snyder 2022-01-01 16:43:06 -05:00
parent 65de118e51
commit d679d50eca
6 changed files with 48 additions and 9 deletions

View File

@ -30,6 +30,7 @@ Verilator 4.217 devel
* Fix VL_STREAML_FAST_QQI with 64 bit left-hand-side (#3232) (#3235)
* Fix $sformat of inputs/outputs (#3236). [Adrien Le Masle]
* Fix associative array foreach loop (#3229).
* Fix $random not updating seed (#3238). [Julie Schwartz]
* Fix splitting of _eval and other top level functions. [Geza Lore, Shunyao CAD]

View File

@ -337,11 +337,17 @@ WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE {
return outwp;
}
IData VL_RANDOM_SEEDED_II(IData seed) VL_MT_SAFE {
IData VL_RANDOM_SEEDED_II(IData& seedr) VL_MT_SAFE {
// $random - seed is a new seed to apply, then we return new seed
Verilated::threadContextp()->randSeed(static_cast<int>(seedr));
seedr = VL_RANDOM_I();
return VL_RANDOM_I();
}
IData VL_URANDOM_SEEDED_II(IData seed) VL_MT_SAFE {
// $urandom - seed is a new seed to apply
Verilated::threadContextp()->randSeed(static_cast<int>(seed));
return VL_RANDOM_I();
}
IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
if (Verilated::threadContextp()->randReset() == 0) return 0;
IData data = ~0;

View File

@ -85,7 +85,8 @@ extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
inline IData VL_RANDOM_I() VL_MT_SAFE { return vl_rand64(); }
inline QData VL_RANDOM_Q() VL_MT_SAFE { return vl_rand64(); }
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp);
extern IData VL_RANDOM_SEEDED_II(IData seed) VL_MT_SAFE;
extern IData VL_RANDOM_SEEDED_II(IData& seedr) VL_MT_SAFE;
extern IData VL_URANDOM_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

@ -5577,10 +5577,11 @@ 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(%li)"
: isWide() ? "VL_RANDOM_%nq(%nw, %P)" //
: "VL_RANDOM_%nq()";
return m_reset ? "VL_RAND_RESET_%nq(%nw, %P)"
: seedp() ? (urandom() ? "VL_URANDOM_SEEDED_%nq%lq(%li)"
: "VL_RANDOM_SEEDED_%nq%lq(%li)")
: isWide() ? "VL_RANDOM_%nq(%nw, %P)" //
: "VL_RANDOM_%nq()";
}
virtual bool cleanOut() const override { return false; }
virtual bool isGateOptimizable() const override { return false; }

View File

@ -183,6 +183,13 @@ private:
VL_RESTORER(m_setRefLvalue);
iterateChildren(nodep);
}
virtual void visit(AstRand* nodep) override {
VL_RESTORER(m_setRefLvalue);
{
if (!nodep->urandom()) m_setRefLvalue = VAccess::WRITE;
iterateAndNextNull(nodep->seedp());
}
}
virtual void visit(AstReadMem* nodep) override {
VL_RESTORER(m_setRefLvalue);
{

View File

@ -6,16 +6,39 @@
module t;
integer seeda;
integer seedb;
integer seedc;
int valuea;
int valueb;
int valuec;
initial begin
valuea = $random(10);
valueb = $random(10);
// $random unlike $urandom updates the value if given
seeda = 10;
valuea = $random(seeda);
seedb = 10;
valueb = $random(seedb);
if (valuea !== valueb) $stop;
seeda = 10;
valuea = $random(seeda);
seedb = seeda;
valueb = $random(seedb);
seedc = seedb;
valuec = $random(seedc);
if (valuea == valueb && valueb == valuec) $stop; // May false fail 1 in 1^64
if (seeda == seedb && seedb == seedc) $stop; // May false fail 1 in 1^64
valuea = $urandom(10);
valueb = $urandom(10);
if (valuea !== valueb) $stop;
valuea = $urandom(10);
valueb = $urandom();
valuec = $urandom();
if (valuea == valueb && valueb == valuec) $stop; // May false fail 1 in 1^64
$write("*-* All Finished *-*\n");
$finish;
end