From 5f9810070d35c074041572ce463cdda117912a22 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 8 Aug 2012 21:59:17 -0400 Subject: [PATCH] Fix imports under multiple instantiated cells, bug542. --- Changes | 2 + src/V3LinkDot.cpp | 10 ++++- test_regress/t/t_package_dimport.pl | 16 +++++++ test_regress/t/t_package_dimport.v | 68 +++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_package_dimport.pl create mode 100644 test_regress/t/t_package_dimport.v diff --git a/Changes b/Changes index effde60ea..756371bd6 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda] +**** Fix imports under multiple instantiated cells, bug542. [Alex Solomatnikov] + **** Fix defparam in generate broke in 3.840, bug543. [Alex Solomatnikov] diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 3fb9f586a..cb4233c55 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -743,8 +743,7 @@ private: } } m_curSymp->import(srcp, nodep->name()); - // No longer needed - nodep->unlinkFrBack()->deleteTree(); nodep=NULL; + // No longer needed, but can't delete until any multi-instantiated modules are expanded } virtual void visit(AstNode* nodep, AstNUser*) { @@ -1297,6 +1296,7 @@ private: <<"'"<<" as a "<nodep()->typeName() <<" but expected a "<v3error("Can't find definition of "<prettyName()); } else { @@ -1445,7 +1445,9 @@ private: nodep->packagep(foundp->packagep()); UINFO(7," Resolved "<preErrorDump(); + UINFO(7," ErrFtask curSymp=se"<<(void*)m_curSymp<<" dotSymp=se"<<(void*)dotSymp<dotted() == "") { nodep->v3error("Can't find definition of task/function: "<prettyName()); } else { @@ -1527,6 +1529,10 @@ private: } nodep->unlinkFrBack()->deleteTree(); } + virtual void visit(AstPackageImport* nodep, AstNUser*) { + // No longer needed + nodep->unlinkFrBack()->deleteTree(); nodep=NULL; + } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); diff --git a/test_regress/t/t_package_dimport.pl b/test_regress/t/t_package_dimport.pl new file mode 100755 index 000000000..6995cc39a --- /dev/null +++ b/test_regress/t/t_package_dimport.pl @@ -0,0 +1,16 @@ +#!/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 ( + ); + +# Compile only + +ok(1); +1; diff --git a/test_regress/t/t_package_dimport.v b/test_regress/t/t_package_dimport.v new file mode 100644 index 000000000..2305c5820 --- /dev/null +++ b/test_regress/t/t_package_dimport.v @@ -0,0 +1,68 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2009 by Wilson Snyder. + +package defs; + function automatic integer max; + input integer a; + input integer b; + max = (a > b) ? a : b; + endfunction + + function automatic integer log2; + input integer value; + value = value >> 1; + for (log2 = 0; value > 0; log2 = log2 + 1) + value = value >> 1; + endfunction + + function automatic integer ceil_log2; + input integer value; + value = value - 1; + for (ceil_log2 = 0; value > 0; ceil_log2 = ceil_log2 + 1) + value = value >> 1; + endfunction +endpackage + +module sub(); + + import defs::*; + + parameter RAND_NUM_MAX = ""; + + localparam DATA_RANGE = RAND_NUM_MAX + 1; + localparam DATA_WIDTH = ceil_log2(DATA_RANGE); + localparam WIDTH = max(4, ceil_log2(DATA_RANGE + 1)); + +endmodule + +module t(/*AUTOARG*/ + // Inputs + clk + ); + + import defs::*; + + parameter WHICH = 0; + parameter MAX_COUNT = 10; + + localparam MAX_EXPONENT = log2(MAX_COUNT); + localparam EXPONENT_WIDTH = ceil_log2(MAX_EXPONENT + 1); + + input clk; + + generate + if (WHICH == 1) + begin : which_true + sub sub_true(); + defparam sub_true.RAND_NUM_MAX = MAX_EXPONENT; + end + else + begin : which_false + sub sub_false(); + defparam sub_false.RAND_NUM_MAX = MAX_COUNT; + end + endgenerate + +endmodule