diff --git a/Changes b/Changes index 622946f16..5a124ea3c 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix package import of non-localparam parameter, bug591. [Jeremy Bennett] +**** Fix package import of package imports, partial bug592. [Jeremy Bennett] + * Verilator 3.843 2012/12/01 diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index eeb5ee3a0..f8ea0e95e 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -114,6 +114,7 @@ public: ~LinkDotState() {} // ACCESSORS + VSymGraph* symsp() { return &m_syms; } bool forPrimary() const { return m_forPrimary; } bool forPrearray() const { return m_forPrearray; } bool forScopeCreation() const { return m_forScopeCreation; } @@ -700,7 +701,7 @@ private: if (m_statep->forPrimary() && nodep->isGParam()) { m_paramNum++; VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber"+cvtToStr(m_paramNum), nodep, m_packagep); - symp->importable(false); + symp->exported(false); } } } @@ -753,7 +754,7 @@ private: nodep->v3error("Import object not found: "<packagep()->prettyName()<<"::"<prettyName()); } } - m_curSymp->import(srcp, nodep->name()); + m_curSymp->import(m_statep->symsp(), srcp, nodep->name()); UINFO(2," Link Done: "<user4(true); VSymEnt* symp = m_statep->insertSym(m_statep->getNodeSym(m_modp), "__pinNumber"+cvtToStr(nodep->pinNum()), refp, NULL/*packagep*/); - symp->importable(false); + symp->exported(false); } // Ports not needed any more nodep->unlinkFrBack()->deleteTree(); nodep=NULL; diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h index 7a30f8eeb..f30e1c340 100644 --- a/src/V3ParseSym.h +++ b/src/V3ParseSym.h @@ -128,7 +128,7 @@ public: } // Walk old sym table and reinsert into current table // We let V3LinkDot report the error instead of us - symCurrentp()->import(symp, id_or_star); + symCurrentp()->import(&m_syms, symp, id_or_star); } public: // CREATORS diff --git a/src/V3SymTable.h b/src/V3SymTable.h index de3790b74..9dc46f172 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -53,7 +53,8 @@ private: VSymEnt* m_parentp; // Table that created this table, dot notation needed to resolve into it AstPackage* m_packagep; // Package node is in (for V3LinkDot, unused here) string m_symPrefix; // String to prefix symbols with (for V3LinkDot, unused here) - bool m_importable; // Allow importing + bool m_exported; // Allow importing + bool m_imported; // Was imported #ifdef VL_DEBUG static int debug() { static int level = -1; @@ -87,6 +88,7 @@ public: } // METHODS + VSymEnt(VSymGraph* graphp, const VSymEnt* symp); // Below VSymEnt(VSymGraph* graphp, AstNode* nodep); // Below ~VSymEnt() { // Change links so we coredump if used @@ -108,8 +110,10 @@ public: AstNode* nodep() const { if (!this) return NULL; else return m_nodep; } // null check so can call .findId(...)->nodep() string symPrefix() const { return m_symPrefix; } void symPrefix(const string& name) { m_symPrefix = name; } - bool importable() const { return m_importable; } - void importable(bool flag) { m_importable = flag; } + bool exported() const { return m_exported; } + void exported(bool flag) { m_exported = flag; } + bool imported() const { return m_imported; } + void imported(bool flag) { m_imported = flag; } void insert(const string& name, VSymEnt* entp) { UINFO(9, " SymInsert se"<<(void*)this<<" '"<nodep()<findIdFallback(name); return NULL; } - bool import(const VSymEnt* srcp, const string& id_or_star) { + bool import(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) { // Import tokens from source symbol table into this symbol table // Returns true if successful bool any = false; if (id_or_star != "*") { IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star); if (it != m_idNameMap.end()) { - if (it->second->importable()) { - reinsert(it->first, it->second); + if (it->second->exported()) { + VSymEnt* symp = new VSymEnt(graphp, it->second); + symp->exported(false); // Can't reimport an import without an export + reinsert(it->first, symp); } } any = true; // Legal, though perhaps lint questionable to import nothing } else { for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) { - if (it->second->importable()) { - reinsert(it->first, it->second); + if (it->second->exported()) { + VSymEnt* symp = new VSymEnt(graphp, it->second); + symp->exported(false); // Can't reimport an import without an export + reinsert(it->first, symp); any = true; } } @@ -243,7 +251,7 @@ public: //###################################################################### -inline VSymEnt::VSymEnt(VSymGraph* m_graphp, AstNode* nodep) +inline VSymEnt::VSymEnt(VSymGraph* graphp, AstNode* nodep) : m_nodep(nodep) { // No argument to set fallbackp, as generally it's wrong to set it in the new call, // Instead it needs to be set on a "findOrNew()" return, as it may have been new'ed @@ -251,8 +259,19 @@ inline VSymEnt::VSymEnt(VSymGraph* m_graphp, AstNode* nodep) m_fallbackp = NULL; m_parentp = NULL; m_packagep = NULL; - m_importable = true; - m_graphp->pushNewEnt(this); + m_exported = true; + m_imported = false; + graphp->pushNewEnt(this); +} + +inline VSymEnt::VSymEnt(VSymGraph* graphp, const VSymEnt* symp) + : m_nodep(symp->nodep()) { + m_fallbackp = symp->m_fallbackp; + m_parentp = symp->m_parentp; + m_packagep = symp->m_packagep; + m_exported = symp->m_exported; + m_imported = symp->m_imported; + graphp->pushNewEnt(this); } #endif // guard diff --git a/test_regress/t/t_package_export.pl b/test_regress/t/t_package_export.pl new file mode 100755 index 000000000..9cd16f86a --- /dev/null +++ b/test_regress/t/t_package_export.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug592"); +$Self->{vcs} and $Self->unsupported("VCS unsupported"); + +compile ( + v_flags2 => ['+define+T_PACKAGE_EXPORT',], + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_package_export.v b/test_regress/t/t_package_export.v new file mode 100644 index 000000000..b864a14ca --- /dev/null +++ b/test_regress/t/t_package_export.v @@ -0,0 +1,35 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2012 by Jeremy Bennett + +// see bug 591 + +package pkg2; + parameter PARAM2 = 16; +endpackage // pkg2 + +package pkg1; + import pkg2::*; +`ifdef T_PACKAGE_EXPORT + export pkg2::*; // Not supported on all simulators +`endif + parameter PARAM1 = 8; +endpackage // pkg1 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + import pkg1::*; + + reg [PARAM1:0] bus1; + reg [PARAM2:0] bus2; + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_package_export_bad.pl b/test_regress/t/t_package_export_bad.pl new file mode 100755 index 000000000..a1c77460a --- /dev/null +++ b/test_regress/t/t_package_export_bad.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +top_filename("t/t_package_export.v"); + +compile ( + v_flags2 => ['+define+T_PACKAGE_EXPORT_BAD',], + fails=>1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect=> +'%Error: t/t_package_export.v:\d+: Can\'t find definition of variable: PARAM2 +%Error: Exiting due to.*', + ); + + +ok(1); +1;