Improve error handling on slices of arrays, bug226.

This commit is contained in:
Wilson Snyder 2010-03-20 21:29:16 -04:00
parent 41b167d23c
commit 6715cb9880
4 changed files with 76 additions and 3 deletions

View File

@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix "make install" with configure outside srcdir. [Stefan Wallentowitz]
**** Improve error handling on slices of arrays, bug226. [by Bryon Bradley]
* Verilator 3.801 2010/03/17
*** Support "break", "continue", "return".

View File

@ -151,6 +151,7 @@ class SliceVisitor : public AstNVisitor {
AstNode* m_assignp; // Assignment we are under
AstNodeVarRef* m_lhsVarRefp; // Var on the LHS
bool m_extend; // We have found an extend node
bool m_assignError; // True if the current assign already has an error
// METHODS
static int debug() {
@ -239,8 +240,18 @@ class SliceVisitor : public AstNVisitor {
virtual void visit(AstExtend* nodep, AstNUser*) {
m_extend = true;
if (m_assignp && m_assignp->user2() > 1) {
if (m_assignp && m_assignp->user2() > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
m_assignError = true;
}
nodep->iterateChildren(*this);
}
virtual void visit(AstConst* nodep, AstNUser*) {
m_extend = true;
if (m_assignp && m_assignp->user2() > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between a constant and an array slice");
m_assignError = true;
}
nodep->iterateChildren(*this);
}
@ -258,13 +269,15 @@ class SliceVisitor : public AstNVisitor {
int clones = countClones(nodep);
if (m_assignp->user2() > 0 && m_assignp->user2() != clones) {
m_assignp->v3error("Slices of arrays in assignments must have the same unpacked dimensions");
} else if (m_assignp->user2() == 0) {
} else if (m_assignp->user2() == 0 && !m_assignError) {
if (m_extend && clones > 1) {
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
m_assignError = true;
}
if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp() && !m_assignp->castAssignDly()) {
// LHS Var != RHS Var for a non-delayed assignment
m_assignp->v3error("Unsupported: Slices in a non-delayed assignment with the same Var on both sides");
m_assignError = true;
}
m_assignp->user2(clones);
}
@ -272,8 +285,9 @@ class SliceVisitor : public AstNVisitor {
virtual void visit(AstSel* nodep, AstNUser*) {
m_extend = true;
if (m_assignp && m_assignp->user2() > 1) {
if (m_assignp && m_assignp->user2() > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
m_assignError = true;
}
nodep->iterateChildren(*this);
}
@ -314,6 +328,7 @@ class SliceVisitor : public AstNVisitor {
void findImplicit(AstNodeAssign* nodep) {
if (m_assignp) nodep->v3fatalSrc("Found a NodeAssign under another NodeAssign");
m_assignp = nodep;
m_assignError = false;
m_extend = false;
nodep->user1(true);
// Record the LHS Var so we can check if the Var on the RHS is the same

View File

@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2010 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"],
fails=>1,
expect=>
'%Error: t/t_mem_packed_bad.v:\d+: Unsupported: Assignment between packed arrays of different dimensions
%Error: t/t_mem_packed_bad.v:\d+: Unsupported: Assignment between packed arrays of different dimensions
%Error: t/t_mem_packed_bad.v:\d+: Unsupported: Assignment between packed arrays of different dimensions
%Error: t/t_mem_packed_bad.v:\d+: Unsupported: Assignment between packed arrays of different dimensions
%Error: Exiting due to.*',
) if $Self->{v3};
ok(1);
1;

View File

@ -0,0 +1,34 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc; initial cyc = 0;
logic [1:0][27:0] ch01;
logic [1:0][27:0] ch02;
logic [1:0][27:0] ch03;
logic [27:0] ch04[1:0];
/* verilator lint_off WIDTH */
always @ (posedge clk) begin
// LHS is a 2D packed array, RHS is 1D packed or Const. Unsupported.
ch01 <= {{2{28'd4}}};
ch02 <= {{2{cyc}}};
ch03 <= 56'd0;
// LHS is 1D packed, 1D unpacked, this should never work.
ch04 <= 56'd0;
$display("ch01: %0x %0x", ch01[0], ch01[1]);
$display("ch01: %0x %0x", ch02[0], ch02[1]);
$display("ch01: %0x %0x", ch03[0], ch03[1]);
$display("ch01: %0x %0x", ch04[0], ch04[1]);
end
/* verilator lint_on WIDTH */
endmodule