Add +verilator+seed, bug1396.

This commit is contained in:
Wilson Snyder 2019-02-04 20:28:17 -05:00
parent 426ed8589b
commit 27fa19eb94
6 changed files with 78 additions and 9 deletions

View File

@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.011 devel
*** Add +verilator+seed, bug1396. [Stan Sokorac]
* Verilator 4.010 2019-01-27

View File

@ -1599,6 +1599,11 @@ When a model was Verilated using "-x-inital unique", sets the
initialization technique. 0 = Reset to zeros. 1 = Reset to all-ones. 2 =
Randomize. See L</"Unknown states">.
=item +verilator+seed+I<value>
For $random and "-x-initial unique", set the random seed value. If zero or
not specified picks a value from the system random number generator.
=item +verilator+V
Shows the verbose version, including configuration information.

View File

@ -208,6 +208,7 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
Verilated::Serialized::Serialized() {
s_randReset = 0;
s_randSeed = 0;
s_debug = 0;
s_calcUnusedSigs = false;
s_gotFinish = false;
@ -245,18 +246,25 @@ vluint64_t vl_rand64() VL_MT_SAFE {
static VL_THREAD_LOCAL bool t_seeded = false;
static VL_THREAD_LOCAL vluint64_t t_state[2];
if (VL_UNLIKELY(!t_seeded)) {
t_seeded = true;
{
VerilatedLockGuard lock(s_mutex);
t_state[0] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
t_state[1] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
t_seeded = true;
{
VerilatedLockGuard lock(s_mutex);
if (Verilated::randSeed() != 0) {
t_state[0] = ((static_cast<vluint64_t>(Verilated::randSeed()) << 32)
^ (static_cast<vluint64_t>(Verilated::randSeed())));
t_state[1] = ((static_cast<vluint64_t>(Verilated::randSeed()) << 32)
^ (static_cast<vluint64_t>(Verilated::randSeed())));
} else {
t_state[0] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
t_state[1] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
}
// Fix state as algorithm is slow to randomize if many zeros
// This causes a loss of ~ 1 bit of seed entropy, no big deal
if (VL_COUNTONES_I(t_state[0]) < 10) t_state[0] = ~t_state[0];
if (VL_COUNTONES_I(t_state[1]) < 10) t_state[1] = ~t_state[1];
}
}
}
// Xoroshiro128+ algorithm
vluint64_t result = t_state[0] + t_state[1];
@ -1670,6 +1678,10 @@ void Verilated::randReset(int val) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
s_s.s_randReset = val;
}
void Verilated::randSeed(int val) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
s_s.s_randSeed = val;
}
void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
s_s.s_calcUnusedSigs = flag;
@ -1879,6 +1891,9 @@ void VerilatedImp::commandArgVl(const std::string& arg) {
else if (commandArgVlValue(arg, "+verilator+rand+reset+", value/*ref*/)) {
Verilated::randReset(atoi(value.c_str()));
}
else if (commandArgVlValue(arg, "+verilator+seed+", value/*ref*/)) {
Verilated::randSeed(atoi(value.c_str()));
}
else if (arg == "+verilator+V") {
versionDump(); // Someday more info too
VL_FATAL_MT("COMMAND_LINE", 0, "", "Exiting due to command line argument (not an error)");

View File

@ -342,7 +342,8 @@ class Verilated {
bool s_assertOn; ///< Assertions are enabled
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
// Slow path
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
int s_randSeed; ///< Random seed: 0=random
Serialized();
~Serialized() {}
} s_s;
@ -396,6 +397,8 @@ public:
/// 2 = Randomize all bits
static void randReset(int val) VL_MT_SAFE;
static int randReset() VL_MT_SAFE { return s_s.s_randReset; } ///< Return randReset value
static void randSeed(int val) VL_MT_SAFE;
static int randSeed() VL_MT_SAFE { return s_s.s_randSeed; } ///< Return randSeed value
/// Enable debug of internal verilated code
static void debug(int level) VL_MT_SAFE;

View File

@ -0,0 +1,27 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(vlt_all => 1);
compile(
);
execute(
all_run_flags => ["+verilator+seed+5 +SEED=fffffff4"],
fails => 0,
);
execute(
all_run_flags => ["+verilator+seed+6 +SEED=fffffff2"],
fails => 0,
);
ok(1);
1;

View File

@ -0,0 +1,17 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t;
initial begin
integer r = $random;
integer ex;
if ($value$plusargs("SEED=%x", ex) !== 1) $stop;
`checkh(r, ex);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule