diff --git a/include/verilated.cpp b/include/verilated.cpp index 928e21524..a1e6975a0 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -438,6 +438,30 @@ WDataOutP VL_SCOPED_RAND_RESET_W(int obits, WDataOutP outwp, uint64_t scopeHash, return outwp; } +IData VL_SCOPED_RAND_RESET_ASSIGN_I(int obits, uint64_t scopeHash, uint64_t salt) VL_MT_UNSAFE { + IData data = ~0; + VlRNG rng(Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt); + data = rng.rand64(); + data &= VL_MASK_I(obits); + return data; +} + +QData VL_SCOPED_RAND_RESET_ASSIGN_Q(int obits, uint64_t scopeHash, uint64_t salt) VL_MT_UNSAFE { + QData data = ~0ULL; + VlRNG rng(Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt); + data = rng.rand64(); + data &= VL_MASK_Q(obits); + return data; +} + +WDataOutP VL_SCOPED_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp, uint64_t scopeHash, + uint64_t salt) VL_MT_UNSAFE { + VlRNG rng(Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt); + for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = rng.rand64(); + outwp[VL_WORDS_I(obits) - 1] = rng.rand64() & VL_MASK_E(obits); + return outwp; +} + IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { if (Verilated::threadContextp()->randReset() == 0) return 0; IData data = ~0; @@ -447,7 +471,6 @@ IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { data &= VL_MASK_I(obits); return data; } -IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE { return VL_RANDOM_I() & VL_MASK_I(obits); } QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE { if (Verilated::threadContextp()->randReset() == 0) return 0; @@ -459,18 +482,11 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE { return data; } -QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE { return VL_RANDOM_Q() & VL_MASK_Q(obits); } - WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE { for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_I(32); outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_I(32) & VL_MASK_E(obits); return outwp; } -WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE { - for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_ASSIGN_I(32); - outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_ASSIGN_I(32) & VL_MASK_E(obits); - return outwp; -} WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE { // Not inlined to speed up compilation of slowpath code return VL_ZERO_W(obits, outwp); diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index ca3ca8fe0..412549b7a 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -109,6 +109,16 @@ extern QData VL_SCOPED_RAND_RESET_Q(int obits, uint64_t scopeHash, uint64_t salt extern WDataOutP VL_SCOPED_RAND_RESET_W(int obits, WDataOutP outwp, uint64_t scopeHash, uint64_t salt) VL_MT_UNSAFE; +/// Random reset a signal of given width (assign time only) +extern IData VL_SCOPED_RAND_RESET_ASSIGN_I(int obits, uint64_t scopeHash, + uint64_t salt) VL_MT_UNSAFE; +/// Random reset a signal of given width (assign time only) +extern QData VL_SCOPED_RAND_RESET_ASSIGN_Q(int obits, uint64_t scopeHash, + uint64_t salt) VL_MT_UNSAFE; +/// Random reset a signal of given width (assign time only) +extern WDataOutP VL_SCOPED_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp, uint64_t scopeHash, + uint64_t salt) VL_MT_UNSAFE; + /// Random reset a signal of given width (init time only) extern IData VL_RAND_RESET_I(int obits) VL_MT_SAFE; /// Random reset a signal of given width (init time only) @@ -116,13 +126,6 @@ extern QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE; /// Random reset a signal of given width (init time only) extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE; -/// Random reset a signal of given width (assign time only) -extern IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE; -/// Random reset a signal of given width (assign time only) -extern QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE; -/// Random reset a signal of given width (assign time only) -extern WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE; - /// Zero reset a signal (slow - else use VL_ZERO_W) extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE; diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index f9587b4b4..ebec542ab 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -769,7 +769,8 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing, } } else { out += zeroit ? (slow ? "VL_ZERO_RESET_W(" : "VL_ZERO_W(") - : "VL_SCOPED_RAND_RESET_W("; + : (varp->isXTemp() ? "VL_SCOPED_RAND_RESET_ASSIGN_W(" + : "VL_SCOPED_RAND_RESET_W("); out += cvtToStr(dtypep->widthMin()); out += ", " + varNameProtected + suffix; if (!zeroit) { @@ -797,6 +798,7 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing, emitVarResetScopeHash(); const uint64_t salt = VString::hashMurmur(varp->prettyName()); out += " = VL_SCOPED_RAND_RESET_"; + if (varp->isXTemp()) out += "ASSIGN_"; out += dtypep->charIQWN(); out += "(" + cvtToStr(dtypep->widthMin()) + ", " + (m_classOrPackage ? m_classOrPackageHash : "__VscopeHash") + ", " diff --git a/test_regress/t/t_x_assign.cpp b/test_regress/t/t_x_assign.cpp index 36aa6371f..eec3f5816 100644 --- a/test_regress/t/t_x_assign.cpp +++ b/test_regress/t/t_x_assign.cpp @@ -29,8 +29,6 @@ int main(int argc, const char** argv) { Verilated::randReset(0); #elif defined(T_X_ASSIGN_UNIQUE_1) Verilated::randReset(1); -#elif defined(T_X_ASSIGN_UNIQUE_2) - Verilated::randReset(2); #endif VM_PREFIX* top = new VM_PREFIX{}; @@ -41,17 +39,7 @@ int main(int argc, const char** argv) { top->clk = 1; top->eval(); -#if defined(T_X_ASSIGN_UNIQUE_0) - if (top->o_int != 0) { - vl_fatal(__FILE__, __LINE__, "TOP.t", "x assign was not correct"); - exit(1); - } -#elif defined(T_X_ASSIGN_UNIQUE_1) - if (top->o_int != -1) { - vl_fatal(__FILE__, __LINE__, "TOP.t", "x assign was not correct"); - exit(1); - } -#elif defined(T_X_ASSIGN_UNIQUE_2) +#if defined(T_X_ASSIGN_UNIQUE_0) || defined(T_X_ASSIGN_UNIQUE_1) if (top->o_int == 0 || top->o_int == -1) { vl_fatal(__FILE__, __LINE__, "TOP.t", "x assign was not unique"); exit(1); @@ -61,6 +49,13 @@ int main(int argc, const char** argv) { vl_fatal(__FILE__, __LINE__, "TOP.t", "incorrect module output"); exit(1); } + + uint32_t o_int_expected = EXPECTED ? 0xffffffff : 0; + + if (top->o_int != o_int_expected) { + vl_fatal(__FILE__, __LINE__, "TOP.t", "incorrect module output"); + exit(1); + } #endif VL_DO_DANGLING(delete top, top); diff --git a/test_regress/t/t_x_assign_unique_2.py b/test_regress/t/t_x_assign_unique_2.py deleted file mode 100755 index f5cc5d72a..000000000 --- a/test_regress/t/t_x_assign_unique_2.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python3 -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2024 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. -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -import vltest_bootstrap - -test.scenarios("vlt_all") -test.pli_filename = "t/t_x_assign.cpp" -test.top_filename = "t/t_x_assign.v" - -test.compile( - make_top_shell=False, - make_main=False, - verilator_flags2=["--x-assign unique --exe", "--x-initial 0", test.pli_filename], -) - -test.execute() - -test.passes() diff --git a/test_regress/t/t_x_rand_mt_stability_zeros.out b/test_regress/t/t_x_rand_mt_stability_zeros.out index 1426e7828..573a7650c 100644 --- a/test_regress/t/t_x_rand_mt_stability_zeros.out +++ b/test_regress/t/t_x_rand_mt_stability_zeros.out @@ -12,6 +12,6 @@ rand = 0xf0acf3e4 rand = 0xca0ac74c rand = 0x4eddfc2c rand = 0x1919db69 -x_assigned = 0x00000000 +x_assigned = 0x486aeb2d Last rand = 0x2d118c9b *-* All Finished *-* diff --git a/test_regress/t/t_x_rand_stability_zeros.out b/test_regress/t/t_x_rand_stability_zeros.out index d54e3ecd4..fe1f4ba0a 100644 --- a/test_regress/t/t_x_rand_stability_zeros.out +++ b/test_regress/t/t_x_rand_stability_zeros.out @@ -12,6 +12,6 @@ rand = 0xe85acf2d rand = 0x15e12c6a rand = 0x0f7f28c0 rand = 0xe189c52a -x_assigned = 0x00000000 +x_assigned = 0x486aeb2d Last rand = 0xf0700dbf *-* All Finished *-*