From 4b02e32314e29ca00216f2d9e2ea04bde69ff5ea Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 7 Dec 2025 13:30:54 -0500 Subject: [PATCH] Fix DPI under param class (#6733 partial) --- src/V3LinkResolve.cpp | 4 --- src/V3Task.cpp | 3 +- src/V3Width.cpp | 4 +++ test_regress/t/t_dpi_class_param.cpp | 15 +++++++++ test_regress/t/t_dpi_class_param.py | 18 +++++++++++ test_regress/t/t_dpi_class_param.v | 46 ++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 test_regress/t/t_dpi_class_param.cpp create mode 100755 test_regress/t/t_dpi_class_param.py create mode 100644 test_regress/t/t_dpi_class_param.v diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index ad6d72d3e..0988eba8f 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -249,10 +249,6 @@ class LinkResolveVisitor final : public VNVisitor { letp->user2(false); return; } - if (nodep->taskp() && !nodep->scopeNamep() - && (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) { - nodep->scopeNamep(new AstScopeName{nodep->fileline(), false}); - } } void visit(AstCaseItem* nodep) override { diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 0c53467f4..58fc1baf2 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -711,8 +711,9 @@ class TaskVisitor final : public VNVisitor { if (needSyms) ccallp->argTypes("vlSymsp"); if (refp->taskp()->dpiContext()) { - AstScopeName* const snp = refp->scopeNamep()->unlinkFrBack(); + AstScopeName* const snp = refp->scopeNamep(); UASSERT_OBJ(snp, refp, "Missing scoping context"); + snp->unlinkFrBack(); FileLine* const flp = refp->fileline(); // __Vscopep ccallp->addArgsp(snp); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index b18c13f56..c6c3416c7 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6792,6 +6792,10 @@ class WidthVisitor final : public VNVisitor { nodep->v3error("Cannot call non-static member function " << nodep->prettyNameQ() << " without object (IEEE 1800-2023 8.10)"); } + if (nodep->taskp() && !nodep->scopeNamep() + && (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) { + nodep->scopeNamep(new AstScopeName{nodep->fileline(), false}); + } // And do the arguments to the task/function too processFTaskRefArgs(nodep); nodep->addPinsp(withp); diff --git a/test_regress/t/t_dpi_class_param.cpp b/test_regress/t/t_dpi_class_param.cpp new file mode 100644 index 000000000..f49b38d93 --- /dev/null +++ b/test_regress/t/t_dpi_class_param.cpp @@ -0,0 +1,15 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2024 by Antmicro. 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 +// +//************************************************************************* + +extern "C" int dpii_add() { + static int s_i; + return ++s_i; +} diff --git a/test_regress/t/t_dpi_class_param.py b/test_regress/t/t_dpi_class_param.py new file mode 100755 index 000000000..aae0ff397 --- /dev/null +++ b/test_regress/t/t_dpi_class_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(verilator_flags2=['--binary', test.pli_filename]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_dpi_class_param.v b/test_regress/t/t_dpi_class_param.v new file mode 100644 index 000000000..ab02fb58d --- /dev/null +++ b/test_regress/t/t_dpi_class_param.v @@ -0,0 +1,46 @@ +// 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 + +// verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0); +// verilog_format: on + +module t; + import "DPI-C" context function int dpii_add(); + + virtual class uvm_sequence #( + type RSP = int + ); + endclass + + class Cls extends uvm_sequence #(); + virtual function void check_reg(); + int paths[$]; + int i; + paths.push_back(1); + paths.push_back(2); + foreach (paths[p]) begin + i = dpii_add(); + end + endfunction + endclass + + initial begin + Cls c; + int i; + c = new; + i = dpii_add(); + `checkd(i, 1); + + c.check_reg(); + + i = dpii_add(); + `checkd(i, 4); + $finish; + end + +endmodule