From dc34968fe7740441688d3aefea3a6f658a47e701 Mon Sep 17 00:00:00 2001 From: John Wehle <46985578+jlwehle@users.noreply.github.com> Date: Sat, 3 Jun 2023 10:07:39 -0400 Subject: [PATCH] Add class specific same methods for AstVarScope, AstVar, and AstScope (#4203) (#4250) --- docs/CONTRIBUTORS | 1 + src/V3AstNodeOther.h | 3 ++ src/V3AstNodes.cpp | 16 +++++++ test_regress/t/t_cxx_equal_to.pl | 32 ++++++++++++++ test_regress/t/t_cxx_equal_to.v | 74 ++++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+) create mode 100755 test_regress/t/t_cxx_equal_to.pl create mode 100644 test_regress/t/t_cxx_equal_to.v diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index d82c05948..86fa68c5a 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -74,6 +74,7 @@ Jiuyang Liu Joey Liu John Coiner John Demme +John Wehle Jiamin Zhu Jonathan Drolet Jose Loyola diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 497b545cb..4a284b233 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1376,6 +1376,7 @@ public: string name() const override VL_MT_STABLE { return m_name; } // * = Scope name void name(const string& name) override { m_name = name; } void dump(std::ostream& str) const override; + bool same(const AstNode* samep) const override; string nameDotless() const; string nameVlSym() const { return string{"vlSymsp->"} + nameDotless(); } AstNodeModule* modp() const { return m_modp; } @@ -1775,6 +1776,7 @@ public: } ASTGEN_MEMBERS_AstVar; void dump(std::ostream& str) const override; + bool same(const AstNode* samep) const override; string name() const override VL_MT_STABLE VL_MT_SAFE { return m_name; } // * = Var name bool hasDType() const override { return true; } bool maybePointedTo() const override { return true; } @@ -2017,6 +2019,7 @@ public: bool maybePointedTo() const override { return true; } string name() const override VL_MT_STABLE { return scopep()->name() + "->" + varp()->name(); } void dump(std::ostream& str) const override; + bool same(const AstNode* samep) const override; bool hasDType() const override { return true; } AstVar* varp() const VL_MT_STABLE { return m_varp; } // [After Link] Pointer to variable AstScope* scopep() const VL_MT_STABLE { return m_scopep; } // Pointer to scope it's under diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index ab7225d87..2ded5d043 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2066,6 +2066,10 @@ void AstVarScope::dump(std::ostream& str) const { str << " ->UNLINKED"; } } +bool AstVarScope::same(const AstNode* samep) const { + const AstVarScope* const asamep = static_cast(samep); + return varp()->same(asamep->varp()) && scopep()->same(asamep->scopep()); +} void AstNodeVarRef::dump(std::ostream& str) const { this->AstNodeExpr::dump(str); if (classOrPackagep()) str << " pkg=" << nodeAddr(classOrPackagep()); @@ -2129,12 +2133,24 @@ void AstVar::dump(std::ostream& str) const { if (!lifetime().isNone()) str << " [" << lifetime().ascii() << "] "; str << " " << varType(); } +bool AstVar::same(const AstNode* samep) const { + const AstVar* const asamep = static_cast(samep); + return name() == asamep->name() + && varType() == asamep->varType(); +} void AstScope::dump(std::ostream& str) const { this->AstNode::dump(str); str << " [abovep=" << reinterpret_cast(aboveScopep()) << "]"; str << " [cellp=" << reinterpret_cast(aboveCellp()) << "]"; str << " [modp=" << reinterpret_cast(modp()) << "]"; } +bool AstScope::same(const AstNode* samep) const { + const AstScope* const asamep = static_cast(samep); + return name() == asamep->name() + && ((!aboveScopep() && !asamep->aboveScopep()) + || (aboveScopep() && asamep->aboveScopep() + && aboveScopep()->name() == asamep->aboveScopep()->name())); +} void AstScopeName::dump(std::ostream& str) const { this->AstNodeExpr::dump(str); if (dpiExport()) str << " [DPIEX]"; diff --git a/test_regress/t/t_cxx_equal_to.pl b/test_regress/t/t_cxx_equal_to.pl new file mode 100755 index 000000000..5ac57f398 --- /dev/null +++ b/test_regress/t/t_cxx_equal_to.pl @@ -0,0 +1,32 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 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 + +scenarios(simulator => 1); + +if (!$Self->have_coroutines) { + skip("No coroutine support"); +} +else { + top_filename("t/t_cxx_equal_to.v"); + + compile( + verilator_flags2 => ['--binary --timing --trace'], + verilator_make_cmake => 0, + verilator_make_gmake => 0, + make_main => 0, + ); + + execute( + check_finished => 1, + ); +} + +ok(1); +1; diff --git a/test_regress/t/t_cxx_equal_to.v b/test_regress/t/t_cxx_equal_to.v new file mode 100644 index 000000000..e35c8d6d6 --- /dev/null +++ b/test_regress/t/t_cxx_equal_to.v @@ -0,0 +1,74 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// On some platforms (i.e. FreeBSD 12) this triggered: +// +// Active region did not converge. +// +// due to the mistaken belief that the AstVarScope node for TOP->t__DOT__clk +// is equal to the AstVarScope node for TOP->t__DOT__rst. This occured because +// AstVarScope was missing an appropriate same method and is tickled by the LLVM +// libcxx library. +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by John Wehle. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + wire [1:0] out; + reg in; + reg rst; + reg clk; + + initial begin + clk = 0; + rst = 0; + + #10 rst = 1; + #10 rst = 0; + + in = 1'b0; + + #30 $write("*-* All Finished *-*\n"); + $finish; + end + + always begin + #10 clk <= !clk; + end + + Test test(.out(out), .in(in), + .clk(clk), .rst(rst)); +endmodule + + +module Test(/*AUTOARG*/ + // Outputs + out, + // Inputs + clk, in, rst + ); + + input clk; + input in; + input rst; + output wire [1:0] out; + + reg [1:0] s; + reg sin; + + assign out = s; + + always @(posedge clk) + begin + s[1] <= in; + s[0] <= sin; + end + + always @(negedge clk, posedge rst) + if (rst) + sin <= 1'b0; + else + sin <= in; + +endmodule