forked from github/verilator
Support package export, bug1217.
This commit is contained in:
parent
331fcb633e
commit
89c8449ec0
2
Changes
2
Changes
@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
*** Support or/and/xor array intrinsic methods, bug1210. [Mike Popoloski]
|
||||
|
||||
*** Support package export, bug1217. [Usuario Eda]
|
||||
|
||||
*** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski]
|
||||
|
||||
**** Support module port parameters without defaults, bug 1213. [Mike Popoloski]
|
||||
|
@ -891,6 +891,10 @@ void AstNodeModule::dump(ostream& str) {
|
||||
if (inLibrary()) str<<" [LIB]";
|
||||
if (dead()) str<<" [DEAD]";
|
||||
}
|
||||
void AstPackageExport::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<packagep();
|
||||
}
|
||||
void AstPackageImport::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<packagep();
|
||||
|
@ -1508,6 +1508,31 @@ public:
|
||||
virtual string verilogKwd() const { return "primitive"; }
|
||||
};
|
||||
|
||||
class AstPackageExportStarStar : public AstNode {
|
||||
// A package export *::* declaration
|
||||
public:
|
||||
AstPackageExportStarStar(FileLine* fl)
|
||||
: AstNode (fl) {}
|
||||
ASTNODE_NODE_FUNCS(PackageExportStarStar)
|
||||
};
|
||||
|
||||
class AstPackageExport : public AstNode {
|
||||
private:
|
||||
// A package export declaration
|
||||
string m_name;
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
public:
|
||||
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
|
||||
: AstNode (fl), m_name(name), m_packagep(packagep) {}
|
||||
ASTNODE_NODE_FUNCS(PackageExport)
|
||||
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
|
||||
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
|
||||
virtual void dump(ostream& str);
|
||||
virtual string name() const { return m_name; }
|
||||
AstPackage* packagep() const { return m_packagep; }
|
||||
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
||||
};
|
||||
|
||||
class AstPackageImport : public AstNode {
|
||||
private:
|
||||
// A package import declaration
|
||||
|
@ -1017,6 +1017,24 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||
UINFO(9," Link Done: "<<nodep<<endl);
|
||||
// No longer needed, but can't delete until any multi-instantiated modules are expanded
|
||||
}
|
||||
virtual void visit(AstPackageExport* nodep) {
|
||||
UINFO(9," Link: "<<nodep<<endl);
|
||||
VSymEnt* srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
if (nodep->name()!="*") {
|
||||
VSymEnt* impp = srcp->findIdFlat(nodep->name());
|
||||
if (!impp) {
|
||||
nodep->v3error("Export object not found: "<<nodep->packagep()->prettyName()<<"::"<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
m_curSymp->exportFromPackage(m_statep->symsp(), srcp, nodep->name());
|
||||
UINFO(9," Link Done: "<<nodep<<endl);
|
||||
// No longer needed, but can't delete until any multi-instantiated modules are expanded
|
||||
}
|
||||
virtual void visit(AstPackageExportStarStar* nodep) {
|
||||
UINFO(2," Link: "<<nodep<<endl);
|
||||
m_curSymp->exportStarStar(m_statep->symsp());
|
||||
// No longer needed, but can't delete until any multi-instantiated modules are expanded
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
@ -2216,6 +2234,16 @@ private:
|
||||
checkNoDot(nodep);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstPackageExport* nodep) {
|
||||
// No longer needed
|
||||
checkNoDot(nodep);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstPackageExportStarStar* nodep) {
|
||||
// No longer needed
|
||||
checkNoDot(nodep);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstCellRef* nodep) {
|
||||
UINFO(5," AstCellRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||
nodep->iterateChildren(*this);
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
if (foundp) return foundp->nodep();
|
||||
else return NULL;
|
||||
}
|
||||
void import(AstNode* packagep, const string& id_or_star) {
|
||||
void importItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Import from package::id_or_star to this
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
|
||||
@ -133,6 +133,19 @@ public:
|
||||
// We let V3LinkDot report the error instead of us
|
||||
symCurrentp()->importFromPackage(&m_syms, symp, id_or_star);
|
||||
}
|
||||
void exportItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Export from this the remote package::id_or_star
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
|
||||
packagep->v3fatalSrc("Export package not found");
|
||||
return;
|
||||
}
|
||||
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);
|
||||
}
|
||||
void exportStarStar(AstNode* packagep) {
|
||||
// Export *::* from remote packages
|
||||
symCurrentp()->exportStarStar(&m_syms);
|
||||
}
|
||||
public:
|
||||
// CREATORS
|
||||
explicit V3ParseSym(AstNetlist* rootp)
|
||||
|
@ -41,6 +41,7 @@ class VSymEnt;
|
||||
// Symbol table
|
||||
|
||||
typedef set<VSymEnt*> VSymMap;
|
||||
typedef set<const VSymEnt*> VSymConstMap;
|
||||
|
||||
class VSymEnt {
|
||||
// Symbol table that can have a "superior" table for resolving upper references
|
||||
@ -65,7 +66,7 @@ private:
|
||||
static inline int debug() { return 0; } // NOT runtime, too hot of a function
|
||||
#endif
|
||||
public:
|
||||
void dumpIterate(ostream& os, VSymMap& doneSymsr, const string& indent, int numLevels, const string& searchName) {
|
||||
void dumpIterate(ostream& os, VSymConstMap& doneSymsr, const string& indent, int numLevels, const string& searchName) const {
|
||||
os<<indent<<"+ "<<left<<setw(30)<<(searchName==""?"\"\"":searchName)<<setw(0)<<right;
|
||||
os<<" se"<<(void*)(this)<<setw(0);
|
||||
os<<" fallb=se"<<(void*)(m_fallbackp);
|
||||
@ -82,8 +83,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
void dump(ostream& os, const string& indent="", int numLevels=1) {
|
||||
VSymMap doneSyms;
|
||||
void dump(ostream& os, const string& indent="", int numLevels=1) const {
|
||||
VSymConstMap doneSyms;
|
||||
dumpIterate(os, doneSyms, indent, numLevels, "TOP");
|
||||
}
|
||||
|
||||
@ -153,35 +154,55 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
private:
|
||||
bool importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
|
||||
void importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
|
||||
if (srcp->exported()
|
||||
&& !findIdFlat(name)) { // Don't insert over existing entry
|
||||
VSymEnt* symp = new VSymEnt(graphp, srcp);
|
||||
symp->exported(false); // Can't reimport an import without an export
|
||||
symp->imported(true);
|
||||
reinsert(name, symp);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
|
||||
if (srcp->exported()) {
|
||||
if (VSymEnt* symp = findIdFlat(name)) { // Should already exist in current table
|
||||
if (!symp->exported()) symp->exported(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
bool importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
|
||||
void importFromPackage(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 != srcp->m_idNameMap.end()) {
|
||||
importOneSymbol(graphp, it->first, it->second);
|
||||
}
|
||||
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 (importOneSymbol(graphp, it->first, it->second)) any = true;
|
||||
importOneSymbol(graphp, it->first, it->second);
|
||||
}
|
||||
}
|
||||
return any;
|
||||
}
|
||||
void exportFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
|
||||
// Export tokens from source symbol table into this symbol table
|
||||
if (id_or_star != "*") {
|
||||
IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star);
|
||||
if (it != srcp->m_idNameMap.end()) {
|
||||
exportOneSymbol(graphp, it->first, it->second);
|
||||
}
|
||||
} else {
|
||||
for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) {
|
||||
exportOneSymbol(graphp, it->first, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
void exportStarStar(VSymGraph* graphp) {
|
||||
// Export *:*: Export all tokens from imported packages
|
||||
for (IdNameMap::const_iterator it=m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) {
|
||||
VSymEnt* symp = it->second;
|
||||
if (!symp->exported()) symp->exported(true);
|
||||
}
|
||||
}
|
||||
void importFromIface(VSymGraph* graphp, const VSymEnt* srcp, bool onlyUnmodportable = false) {
|
||||
// Import interface tokens from source symbol table into this symbol table, recursively
|
||||
@ -239,7 +260,7 @@ public:
|
||||
VSymEnt* rootp() const { return m_symRootp; }
|
||||
// Debug
|
||||
void dump(ostream& os, const string& indent="") {
|
||||
VSymMap doneSyms;
|
||||
VSymConstMap doneSyms;
|
||||
os<<"SymEnt Dump:\n";
|
||||
m_symRootp->dumpIterate(os, doneSyms, indent, 9999, "$root");
|
||||
bool first = true;
|
||||
|
@ -707,7 +707,7 @@ package_itemList<nodep>: // IEEE: { package_item }
|
||||
package_item<nodep>: // ==IEEE: package_item
|
||||
package_or_generate_item_declaration { $$ = $1; }
|
||||
//UNSUP anonymous_program { $$ = $1; }
|
||||
//UNSUP package_export_declaration { $$ = $1; }
|
||||
| package_export_declaration { $$ = $1; }
|
||||
| timeunits_declaration { $$ = $1; }
|
||||
;
|
||||
|
||||
@ -746,7 +746,7 @@ package_import_itemList<nodep>:
|
||||
package_import_item<nodep>: // ==IEEE: package_import_item
|
||||
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
|
||||
{ $$ = new AstPackageImport($<fl>1, $<scp>1->castPackage(), *$3);
|
||||
SYMP->import($<scp>1,*$3); }
|
||||
SYMP->importItem($<scp>1,*$3); }
|
||||
;
|
||||
|
||||
package_import_itemObj<strp>: // IEEE: part of package_import_item
|
||||
@ -754,6 +754,22 @@ package_import_itemObj<strp>: // IEEE: part of package_import_item
|
||||
| '*' { $<fl>$=$<fl>1; static string star="*"; $$=☆ }
|
||||
;
|
||||
|
||||
package_export_declaration<nodep>: // IEEE: package_export_declaration
|
||||
yEXPORT '*' yP_COLONCOLON '*' ';' { $$ = new AstPackageExportStarStar($<fl>1); SYMP->exportStarStar($<scp>1); }
|
||||
| yEXPORT package_export_itemList ';' { $$ = $2; }
|
||||
;
|
||||
|
||||
package_export_itemList<nodep>:
|
||||
package_export_item { $$ = $1; }
|
||||
| package_export_itemList ',' package_export_item { $$ = $1->addNextNull($3); }
|
||||
;
|
||||
|
||||
package_export_item<nodep>: // ==IEEE: package_export_item
|
||||
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
|
||||
{ $$ = new AstPackageExport($<fl>1, $<scp>1->castPackage(), *$3);
|
||||
SYMP->exportItem($<scp>1,*$3); }
|
||||
;
|
||||
|
||||
//**********************************************************************
|
||||
// Module headers
|
||||
|
||||
|
@ -7,7 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# 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 (
|
||||
|
@ -5,17 +5,46 @@
|
||||
|
||||
// see bug 591
|
||||
|
||||
package pkg2;
|
||||
parameter PARAM2 = 16;
|
||||
endpackage // pkg2
|
||||
|
||||
package pkg1;
|
||||
import pkg2::*;
|
||||
parameter PARAM2 = 16;
|
||||
parameter PARAM3 = 16;
|
||||
endpackage : pkg1
|
||||
|
||||
|
||||
package pkg10;
|
||||
import pkg1::*;
|
||||
import pkg1::*; // Ignore if already
|
||||
`ifdef T_PACKAGE_EXPORT
|
||||
export pkg2::*; // Not supported on all simulators
|
||||
export *::*; // Not supported on all simulators
|
||||
`endif
|
||||
parameter PARAM1 = 8;
|
||||
endpackage // pkg1
|
||||
endpackage
|
||||
package pkg11;
|
||||
import pkg10::*;
|
||||
endpackage
|
||||
|
||||
package pkg20;
|
||||
import pkg1::*;
|
||||
`ifdef T_PACKAGE_EXPORT
|
||||
export pkg1::*;
|
||||
`endif
|
||||
parameter PARAM1 = 8;
|
||||
endpackage
|
||||
package pkg21;
|
||||
import pkg20::*;
|
||||
endpackage
|
||||
|
||||
package pkg30;
|
||||
import pkg1::*;
|
||||
`ifdef T_PACKAGE_EXPORT
|
||||
export pkg1::PARAM2;
|
||||
export pkg1::PARAM3;
|
||||
`endif
|
||||
parameter PARAM1 = 8;
|
||||
endpackage
|
||||
package pkg31;
|
||||
import pkg30::*;
|
||||
endpackage
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
@ -23,10 +52,17 @@ module t (/*AUTOARG*/
|
||||
);
|
||||
input clk;
|
||||
|
||||
import pkg1::*;
|
||||
reg [pkg11::PARAM1 : 0] bus11;
|
||||
reg [pkg11::PARAM2 : 0] bus12;
|
||||
reg [pkg11::PARAM3 : 0] bus13;
|
||||
|
||||
reg [PARAM1:0] bus1;
|
||||
reg [PARAM2:0] bus2;
|
||||
reg [pkg21::PARAM1 : 0] bus21;
|
||||
reg [pkg21::PARAM2 : 0] bus22;
|
||||
reg [pkg21::PARAM3 : 0] bus23;
|
||||
|
||||
reg [pkg31::PARAM1 : 0] bus31;
|
||||
reg [pkg31::PARAM2 : 0] bus32;
|
||||
reg [pkg31::PARAM3 : 0] bus33;
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
@ -16,7 +16,12 @@ compile (
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
expect=>
|
||||
'%Error: t/t_package_export.v:\d+: Can\'t find definition of variable: PARAM2
|
||||
'%Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM2
|
||||
%Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM3
|
||||
%Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM2
|
||||
%Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM3
|
||||
%Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM2
|
||||
%Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM3
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user