Fix eliminating assignments to DPI-read vaiables (#7158)
This commit is contained in:
parent
face700f29
commit
2ceea267e5
|
|
@ -1933,6 +1933,7 @@ class AstVar final : public AstNode {
|
|||
bool m_isLatched : 1; // Not assigned in all control paths of combo always
|
||||
bool m_isForceable : 1; // May be forced/released externally from user C code
|
||||
bool m_isForcedByCode : 1; // May be forced/released from AstAssignForce/AstRelease
|
||||
bool m_isReadByDpi : 1; // This variable can be read by a DPI Export
|
||||
bool m_isWrittenByDpi : 1; // This variable can be written by a DPI Export
|
||||
bool m_isWrittenBySuspendable : 1; // This variable can be written by a suspendable process
|
||||
bool m_ignorePostRead : 1; // Ignore reads in 'Post' blocks during ordering
|
||||
|
|
@ -1987,6 +1988,7 @@ class AstVar final : public AstNode {
|
|||
m_isLatched = false;
|
||||
m_isForceable = false;
|
||||
m_isForcedByCode = false;
|
||||
m_isReadByDpi = false;
|
||||
m_isWrittenByDpi = false;
|
||||
m_isWrittenBySuspendable = false;
|
||||
m_ignorePostRead = false;
|
||||
|
|
@ -2152,6 +2154,8 @@ public:
|
|||
void setForceable() { m_isForceable = true; }
|
||||
void setForcedByCode() { m_isForcedByCode = true; }
|
||||
bool isForced() const { return m_isForceable || m_isForcedByCode; }
|
||||
bool isReadByDpi() const { return m_isReadByDpi; }
|
||||
void setReadByDpi() { m_isReadByDpi = true; }
|
||||
bool isWrittenByDpi() const { return m_isWrittenByDpi; }
|
||||
void setWrittenByDpi() { m_isWrittenByDpi = true; }
|
||||
bool isWrittenBySuspendable() const { return m_isWrittenBySuspendable; }
|
||||
|
|
|
|||
|
|
@ -2880,6 +2880,8 @@ void AstVar::dump(std::ostream& str) const {
|
|||
if (isSigPublic()) str << " [P]";
|
||||
if (isSigUserRdPublic()) str << " [PRD]";
|
||||
if (isSigUserRWPublic()) str << " [PWR]";
|
||||
if (isReadByDpi()) str << " [DPIRD]";
|
||||
if (isWrittenByDpi()) str << " [DPIWR]";
|
||||
if (isInternal()) str << " [INTERNAL]";
|
||||
if (isLatched()) str << " [LATCHED]";
|
||||
if (isUsedLoopIdx()) str << " [LOOPIDX]";
|
||||
|
|
@ -2927,6 +2929,8 @@ void AstVar::dumpJson(std::ostream& str) const {
|
|||
if (dtypep()) dumpJsonStr(str, "dtypeName", dtypep()->name());
|
||||
dumpJsonBoolFuncIf(str, isSigUserRdPublic);
|
||||
dumpJsonBoolFuncIf(str, isSigUserRWPublic);
|
||||
dumpJsonBoolFuncIf(str, isReadByDpi);
|
||||
dumpJsonBoolFuncIf(str, isWrittenByDpi);
|
||||
dumpJsonBoolFuncIf(str, isGParam);
|
||||
dumpJsonBoolFuncIf(str, isParam);
|
||||
dumpJsonBoolFuncIf(str, attrScBv);
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ public:
|
|||
const AstVar* const varp = vscp->varp();
|
||||
// We don't optimize any public sigs
|
||||
if (varp->isSigPublic()) return;
|
||||
if (varp->isReadByDpi()) return;
|
||||
if (varp->sensIfacep()) return;
|
||||
// Check the var entry, and remove if appropriate
|
||||
AstNodeStmt* const oldassp = entr.assignp();
|
||||
|
|
|
|||
|
|
@ -1428,15 +1428,22 @@ class TaskVisitor final : public VNVisitor {
|
|||
// Mark non-local variables written by the exported function
|
||||
bool writesNonLocals = false;
|
||||
cfuncp->foreach([&writesNonLocals](AstVarRef* refp) {
|
||||
if (refp->access().isReadOnly()) return; // Ignore read reference
|
||||
AstVar* const varp = refp->varScopep()->varp();
|
||||
// We are ignoring function locals as they should not be referenced anywhere
|
||||
// outside the enclosing AstCFunc, hence they are irrelevant for code ordering.
|
||||
if (varp->isFuncLocal()) return;
|
||||
// Mark it as written by DPI export
|
||||
varp->setWrittenByDpi();
|
||||
// Remember we had some
|
||||
writesNonLocals = true;
|
||||
// Check if written
|
||||
if (refp->access().isWriteOrRW()) {
|
||||
// Mark it as written by DPI export
|
||||
varp->setWrittenByDpi();
|
||||
// Remember we had some
|
||||
writesNonLocals = true;
|
||||
}
|
||||
// Check if read
|
||||
if (refp->access().isReadOrRW()) {
|
||||
// Mark it as read by DPI export
|
||||
varp->setReadByDpi();
|
||||
}
|
||||
});
|
||||
|
||||
// If this DPI export writes some non-local variables, set the DPI Export Trigger flag
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// 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-2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "svdpi.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern "C" int getDpi();
|
||||
|
||||
extern "C" int getViaDpi() {
|
||||
const int value = getDpi();
|
||||
std::cout << "getDpi " << value << std::endl;
|
||||
return value;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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('vlt_all')
|
||||
|
||||
test.compile(verilator_flags2=["--binary", "--stats", test.top_filename.replace(".v", ".cpp")])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define check(got,exp) do if ((got) !== (exp)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (got), (exp)); `stop; end while(0)
|
||||
// verilog_format: on
|
||||
|
||||
module t;
|
||||
|
||||
int dpiGet = 0;
|
||||
function automatic int getDpi();
|
||||
return dpiGet;
|
||||
endfunction
|
||||
export "DPI-C" function getDpi;
|
||||
import "DPI-C" context function int getViaDpi(); // calls getDpi()
|
||||
|
||||
int tmp1, tmp2, tmp3;
|
||||
|
||||
initial begin
|
||||
dpiGet = 13;
|
||||
tmp1 = getViaDpi();
|
||||
dpiGet = 14;
|
||||
tmp2 = getViaDpi();
|
||||
dpiGet = 15;
|
||||
tmp3 = getViaDpi();
|
||||
`check(tmp1, 13);
|
||||
`check(tmp2, 14);
|
||||
`check(tmp3, 15);
|
||||
end
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue