From 891edad53a799332db481767b198af2780a9b23c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 5 Nov 2007 14:09:22 +0000 Subject: [PATCH] Fixed generate for loops with constant zero conditions. git-svn-id: file://localhost/svn/verilator/trunk/verilator@968 77ca24e4-aefa-0310-84f0-b9a241c72d87 --- Changes | 4 ++- src/V3Unroll.cpp | 15 ++++++++--- test_regress/t/t_gen_for0.pl | 18 ++++++++++++++ test_regress/t/t_gen_for0.v | 48 ++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100755 test_regress/t/t_gen_for0.pl create mode 100644 test_regress/t/t_gen_for0.v diff --git a/Changes b/Changes index 3b7e34195..ebf56a9db 100644 --- a/Changes +++ b/Changes @@ -7,7 +7,9 @@ indicates the contributor was also the author of the fix; Thanks! *** Support "#delay ;" with associated STMTDLY warning. -**** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair] +**** Fixed generate for loops with constant zero conditions. [Rodney Sinclair] + +**** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair] **** Fixed wrong result with obscure signed-shift underneath a "? :". diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index a2ba56324..e5f1733c2 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -313,9 +313,18 @@ private: if (nodep->initsp()) V3Const::constifyTree(nodep->initsp()); if (nodep->condp()) V3Const::constifyTree(nodep->condp()); if (nodep->incsp()) V3Const::constifyTree(nodep->incsp()); - if (forUnrollCheck(nodep, nodep->initsp(), - NULL, nodep->condp(), - nodep->incsp(), nodep->bodysp())) { + if (nodep->condp()->isZero()) { + // We don't need to do any loops. Remove the GenFor, + // Genvar's don't care about any initial assignments. + // + // Note normal For's can't do exactly this deletion, as + // we'd need to initialize the variable to the initial + // condition, but they'll become while's which can be + // deleted by V3Const. + nodep->unlinkFrBack()->deleteTree(); nodep=NULL; + } else if (forUnrollCheck(nodep, nodep->initsp(), + NULL, nodep->condp(), + nodep->incsp(), nodep->bodysp())) { pushDeletep(nodep); nodep=NULL; // Did replacement } else { nodep->v3error("For loop doesn't have genvar index, or is misformed"); diff --git a/test_regress/t/t_gen_for0.pl b/test_regress/t/t_gen_for0.pl new file mode 100755 index 000000000..7bfdbe852 --- /dev/null +++ b/test_regress/t/t_gen_for0.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; } +# $Id$ +# 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 +# General Public License or the Perl Artistic License. + +compile ( + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_gen_for0.v b/test_regress/t/t_gen_for0.v new file mode 100644 index 000000000..79be997b7 --- /dev/null +++ b/test_regress/t/t_gen_for0.v @@ -0,0 +1,48 @@ +// $Id$ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2007 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + integer cyc=0; + + Testit testit (/*AUTOINST*/ + // Inputs + .clk (clk)); + + always @ (posedge clk) begin + cyc <= cyc + 1; + if (cyc==0) begin + end + else if (cyc<10) begin + end + else if (cyc<90) begin + end + else if (cyc==99) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule + +module Testit (clk); + input clk; + + genvar igen; + generate + for (igen=0; igen<0; igen=igen+1) begin : test_gen + always @ (posedge clk) begin + $display("igen1 = %d", igen); + $stop; + end + end + endgenerate + +endmodule