diff --git a/Changes b/Changes index d587b7dbe..6db06004e 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,10 @@ 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.846-devel + +**** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett] + * Verilator 3.845 2013/02/04 *** Fix nested packed arrays and struct, bug600. [Jeremy Bennett] diff --git a/bin/verilator b/bin/verilator index a71b1cc72..e1e3f72a0 100755 --- a/bin/verilator +++ b/bin/verilator @@ -2840,7 +2840,8 @@ correctly. =item DETECTARRAY Error when Verilator tries to deal with a combinatorial loop that could not be -flattened, and which involves a structure. This typically ocurrs when +flattened, and which involves a datatype which Verilator cannot handle, such +as an unpacked struct or a large unpacked array. This typically ocurrs when -Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below). The solution is to break the loop, as described for UNOPTFLAT. diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index 538f00790..4fd034f86 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -87,7 +87,9 @@ private: AstVar* varp = vscp->varp(); vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<dtypeSkipRefp()->castUnpackArrayDType(); + AstStructDType *structp = varp->dtypeSkipRefp()->castStructDType(); bool isArray = arrayp; + bool isStruct = structp && structp->packed(); int msb = isArray ? arrayp->msb() : 0; int lsb = isArray ? arrayp->lsb() : 0; if (isArray && ((msb - lsb + 1) > DETECTARRAY_MAX_INDEXES)) { @@ -95,7 +97,7 @@ private: <<" array indexes (probably with UNOPTFLAT warning suppressed): "<prettyName()<warnMore() <<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<dtypeSkipRefp()->castBasicDType()) { if (debug()) varp->dumpTree(cout,"-DETECTARRAY-"); vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<prettyName()); diff --git a/test_regress/t/t_detectarray_1.pl b/test_regress/t/t_detectarray_1.pl new file mode 100755 index 000000000..eadb41ee3 --- /dev/null +++ b/test_regress/t/t_detectarray_1.pl @@ -0,0 +1,19 @@ +#!/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 => ["-Wno-UNOPTFLAT"] + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_detectarray_1.v b/test_regress/t/t_detectarray_1.v new file mode 100644 index 000000000..73834ea89 --- /dev/null +++ b/test_regress/t/t_detectarray_1.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Simple test of unoptflat +// +// Trigger the DETECTARRAY error. +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2013 by Jeremy Bennett. + +localparam ID_MSB = 1; + + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + typedef struct packed { + logic [ID_MSB:0] id; + } context_t; + + context_t tsb; + + assign tsb.id = {tsb.id[0], clk}; + + initial begin + tsb.id = 0; + end + + always @(posedge clk or negedge clk) begin + +`ifdef TEST_VERBOSE + $write("tsb.id = %x\n", tsb.id); +`endif + + if (tsb.id[1] != 0) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule diff --git a/test_regress/t/t_detectarray_2.pl b/test_regress/t/t_detectarray_2.pl new file mode 100755 index 000000000..eadb41ee3 --- /dev/null +++ b/test_regress/t/t_detectarray_2.pl @@ -0,0 +1,19 @@ +#!/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 => ["-Wno-UNOPTFLAT"] + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_detectarray_2.v b/test_regress/t/t_detectarray_2.v new file mode 100644 index 000000000..77eb06189 --- /dev/null +++ b/test_regress/t/t_detectarray_2.v @@ -0,0 +1,43 @@ +// DESCRIPTION: Verilator: Simple test of unoptflat +// +// This should trigger the DETECTARRAY error like t_detectarray_1.v, but in +// fact it casuses a broken link error. The only difference is that the struct +// is defined using a constant rather than a localparam. +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2013 by Jeremy Bennett. + +localparam ID_MSB = 1; + + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + typedef struct packed { + logic [1:0] id; + } context_t; + + context_t tsb; + + assign tsb.id = {tsb.id[0], clk}; + + initial begin + tsb.id = 0; + end + + always @(posedge clk or negedge clk) begin + +`ifdef TEST_VERBOSE + $write("tsb.id = %x\n", tsb.id); +`endif + + if (tsb.id[1] != 0) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule