forked from github/verilator
Fix $random not updating seed (#3238). [Julie Schwartz]
This commit is contained in:
parent
65de118e51
commit
d679d50eca
1
Changes
1
Changes
@ -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]
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user