From 9731ec76e3d1c77cdb782bf9e55936723795c3f2 Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Mon, 11 Oct 2021 20:45:19 +0800 Subject: [PATCH] Fix $urandom_range when the range is 0 ... UINT_MAX (#3161) --- include/verilated_funcs.h | 3 +++ test_regress/t/t_urandom.v | 3 +++ 2 files changed, 6 insertions(+) diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 0c11c6551..cddc44842 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -82,9 +82,12 @@ extern IData VL_RANDOM_SEEDED_II(int obits, IData seed) VL_MT_SAFE; inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) { vluint64_t rnd = vl_rand64(); if (VL_LIKELY(hi > lo)) { + // (hi - lo + 1) can be zero when hi is UINT_MAX and lo is zero + if (VL_UNLIKELY(hi - lo + 1 == 0)) return rnd; // Modulus isn't very fast but it's common that hi-low is power-of-two return (rnd % (hi - lo + 1)) + lo; } else { + if (VL_UNLIKELY(lo - hi + 1 == 0)) return rnd; return (rnd % (lo - hi + 1)) + hi; } } diff --git a/test_regress/t/t_urandom.v b/test_regress/t/t_urandom.v index fcb6b7b9d..bd865b990 100644 --- a/test_regress/t/t_urandom.v +++ b/test_regress/t/t_urandom.v @@ -37,6 +37,9 @@ module t(/*AUTOARG*/); v2 = $urandom_range(v1, v1); if (v1 != v2) $stop; + v2 = $urandom_range(0, 32'hffffffff); + if (v2 == v1) $stop; + for (int test = 0; test < 20; ++test) begin v1 = 2; v1 = $urandom_range(0, v1);