Fix DETECTARRAY on packed structures, bug610.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Jeremy Bennett 2013-02-10 09:54:27 -05:00 committed by Wilson Snyder
parent e1f6802f5f
commit 062eb85075
7 changed files with 131 additions and 2 deletions

View File

@ -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]

View File

@ -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.

View File

@ -87,7 +87,9 @@ private:
AstVar* varp = vscp->varp();
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
AstUnpackArrayDType* arrayp = varp->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): "<<varp->prettyName()<<endl
<<vscp->warnMore()
<<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(msb-lsb+1));
} else if (!isArray
} else if (!isArray && !isStruct
&& !varp->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): "<<varp->prettyName());

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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