diff --git a/Changes b/Changes index 7c25b2544..b2e9db90f 100644 --- a/Changes +++ b/Changes @@ -106,6 +106,7 @@ Verilator 5.053 devel * Fix error on non-existent interface ports (#8393). [Andrii Andrieiev, Antmicro Ltd.] * Fix compile-time blowup forcing large unpacked arrays (#8395). [Jonathan Drolet] * Fix false MULTIDRIVEN for writes in tasks never executed (#8401). [Artur Bieniek, Antmicro Ltd.] +* Fix $c() inside a DPI export (#8402). [Nazar Zibilyuk] * Fix covergroup constructor initialization (#8410). [Marco Bartoli] * Fix issues with configuring flex during build on MacOS (#8412). [Kaleb Barrett] * Fix interface modport resolution against non-scope symbol tables (#8420). [Geza Lore, Testorrent USA, Inc.] diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index b0912d3f1..b3b2c140d 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -110,7 +110,10 @@ class DepthVisitor final : public VNVisitor { // (Here instead of new visitor after V3Descope just to avoid another visitor) void needNonStaticFunc(AstNode* nodep) { UASSERT_OBJ(m_cfuncp, nodep, "Non-static accessor not under a function"); - if (m_cfuncp->isStatic()) { + // DPI export implementations are always invoked via the generic DPI dispatcher, + // which can only ever supply the symbol table pointer, never a scope-specific + // "this", so they must remain static regardless of what they contain. + if (m_cfuncp->isStatic() && !m_cfuncp->dpiExportImpl()) { UINFO(5, "Mark non-public due to " << nodep); m_cfuncp->isStatic(false); } diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index c94c7b81b..741338aa8 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -31,8 +31,6 @@ class EmitCModel final : public EmitCFunc { using CFuncVector = std::vector; // MEMBERS - // Needed to emit references to functions of the model, e.g. entry points - const EmitCParentModule m_emitCParentModule; V3UniqueNames m_uniqueNames; // For generating unique file names // METHODS diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 4e572069e..4f821dc91 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -48,6 +48,7 @@ #include "V3DfgOptimizer.h" #include "V3DiagSarif.h" #include "V3EmitC.h" +#include "V3EmitCBase.h" #include "V3EmitCMain.h" #include "V3EmitMk.h" #include "V3EmitMkJson.h" @@ -628,6 +629,8 @@ static void process() { // Output the text if (!v3Global.opt.lintOnly() && !v3Global.opt.serializeOnly() && !v3Global.opt.dpiHdrOnly()) { + // Make parent module pointers available for all Emit stages below + const EmitCParentModule emitCParentModule; // emitcInlines is first, as it may set needHInlines which other emitters read V3EmitC::emitcInlines(); V3EmitC::emitcSyms(); diff --git a/test_regress/t/t_dpi_export.v b/test_regress/t/t_dpi_export.v index 7c92126e4..49db76f27 100644 --- a/test_regress/t/t_dpi_export.v +++ b/test_regress/t/t_dpi_export.v @@ -23,7 +23,12 @@ module t; import "DPI-C" context function int dpix_run_tests(); export "DPI-C" task dpix_t_int; - task dpix_t_int(input int i, output int o); o = ~i; endtask + task dpix_t_int(input int i, output int o); +`ifdef VERILATOR + $c(";"); // Test issue #8402 +`endif + o = ~i; + endtask export "DPI-C" dpix_t_renamed = task dpix_t_ren; task dpix_t_ren(input int i, output int o); o = i+2; endtask