8000 POC: VL_RAND_RESET PRNG stability · verilator/verilator@3acdb15 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3acdb15

Browse files
committed
POC: VL_RAND_RESET PRNG stability
1 parent 9ccc02c commit 3acdb15

File tree

8 files changed

+107
-61
lines changed

8 files changed

+107
-61
lines changed

include/verilated.cpp

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -406,37 +406,60 @@ IData VL_URANDOM_SEEDED_II(IData seed) VL_MT_SAFE {
406406
Verilated::threadContextp()->randSeed(static_cast<int>(seed));
407407
return VL_RANDOM_I();
408408
}
409-
IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
409+
static QData VL_RANDOM_RESET_Q_GUTS(std::array<uint64_t, 2>& state) {
410+
state[1] ^= state[0];
411+
state[0] = (((state[0] << 55) | (state[0] >> 9)) ^ state[1] ^ (state[1] << 14));
412+
state[1] = (state[1] << 36) | (state[1] >> 28);
413+
return state[0] + state[1];
414+
}
415+
static QData VL_RANDOM_RESET_Q(uint64_t salt) {
416+
std::array<uint64_t, 2> state;
417+
state[0] = Verilated::threadContextp()->randSeed() ^ salt;
418+
state[1] = state[0];
419+
return VL_RANDOM_RESET_Q_GUTS(state);
420+
}
421+
static IData VL_RANDOM_RESET_I(uint64_t salt) { return VL_RANDOM_RESET_Q(salt); }
422+
IData VL_RAND_RESET_I(int obits, uint64_t salt) VL_MT_SAFE {
410423
if (Verilated::threadContextp()->randReset() == 0) return 0;
411424
IData data = ~0;
412425
if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize
413-
data = VL_RANDOM_I();
426+
data = VL_RANDOM_RESET_I(salt);
414427
}
415428
data &= VL_MASK_I(obits);
416429
return data;
417430
}
418-
IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE { return VL_RANDOM_I() & VL_MASK_I(obits); }
431+
IData VL_RAND_RESET_ASSIGN_I(int obits, uint64_t salt) VL_MT_SAFE {
432+
return VL_RANDOM_RESET_I(salt) & VL_MASK_I(obits);
433+
}
419434

420-
QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
435+
QData VL_RAND_RESET_Q(int obits, uint64_t salt) VL_MT_SAFE {
421436
if (Verilated::threadContextp()->randReset() == 0) return 0;
422437
QData data = ~0ULL;
423438
if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize
424-
data = VL_RANDOM_Q();
439+
data = VL_RANDOM_RESET_Q(salt);
425440
}
426441
data &= VL_MASK_Q(obits);
427442
return data;
428443
}
429444

430-
QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE { return VL_RANDOM_Q() & VL_MASK_Q(obits); }
445+
QData VL_RAND_RESET_ASSIGN_Q(int obits, uint64_t salt) VL_MT_SAFE {
446+
return VL_RANDOM_RESET_Q(salt) & VL_MASK_Q(obits);
447+
}
431448

432-
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
433-
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_I(32);
434-
outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_I(32) & VL_MASK_E(obits);
449+
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp, uint64_t salt) VL_MT_SAFE {
450+
std::array<uint64_t, 2> state;
451+
state[0] = Verilated::threadContextp()->randSeed() ^ salt;
452+
state[1] = state[0];
453+
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RANDOM_RESET_Q_GUTS(state);
454+
outwp[VL_WORDS_I(obits) - 1] = VL_RANDOM_RESET_Q_GUTS(state) & VL_MASK_E(obits);
435455
return outwp;
436456
}
437-
WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE {
438-
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_ASSIGN_I(32);
439-
outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_ASSIGN_I(32) & VL_MASK_E(obits);
457+
WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp, uint64_t salt) VL_MT_SAFE {
458+
std::array<uint64_t, 2> state;
459+
state[0] = Verilated::threadContextp()->randSeed() ^ salt;
460+
state[1] = state[0];
461+
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RANDOM_RESET_Q_GUTS(state);
462+
outwp[VL_WORDS_I(obits) - 1] = VL_RANDOM_RESET_Q_GUTS(state) & VL_MASK_E(obits);
440463
return outwp;
441464
}
442465
WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
@@ -2159,9 +2182,11 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
21592182
// Shift value in
21602183
for (const auto& i : rhs) {
21612184
const char c = std::tolower(i);
2162-
const int value = (c == 'x' || c == 'z') ? VL_RAND_RESET_I(m_hex ? 4 : 1)
2163-
: (c >= 'a') ? (c - 'a' + 10)
2164-
: (c - '0');
2185+
const int value
2186+
= (c == 'x' || c == 'z')
2187+
? VL_RAND_RESET_I(m_hex ? 4 : 1, 0x01234567890abcdefull) // NOCOMMIT
2188+
: (c >= 'a') ? (c - 'a' + 10)
2189+
: (c - '0');
21652190
if (m_bits <= 8) {
21662191
CData* const datap = reinterpret_cast<CData*>(valuep);
21672192
if (!innum) *datap = 0;
F438

include/verilated_funcs.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#ifndef VERILATOR_VERILATED_FUNCS_H_
2525
#define VERILATOR_VERILATED_FUNCS_H_
2626

27+
#include <cstdint>
2728
#ifndef VERILATOR_VERILATED_H_INTERNAL_
2829
#error "verilated_funcs.h should only be included by verilated.h"
2930
#endif
@@ -102,18 +103,18 @@ inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) {
102103
}
103104

104105
/// Random reset a signal of given width (init time only)
105-
extern IData VL_RAND_RESET_I(int obits) VL_MT_SAFE;
106+
extern IData VL_RAND_RESET_I(int obits, uint64_t salt) VL_MT_SAFE;
106107
/// Random reset a signal of given width (init time only)
107-
extern QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE;
108+
extern QData VL_RAND_RESET_Q(int obits, uint64_t salt) VL_MT_SAFE;
108109
/// Random reset a signal of given width (init time only)
109-
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE;
110+
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp, uint64_t salt) VL_MT_SAFE;
110111

111112
/// Random reset a signal of given width (assign time only)
112-
extern IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE;
113+
extern IData VL_RAND_RESET_ASSIGN_I(int obits, uint64_t salt) VL_MT_SAFE;
113114
/// Random reset a signal of given width (assign time only)
114-
extern QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE;
115+
extern QData VL_RAND_RESET_ASSIGN_Q(int obits, uint64_t salt) VL_MT_SAFE;
115116
/// Random reset a signal of given width (assign time only)
116-
extern WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE;
117+
extern WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp, uint64_t salt) VL_MT_SAFE;
117118

118119
/// Zero reset a signal (slow - else use VL_ZERO_W)
119120
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE;

src/V3AstNodeExpr.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,11 +1822,13 @@ class AstRand final : public AstNodeExpr {
18221822
}
18231823
string emitC() override {
18241824
if (m_reset) {
1825+
// NOCOMMIT
1826+
string salt = std::to_string(0x0123456789abcdefull);
18251827
if (v3Global.opt.xAssign() == "unique") {
1826-
return "VL_RAND_RESET_ASSIGN_%nq(%nw, %P)";
1828+
return "VL_RAND_RESET_ASSIGN_%nq(%nw, %P, " + salt + ")";
18271829
} else {
18281830
// This follows xInitial randomization
1829-
return "VL_RAND_RESET_%nq(%nw, %P)";
1831+
return "VL_RAND_RESET_%nq(%nw, %P, " + salt + ")";
18301832
}
18311833
}
18321834
if (seedp()) {

src/V3EmitCFunc.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include <map>
2424
#include <vector>
2525

26+
// NOCOMMIT
27+
VL_DEFINE_DEBUG_FUNCTIONS;
28+
2629
// We use a static char array in VL_VALUE_STRING
2730
constexpr int VL_VALUE_STRING_MAX_WIDTH = 8192;
2831

@@ -669,6 +672,8 @@ void EmitCFunc::emitVarReset(AstVar* varp, bool constructing) {
669672
string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing,
670673
const string& varNameProtected, AstNodeDType* dtypep,
671674
int depth, const string& suffix) {
675+
UINFO(1, "Var Reset -- " << varp->prettyName() << " -- " << varp->origName() << " -- " << varp
676+
<< endl);
672677
dtypep = dtypep->skipRefp();
673678
AstBasicDType* const basicp = dtypep->basicp();
674679
// Returns string to do resetting, empty to do nothing (which caller should handle)
@@ -766,7 +771,16 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing,
766771
} else {
767772
out += zeroit ? (slow ? "VL_ZERO_RESET_W(" : "VL_ZERO_W(") : "VL_RAND_RESET_W(";
768773
out += cvtToStr(dtypep->widthMin());
769-
out += 6377 ", " + varNameProtected + suffix + ");\n";
774+
out += ", " + varNameProtected + suffix;
775+
if (!zeroit) {
776+
V3Hash hash(varp->prettyName());
777+
UINFO(1,
778+
"Var Hash -- " << varp->prettyName() << " -- " << hash.value() << endl);
779+
out += ", ";
780+
// NOCOMMIT -- 64b
781+
out += std::to_string(hash.value());
782+
}
783+
out += ");\n";
770784
}
771785
return out;
772786
} else {
@@ -779,9 +793,13 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing,
779793
if (zeroit || (v3Global.opt.xInitialEdge() && varp->isUsedClock())) {
780794
out += " = 0;\n";
781795
} else {
796+
V3Hash hash(varp->prettyName());
797+
UINFO(1, "Var Hash -- " << varp->prettyName() << " -- " << hash.value() << endl);
782798
out += " = VL_RAND_RESET_";
783799
out += dtypep->charIQWN();
784-
out += "(" + cvtToStr(dtypep->widthMin()) + ");\n";
800+
// NOCOMMIT -- 64b
801+
out += "(" + cvtToStr(dtypep->widthMin()) + ", " + std::to_string(hash.value())
802+
+ ");\n";
785803
}
786804
return out;
787805
}

test_regress/t/t_x_rand_stability.out

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
rand = 0x02fe107d
2-
rand = 0xa97523fb
3-
rand = 0xbe450da7
4-
rand = 0x5d1eb5e3
5-
rand = 0xd5b8d57e
6-
uninitialized = 0xe85acf2d
7-
x_assigned = 0xf0700dbf
8-
uninitialized2 = 0x0f7f28c0
9-
Last rand = 0xf0be314a
1+
rand = 0x952aaa76
2+
rand = 0xe3e54aaa
3+
rand = 0xe85acf2d
4+
rand = 0x15e12c6a
5+
rand = F438 0x0f7f28c0
6+
uninitialized = 0x0077defe
7+
x_assigned = 0xb3c4d5e6
8+
uninitialized2 = 0x0067ee70
9+
Last rand = 0xe189c52a
1010
*-* All Finished *-*
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
rand = 0xbe450da7
2-
rand = 0x5d1eb5e3
3-
rand = 0xd5b8d57e
4-
rand = 0xf0be314a
5-
rand = 0xba24397c
6-
uninitialized = 0x0f7f28c0
7-
x_assigned = 0xa97523fb
8-
uninitialized2 = 0x02fe107d
9-
Last rand = 0xd61b440b
1+
rand = 0x952aaa76
2+
rand = 0xe3e54aaa
3+
rand = 0xe85acf2d
4+
rand = 0x15e12c6a
5+
rand = 0x0f7f28c0
6+
uninitialized = 0x001f1bbe
7+
x_assigned = 0xb3c4d5e6
8+
uninitialized2 = 0x0013d7d3
9+
Last rand = 0xe189c52a
1010
*-* All Finished *-*
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
rand = 0x5d1eb5e3
2-
rand = 0xd5b8d57e
3-
rand = 0xf0be314a
4-
rand = 0xba24397c
5-
rand = 0xd61b440b
6-
uninitialized = 0x0f7f28c0
7-
x_assigned = 0xbe450da7
8-
uninitialized2 = 0xa97523fb
9-
Last rand = 0x911c43eb
1+
rand = 0x952aaa76
2+
rand = 0xe3e54aaa
3+
rand = 0xe85acf2d
4+
rand = 0x15e12c6a
5+
rand = 0x0f7f28c0
6+
uninitialized = 0x001f1bbe
7+
x_assigned = 0xb3c4d5e6
8+
uninitialized2 = 0x0013d7d3
9+
Last rand = 0xe189c52a
1010
*-* All Finished *-*
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
rand = 0xa97523fb
2-
rand = 0xbe450da7
3-
rand = 0x5d1eb5e3
4-
rand = 0xd5b8d57e
5-
rand = 0xf0be314a
6-
uninitialized = 0xe85acf2d
7-
x_assigned = 0x02fe107d
8-
uninitialized2 = 0xe189c52a
9-
Last rand = 0xba24397c
1+
rand = 0x952aaa76
2+
rand = 0xe3e54aaa
3+
rand = 0xe85acf2d
4+
rand = 0x15e12c6a
5+
rand = 0x0f7f28c0
6+
uninitialized = 0x0077defe
7+
x_assigned = 0xb3c4d5e6
8+
uninitialized2 = 0x0067ee70
9+
Last rand = 0xe189c52a
1010
*-* All Finished *-*

0 commit comments

Comments
 (0)
0