From 8031f0ed7fa26edaa73b378b1027400b9bbcee70 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 15 Jun 2014 11:18:47 -0400 Subject: [PATCH] Fix duplicate anonymous structures in , bug788. --- Changes | 2 ++ src/V3Ast.h | 4 +++- src/V3AstNodes.h | 2 +- src/verilog.y | 21 ++++++++------------- test_regress/t/t_struct_anon.pl | 18 ++++++++++++++++++ test_regress/t/t_struct_anon.v | 26 ++++++++++++++++++++++++++ 6 files changed, 58 insertions(+), 15 deletions(-) create mode 100755 test_regress/t/t_struct_anon.pl create mode 100644 test_regress/t/t_struct_anon.v diff --git a/Changes b/Changes index 3f22c9323..e0c5b1002 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.863 devel +**** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard] + * Verilator 3.862 2014-06-10 diff --git a/src/V3Ast.h b/src/V3Ast.h index 9600daec7..2c38279df 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1810,12 +1810,13 @@ private: bool m_internal:1; // Internally created int m_level; // 1=top module, 2=cell off top module, ... int m_varNum; // Incrementing variable number + int m_typeNum; // Incrementing implicit type number public: AstNodeModule(FileLine* fl, const string& name) : AstNode (fl) ,m_name(name), m_origName(name) ,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false), m_internal(false) - ,m_level(0), m_varNum(0) { } + ,m_level(0), m_varNum(0), m_typeNum(0) { } ASTNODE_BASE_FUNCS(NodeModule) virtual void dump(ostream& str); virtual bool maybePointedTo() const { return true; } @@ -1835,6 +1836,7 @@ public: int level() const { return m_level; } bool isTop() const { return level()==1; } int varNumGetInc() { return ++m_varNum; } + int typeNumGetInc() { return ++m_typeNum; } void modPublic(bool flag) { m_modPublic = flag; } bool modPublic() const { return m_modPublic; } void modTrace(bool flag) { m_modTrace = flag; } diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index ae8c04b35..eb205928f 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -221,7 +221,7 @@ private: void* m_containerp; // In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value) int m_uniqueNum; public: - AstDefImplicitDType(FileLine* fl, const string& name, AstNode* containerp, + AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl), m_name(name), m_containerp(containerp) { childDTypep(dtp); // Only for parser diff --git a/src/verilog.y b/src/verilog.y index 2b6389abe..f92215efc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -62,8 +62,8 @@ public: int m_pinNum; // Pin number currently parsing string m_instModule; // Name of module referenced for instantiations AstPin* m_instParamp; // Parameters for instantiations - AstNodeModule* m_modp; // Module - int m_modTypeImpNum; // Implicit type number, incremented each module + + static int s_modTypeImpNum; // Implicit type number, incremented each module // CONSTRUCTORS V3ParseGrammar() { @@ -76,8 +76,6 @@ public: m_pinNum = -1; m_instModule = ""; m_instParamp = NULL; - m_modp = NULL; - m_modTypeImpNum = 0; m_varAttrp = NULL; m_caseAttrp = NULL; } @@ -121,7 +119,6 @@ public: AstPackage* pkgp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName())->nodep()->castPackage(); if (!pkgp) { pkgp = PARSEP->rootp()->dollarUnitPkgAddp(); - GRAMMARP->m_modp = pkgp; GRAMMARP->m_modTypeImpNum = 0; SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global } return pkgp; @@ -167,6 +164,8 @@ public: const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC" const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT; +int V3ParseGrammar::s_modTypeImpNum = 0; + //====================================================================== // Macro functions @@ -697,7 +696,6 @@ packageFront: { $$ = new AstPackage($1,*$2); $$->inLibrary(true); // packages are always libraries; don't want to make them a "top" $$->modTrace(v3Global.opt.trace()); - GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; @@ -793,7 +791,6 @@ modFront: yMODULE lifetimeE idAny { $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine()); $$->modTrace(v3Global.opt.trace()); - GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; @@ -810,7 +807,6 @@ udpFront: $$->modTrace(false); $$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE)); PARSEP->fileline()->tracingOn(false); - GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; @@ -1029,7 +1025,6 @@ pgmFront: yPROGRAM lifetimeE idAny/*new_program*/ { $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine()); $$->modTrace(v3Global.opt.trace()); - GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; @@ -1344,10 +1339,10 @@ data_typeBasic: // IEEE: part of data_type data_typeNoRef: // ==IEEE: data_type, excluding class_type etc references data_typeBasic { $$ = $1; } - | struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->m_modTypeImpNum++), - GRAMMARP->m_modp,VFlagChildDType(),$1),$2,true); } - | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++), - GRAMMARP->m_modp,VFlagChildDType(),$1); } + | struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->s_modTypeImpNum++), + SYMP,VFlagChildDType(),$1),$2,true); } + | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->s_modTypeImpNum++), + SYMP,VFlagChildDType(),$1); } | ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); } | yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); } //UNSUP yEVENT { UNSUP } diff --git a/test_regress/t/t_struct_anon.pl b/test_regress/t/t_struct_anon.pl new file mode 100755 index 000000000..1774aab4f --- /dev/null +++ b/test_regress/t/t_struct_anon.pl @@ -0,0 +1,18 @@ +#!/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. + +compile ( + v_flags2 => ["--lint-only"], + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + ); + +ok(1); +1; diff --git a/test_regress/t/t_struct_anon.v b/test_regress/t/t_struct_anon.v new file mode 100644 index 000000000..2b97364bc --- /dev/null +++ b/test_regress/t/t_struct_anon.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2013 by Wilson Snyder. + +// Anonymous +struct packed { + logic [31:0] val1; + logic [31:0] val2; +} struct1; + +struct packed { + logic [31:0] val3; + logic [31:0] val4; +} struct2; + +module t ( + output [63:0] s1, + output [63:0] s2 +); + initial struct1 = 64'h123456789_abcdef0; + always_comb s1 = struct1; + initial struct2 = 64'h123456789_abcdef0; + always_comb s2 = struct2; +endmodule +