Fix out of memory on slice syntax error, bug354.

This commit is contained in:
Wilson Snyder 2011-05-21 08:19:33 -04:00
parent 2b330b78b7
commit 4f7b3d8882
4 changed files with 144 additions and 3 deletions

View File

@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix error on enum references to other packages, bug339. [Alex Solomatnikov]
*** Fix out of memory on slice syntax error, bug354. [Alex Solomatnikov]
**** Fix DPI undeclared svBitVecVal compile error, bug346. [Chandan Egbert]
**** Fix DPI bit vector compile errors, bug347. [Chandan Egbert]

View File

@ -53,6 +53,7 @@ class SliceCloneVisitor : public AstNVisitor {
// Inputs:
// AstArraySel::user1p() -> AstVarRef. The VarRef that the final ArraySel points to
// AstNodeAssign::user2() -> int. The number of clones needed for this assign
// AstArraySel::user3() -> bool. Error detected
// ENUMS
enum RedOp { // The type of unary operation to be expanded
@ -221,6 +222,7 @@ class SliceVisitor : public AstNVisitor {
// AstNode::user2() -> int. The number of clones needed for this node
AstUser1InUse m_inuser1;
AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
// TYPEDEFS
typedef pair<uint32_t, uint32_t> ArrayDimensions; // Array Dimensions (packed, unpacked)
@ -332,6 +334,7 @@ class SliceVisitor : public AstNVisitor {
virtual void visit(AstArraySel* nodep, AstNUser*) {
if (!m_assignp) return;
if (nodep->user3()) return; // Prevent recursion on just created nodes
unsigned dim = explicitDimensions(nodep);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
pair<uint32_t,uint32_t> arrDim = refp->varp()->dimensions();
@ -339,16 +342,18 @@ class SliceVisitor : public AstNVisitor {
if (implicit > 0) {
AstArraySel* newp = insertImplicit(nodep->cloneTree(false), dim+1, implicit);
nodep->replaceWith(newp); nodep = newp;
nodep->user3(true);
}
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 && !m_assignError) {
if (m_extend && clones > 1) {
} else if (!m_assignp->user2()) {
if (m_extend && clones > 1 && !m_assignError) {
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()) {
if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp()
&& !m_assignp->castAssignDly() && !m_assignError) {
// 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;

View File

@ -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 (
v_flags2 => ["--lint-only"],
fails=>1,
) if $Self->{v3};
ok(1);
1;

View File

@ -0,0 +1,118 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
//
// bug354
typedef logic [5:0] data_t;
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
// Take CRC data and apply to testblock inputs
wire rst;
data_t iii_in = crc[5:0];
data_t jjj_in = crc[11:6];
data_t iii_out;
data_t jjj_out;
logic [1:0] ctl0 = crc[63:62];
aaa aaa (.*);
// Aggregate outputs into a single result vector
wire [63:0] result = {64'h0};
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
sum <= 64'h0;
rst <= 1'b0;
end
else if (cyc<10) begin
sum <= 64'h0;
rst <= 1'b1;
end
else if (cyc<90) begin
rst <= 1'b0;
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
// What checksum will we end up with (above print should match)
`define EXPECTED_SUM 64'h4afe43fb79d7b71e
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module bbb
(
output data_t ggg_out[1:0],
input data_t ggg_in [1:0],
input [1:0] [1:0] ctl,
input logic clk,
input logic rst
);
genvar i;
generate
for (i=0; i<2; i++) begin: PPP
always_ff @(posedge clk) begin
if (rst) begin
ggg_out[i] <= 6'b0;
end
else begin
if (ctl[i][0]) begin
if (ctl[i][1]) begin
ggg_out[i] <= ~ggg_in[i];
end else begin
ggg_out[i] <= ggg_in[i];
end
end
end
end
end
endgenerate
endmodule
module aaa
(
input data_t iii_in,
input data_t jjj_in,
input [1:0] ctl0,
output data_t iii_out,
output data_t jjj_out,
input logic clk,
input logic rst
);
// Below is a bug; {} concat isn't used to make arrays
bbb bbb (
.ggg_in ({jjj_in, iii_in}),
.ggg_out ({jjj_out, iii_out}),
.ctl ({{1'b1,ctl0[1]}, {1'b0,ctl0[0]}}),
.*);
endmodule