From a3f913c5b13e027a199ec20ccc6eaf797ffdbe0e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 8 Dec 2025 20:26:53 -0500 Subject: [PATCH] Fix randomize call in parameterized class --- src/V3LinkDot.cpp | 1 + src/V3Width.cpp | 4 +-- test_regress/t/t_randomize_method_param.py | 18 ++++++++++ test_regress/t/t_randomize_method_param.v | 40 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_randomize_method_param.py create mode 100644 test_regress/t/t_randomize_method_param.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 97d0359b6..07914fab5 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -4595,6 +4595,7 @@ class LinkDotResolveVisitor final : public VNVisitor { AstFunc* const randFuncp = V3Randomize::newRandomizeFunc( memberMap, VN_AS(m_modp, Class), nodep->name(), true, true); nodep->taskp(randFuncp); + nodep->classOrPackagep(VN_AS(m_modp, Class)); m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), randFuncp, m_modp); } if (m_insideClassExtParam) { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 91120095c..f6ee174ae 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6727,7 +6727,7 @@ class WidthVisitor final : public VNVisitor { || nodep->name() == "set_randstate"))) { // TODO perhaps this should move to V3LinkDot AstClass* const classp = VN_CAST(nodep->classOrPackagep(), Class); - if (nodep->classOrPackagep()->name() == "std") { + if (nodep->classOrPackagep() && nodep->classOrPackagep()->name() == "std") { v3Global.useRandomizeMethods(true); AstNodeDType* const adtypep = nodep->findBitDType(); withp = methodWithArgument(nodep, false, false, adtypep->findVoidDType(), @@ -6740,7 +6740,7 @@ class WidthVisitor final : public VNVisitor { nodep->didWidth(true); return; } - UASSERT_OBJ(classp, nodep, "Should have failed in V3LinkDot"); + UASSERT_OBJ(classp, nodep, "Classless rand-thing should have failed in V3LinkDot"); if (nodep->name() == "randomize") { AstClassRefDType* const adtypep = new AstClassRefDType{nodep->fileline(), classp, nullptr}; diff --git a/test_regress/t/t_randomize_method_param.py b/test_regress/t/t_randomize_method_param.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_randomize_method_param.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_method_param.v b/test_regress/t/t_randomize_method_param.v new file mode 100644 index 000000000..fd8b3d918 --- /dev/null +++ b/test_regress/t/t_randomize_method_param.v @@ -0,0 +1,40 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +package uvm_pkg; + + virtual class uvm_sequence #( + type REQ = int + ); + endclass + + class uvm_sequence_library #( + type REQ = int + ) extends uvm_sequence #(REQ); + rand bit [15:0] m_rand; + // TODO: randc bit [15:0] m_randc; + task body(); + if (0 == randomize(m_rand)) begin + end + // TODO: if (0 == randomize(m_randc)) begin + // TODO: end + endtask + endclass +endpackage + +module t; + import uvm_pkg::*; + + class t1 extends uvm_sequence_library; + endclass + + initial begin + t1 c; + c = new; + $finish; + end + +endmodule