From 0ab739e8b17863358ee67beabcf2f293f848866e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 6 Jan 2011 06:46:19 -0500 Subject: [PATCH] Fix false BLKSEQ on non-unrolled for loop indexes. --- Changes | 4 + src/V3AstNodes.cpp | 1 + src/V3LinkJump.cpp | 16 +++- src/config_build.h.in | 2 +- test_regress/t/t_lint_blksync_loop.pl | 19 +++++ test_regress/t/t_lint_blksync_loop.v | 102 ++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_lint_blksync_loop.pl create mode 100644 test_regress/t/t_lint_blksync_loop.v diff --git a/Changes b/Changes index ac4561efa..b1e539f74 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.81*** + +**** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston] + * Verilator 3.810 2011/01/03 ** Add limited support for VPI access to public signals, see docs. diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 8d91f2fb4..142ea8112 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -611,6 +611,7 @@ void AstVar::dump(ostream& str) { } if (isUsedClock()) str<<" [C]"; if (isSigPublic()) str<<" [P]"; + if (isUsedLoopIdx()) str<<" [LOOP]"; if (attrClockEn()) str<<" [aCLKEN]"; if (attrIsolateAssign()) str<<" [aISO]"; if (attrFileDescr()) str<<" [aFD]"; diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index f331cce9c..a12c50b85 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -50,6 +50,7 @@ private: AstModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current function/task AstWhile* m_loopp; // Current loop + bool m_loopInc; // In loop increment int m_repeatNum; // Repeat counter BeginStack m_beginStack; // All begin blocks above current node @@ -136,6 +137,7 @@ private: AstLogicPacked(), 32); varp->isSigned(true); varp->dtypep()->isSigned(true); + varp->usedLoopIdx(true); m_modp->addStmtp(varp); AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), countp); @@ -158,8 +160,15 @@ private: virtual void visit(AstWhile* nodep, AstNUser*) { // Don't need to track AstRepeat/AstFor as they have already been converted AstWhile* lastLoopp = m_loopp; + bool lastInc = m_loopInc; m_loopp = nodep; - nodep->iterateChildren(*this); + m_loopInc = false; + nodep->precondsp()->iterateAndNext(*this); + nodep->condp()->iterateAndNext(*this); + nodep->bodysp()->iterateAndNext(*this); + m_loopInc = true; + nodep->incsp()->iterateAndNext(*this); + m_loopInc = lastInc; m_loopp = lastLoopp; } virtual void visit(AstReturn* nodep, AstNUser*) { @@ -202,7 +211,11 @@ private: } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } + virtual void visit(AstVarRef* nodep, AstNUser*) { + if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true); + } + virtual void visit(AstConst* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } @@ -212,6 +225,7 @@ public: m_modp = NULL; m_ftaskp = NULL; m_loopp = NULL; + m_loopInc = false; m_repeatNum = 0; nodep->accept(*this); } diff --git a/src/config_build.h.in b/src/config_build.h.in index 08caeef4a..afb72a606 100644 --- a/src/config_build.h.in +++ b/src/config_build.h.in @@ -25,7 +25,7 @@ //********************************************************************** //**** Version and host name -#define DTVERSION "Verilator 3.810 2010/07/10" +#define DTVERSION "Verilator 3.810+" //********************************************************************** //**** Functions diff --git a/test_regress/t/t_lint_blksync_loop.pl b/test_regress/t/t_lint_blksync_loop.pl new file mode 100755 index 000000000..6bc35463e --- /dev/null +++ b/test_regress/t/t_lint_blksync_loop.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 2008 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 -Wwarn-BLKSEQ -Wwarn-COMBDLY"], + fails=>0, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_lint_blksync_loop.v b/test_regress/t/t_lint_blksync_loop.v new file mode 100644 index 000000000..ae012aa70 --- /dev/null +++ b/test_regress/t/t_lint_blksync_loop.v @@ -0,0 +1,102 @@ +// 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*/ + // Outputs + data_out, + // Inputs + wr, wa, rst_l, rd, ra, data_in, clk + ); + input clk; + + /*AUTOINPUT*/ + // Beginning of automatic inputs (from unused autoinst inputs) + input [31:0] data_in; // To sub of reg_1r1w.v + input [7:0] ra; // To sub of reg_1r1w.v + input rd; // To sub of reg_1r1w.v + input rst_l; // To sub of reg_1r1w.v + input [7:0] wa; // To sub of reg_1r1w.v + input wr; // To sub of reg_1r1w.v + // End of automatics + /*AUTOOUTPUT*/ + // Beginning of automatic outputs (from unused autoinst outputs) + output [31:0] data_out; // From sub of reg_1r1w.v + // End of automatics + + reg_1r1w #(.WIDTH(32), .DEPTH(256), .ADRWID(8)) + sub + (/*AUTOINST*/ + // Outputs + .data_out (data_out[31:0]), + // Inputs + .data_in (data_in[31:0]), + .ra (ra[7:0]), + .wa (wa[7:0]), + .wr (wr), + .rd (rd), + .clk (clk), + .rst_l (rst_l)); + +endmodule + +module reg_1r1w + #( + parameter WIDTH=32, + parameter ADRWID=10, + parameter DEPTH=1024, + parameter RST=0 + ) + (/*AUTOARG*/ + // Outputs + data_out, + // Inputs + data_in, ra, wa, wr, rd, clk, rst_l + ); + + input [WIDTH-1:0] data_in; + input [ADRWID-1:0] ra; + input [ADRWID-1:0] wa; + input wr; + input rd; + input clk; + input rst_l; + + output [WIDTH-1:0] data_out; + + reg [WIDTH-1:0] array [0:DEPTH-1]; + reg [ADRWID-1:0] ra_r, wa_r; + reg [WIDTH-1:0] data_in_r; + reg wr_r; + reg rd_r; + + integer x; + + always @(posedge clk or negedge rst_l) begin + if (!rst_l) begin + for (x=0; x