Issue #1396
Verilator random number generated seeded with lrand48(), which isn't deterministic across platforms
0%
Description
Verilator uses a deterministic random number generator, but does the initial seeding using lrand48(), which will produce a different random seed on different platforms, even when seeded the same. This means that simulations that originally ran on, say, Linux, can't be reproduced accurately on OSX, or even different versions of Linux.
C++ offers mt19937_64 random number generator which is guaranteed to produce the same sequence on numbers on every system, given the same seed. For example, running this code below on different OSes will give you different numbers for lrand48, but always the same for mt19937.
#include <cstdlib>
#include <random>
int main(int argc, char *argv[])
{
srand(1);
for (int i=0; i < 3; i++)
printf("lrand48[%d]=%ld\n", i, lrand48());
std::mt19937_64 mt(1);
for (int i=0; i < 3; i++)
printf("mt19937[%d]=%llu\n", i, mt());
}
It would be helpful if Verilator used it to provide better reproducibility across systems. We've worked around this by using our own DPI random() function instead of $random, however there's no way around this for other randomness, like -x-assign/-x-initial.
Alternatively, some way to provide our own random seed/function to override the built-in ones would also do the trick.
History
#1 Updated by Wilson Snyder 18 days ago
- Category set to Usage
- Status changed from New to Resolved
- Assignee set to Wilson Snyder
mt19937 is a good idea, but Verilator does not yet require C++11.
I added the +verilator+seed runtime option, pass the same number to every run and you should be all set, or have your main() call Verilator::randSeed(#). The default is old behavior, perhaps it should instead be a constant.
Fixed in git towards 4.012.
#2 Updated by Armond Paiva 14 days ago
Minor correction on setting the seed. It can be set programmatically with 'Verilated::randSeed(#)', not 'Verilator::randSeed(#)'
Also available in: Atom