diff --git a/include/verilated_std.sv b/include/verilated_std.sv index e2862ed7c..13c3f6ad6 100644 --- a/include/verilated_std.sv +++ b/include/verilated_std.sv @@ -140,6 +140,7 @@ package std; } state; // Width visitor changes it to VlProcessRef + // V3Name is hardcoded not to rename this variable protected chandle m_process; static function process self(); @@ -193,7 +194,6 @@ package std; // Two process references are equal if the different classes' containing // m_process are equal. Can't yet use <=> as the base class template // comparisons doesn't define <=> as they don't yet require --timing and C++20. - // V3Name may remove the __PVT__ from this text. // verilog_format: off `ifdef VERILATOR_TIMING `systemc_header_post @@ -201,19 +201,19 @@ template<> template<> inline bool VlClassRef<`systemc_class_name>::operator==(const VlClassRef<`systemc_class_name>& rhs) const { if (!m_objp && !rhs.m_objp) return true; if (!m_objp || !rhs.m_objp) return false; - return m_objp->__PVT__m_process == rhs.m_objp->__PVT__m_process; + return m_objp->m_process == rhs.m_objp->m_process; }; template<> template<> inline bool VlClassRef<`systemc_class_name>::operator!=(const VlClassRef<`systemc_class_name>& rhs) const { if (!m_objp && !rhs.m_objp) return false; if (!m_objp || !rhs.m_objp) return true; - return m_objp->__PVT__m_process != rhs.m_objp->__PVT__m_process; + return m_objp->m_process != rhs.m_objp->m_process; }; template<> template<> inline bool VlClassRef<`systemc_class_name>::operator<(const VlClassRef<`systemc_class_name>& rhs) const { if (!m_objp && !rhs.m_objp) return false; if (!m_objp || !rhs.m_objp) return false; - return m_objp->__PVT__m_process < rhs.m_objp->__PVT__m_process; + return m_objp->m_process < rhs.m_objp->m_process; }; `verilog `endif diff --git a/src/V3Name.cpp b/src/V3Name.cpp index e38c53912..bcc9efe11 100644 --- a/src/V3Name.cpp +++ b/src/V3Name.cpp @@ -90,7 +90,11 @@ class NameVisitor final : public VNVisitorConst { rename(nodep, ((!m_modp || !m_modp->isTop()) && !nodep->isSigPublic() && !nodep->isFuncLocal() // Isn't exposed, and would mess up dpi import wrappers - && !nodep->isTemp())); // Don't bother to rename internal signals + && !nodep->isTemp() // Don't bother to rename internal signals + // Special case, hardcoded m_process references in verilated_std.h and elsewhere + && !(m_modp && m_modp->name() == "std__03a__03aprocess" + && nodep->name() == "m_process"))); + iterateChildrenConst(nodep); } void visit(AstCFunc* nodep) override { if (!nodep->user1()) { @@ -153,17 +157,6 @@ class NameVisitor final : public VNVisitorConst { iterateChildrenConst(nodep); } } - void visit(AstSystemCSection* nodep) override { - // include/verilated_std.sv assumes that V3Name does renaming of std::process; - // if V3Name does not, remove the __PVT__. - if (m_modp && m_modp->name() == "std__03a__03aprocess") { - VMemberMap memberMap; - if (memberMap.findMember(m_modp, "m_process")) { - nodep->text(VString::replaceSubstr(nodep->text(), "__PVT__", "")); - } - } - iterateChildrenConst(nodep); - } //-------------------- void visit(AstNode* nodep) override { iterateChildrenConst(nodep); } diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 0cce64707..b88cddbfe 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -5496,7 +5496,7 @@ AstFunc* V3Randomize::newSRandomFunc(VMemberMap& memberMap, AstClass* nodep) { // For std::process, seed the per-process RNG via m_process->srandom() // For regular classes, seed the per-object RNG via __Vm_rng if (basep->name() == "process") { - funcp->addStmtsp(new AstCStmt{basep->fileline(), "__PVT__m_process->srandom(seed);"}); + funcp->addStmtsp(new AstCStmt{basep->fileline(), "m_process->srandom(seed);"}); } else { funcp->addStmtsp(new AstCStmt{basep->fileline(), "__Vm_rng.srandom(seed);"}); basep->needRNG(true); diff --git a/test_regress/t/t_process_rand_state_public.py b/test_regress/t/t_process_rand_state_public.py new file mode 100755 index 000000000..59bb211b6 --- /dev/null +++ b/test_regress/t/t_process_rand_state_public.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = "t/t_process_rand_state.v" + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile(verilator_flags2=['--timing --public-flat-rw']) + +test.execute() + +test.passes()