diff --git a/Changes b/Changes index 2329f0ba5..ecc54683c 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,11 @@ Revision history for Verilator The contributors that suggested a given feature are shown in []. [by ...] indicates the contributor was also the author of the fix; Thanks! +* Verilator 3.84*** devel + +**** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda] + + * Verilator 3.840 2012/07/31 Beta ** Rewrote tristate handling; supports tri0, tri1, tristate bit selects, diff --git a/src/V3Param.cpp b/src/V3Param.cpp index f2b2562d7..354e62f14 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -76,8 +76,8 @@ private: LongMap m_longMap; // Hash of very long names to unique identity number int m_longId; - typedef deque ModDeque; - ModDeque m_todoModps; // Modules left to process + typedef multimap LevelModMap; + LevelModMap m_todoModps; // Modules left to process // METHODS static int debug() { @@ -125,10 +125,12 @@ private: } void visitModules() { // Loop on all modules left to process - // Hitting a cell adds to the END of this list, so since cells originally exist top->bottom - // we process in top->bottom order too. + // Hitting a cell adds to the appropriate leval of this level-sorted list, + // so since cells originally exist top->bottom we process in top->bottom order too. while (!m_todoModps.empty()) { - AstNodeModule* nodep = m_todoModps.front(); m_todoModps.pop_front(); + LevelModMap::iterator it = m_todoModps.begin(); + AstNodeModule* nodep = it->second; + m_todoModps.erase(it); if (!nodep->user5SetOnce()) { // Process once; note clone() must clear so we do it again UINFO(4," MOD "<iterateChildren(*this); @@ -147,7 +149,7 @@ private: UINFO(4," MOD-dead. "<level() <= 2) { // Haven't added top yet, so level 2 is the top // Add request to END of modules left to process - m_todoModps.push_back(nodep); + m_todoModps.insert(make_pair(nodep->level(),nodep)); visitModules(); } else if (nodep->user5()) { UINFO(4," MOD-done "<modp()); + m_todoModps.insert(make_pair(nodep->modp()->level(),nodep->modp())); } //###################################################################### diff --git a/test_regress/t/t_param_ddeep_width.pl b/test_regress/t/t_param_ddeep_width.pl new file mode 100755 index 000000000..87815646d --- /dev/null +++ b/test_regress/t/t_param_ddeep_width.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 ( + verilator_flags2 => ["--lint-only"], + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + ); + +ok(1); +1; diff --git a/test_regress/t/t_param_ddeep_width.v b/test_regress/t/t_param_ddeep_width.v new file mode 100644 index 000000000..daced63cc --- /dev/null +++ b/test_regress/t/t_param_ddeep_width.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use. + +// bug541 +module t(clk,odata); + input clk; + output [7:0] odata; + paramtest_DFFRE #(1) dffre0(clk,odata[7]); + paramtest_WRAP #(7) dffe0(clk,odata[6:0]); +endmodule + +module paramtest_WRAP(clk,q); + parameter W=1; + input clk; + output [W-1:0] q; + paramtest_DFFRE #(W) dffre0(clk,q); +endmodule + +module paramtest_DFFRE(clk,q); + parameter W=1; + parameter [W-1:0] INIT={W{1'b0}}; + input clk; + output [W-1:0] q; + reg [W-1:0] q; + always @(posedge clk) begin + q <= INIT; + end +endmodule