diff --git a/Changes b/Changes index e549f08ab..10eab753d 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,11 @@ 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.869 devel + +**** Suppress COMBDLY when inside always_latch, bug854. [Iztok Jeras] + + * Verilator 3.868 2014-12-20 ** New verilator_coverage program added to replace SystemPerl's vcoverage. diff --git a/src/V3Active.cpp b/src/V3Active.cpp index 48d8dc1c3..b1d1d98f8 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -163,7 +163,7 @@ public: class ActiveDlyVisitor : public ActiveBaseVisitor { public: - enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL }; + enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH }; private: CheckType m_check; // Combo logic or other AstNode* m_alwaysp; // Always we're under @@ -175,6 +175,8 @@ private: UINFO(5," ASSIGNDLY "<v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=)."); + } else if (m_check == CT_LATCH) { + // Suppress. Shouldn't matter that the interior of the latch races } else { nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=)."); } @@ -306,7 +308,7 @@ private: } // METHODS - void visitAlways(AstNode* nodep, AstSenTree* oldsensesp) { + void visitAlways(AstNode* nodep, AstSenTree* oldsensesp, VAlwaysKwd kwd) { // Move always to appropriate ACTIVE based on its sense list if (oldsensesp && oldsensesp->sensesp() @@ -358,7 +360,11 @@ private: // Warn and/or convert any delayed assignments if (combo && !sequent) { - ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO); + if (kwd == VAlwaysKwd::ALWAYS_LATCH) { + ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_LATCH); + } else { + ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO); + } } else if (!combo && sequent) { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ); @@ -374,13 +380,13 @@ private: nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return; } - visitAlways(nodep, nodep->sensesp()); + visitAlways(nodep, nodep->sensesp(), nodep->keyword()); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { // Move always to appropriate ACTIVE based on its sense list UINFO(4," ALWPub "<=9) nodep->dumpTree(cout," Alw: "); - visitAlways(nodep, nodep->sensesp()); + visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS); } virtual void visit(AstSenGate* nodep, AstNUser*) { AstSenItem* subitemp = nodep->sensesp(); diff --git a/test_regress/t/t_lint_latch_bad.pl b/test_regress/t/t_lint_latch_bad.pl new file mode 100755 index 000000000..7de1109d7 --- /dev/null +++ b/test_regress/t/t_lint_latch_bad.pl @@ -0,0 +1,29 @@ +#!/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. + +$Self->{vlt} or $Self->skip("Verilator only test"); + +compile ( + v_flags2 => ["--lint-only -Wwarn-style -Wno-DECLFILENAME"], + fails=>1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect=> +quotemeta( +'%Warning-COMBDLY: t/t_lint_latch_bad.v:24: Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=). +%Warning-COMBDLY: Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message. +%Warning-COMBDLY: *** See the manual before disabling this, +%Warning-COMBDLY: else you may end up with different sim results. +%Error: Exiting due to 1 warning').'.*', + ); + +ok(1); +1; + diff --git a/test_regress/t/t_lint_latch_bad.v b/test_regress/t/t_lint_latch_bad.v new file mode 100644 index 000000000..81129436d --- /dev/null +++ b/test_regress/t/t_lint_latch_bad.v @@ -0,0 +1,29 @@ +// 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 + bl, cl, bc, cc, + // Inputs + a + ); + + input logic a; + output logic bl; + output logic cl; + always_latch begin + bl <= a; // No warning + cl = a; + end + + output logic bc; + output logic cc; + always_comb begin + bc <= a; // Warning + cc = a; + end + + +endmodule