Add INITIALDLY warning on initial assignments, bug478.

This commit is contained in:
Wilson Snyder 2012-04-26 20:40:13 -04:00
parent 74c4c1bf44
commit c75de0f37c
7 changed files with 102 additions and 10 deletions

View File

@ -13,6 +13,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Support nmos and pmos, bug488. [Alex Solomatnikov]
*** Add INITIALDLY warning on initial assignments, bug478. [Alex Solomatnikov]
*** Add PINMISSING and PINNOCONNECT lint checks.
*** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett]

View File

@ -2718,6 +2718,15 @@ command line to specify the top include source directory.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item INITIALDLY
Warns that you have a delayed assignment inside of an initial or final
block. If this message is suppressed, Verilator will convert this to a
non-delayed assignment. See also the COMBDLY warning.
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item LITENDIAN
Warns that a vector is declared with little endian bit numbering

View File

@ -164,16 +164,22 @@ public:
// Active AssignDly replacement functions
class ActiveDlyVisitor : public ActiveBaseVisitor {
public:
enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL };
private:
bool m_combo; // Combo logic
CheckType m_check; // Combo logic or other
AstNode* m_alwaysp; // Always we're under
AstNode* m_assignp; // In assign
// VISITORS
virtual void visit(AstAssignDly* nodep, AstNUser*) {
if (m_combo) {
if (m_check != CT_SEQ) {
// Convert to a non-delayed assignment
UINFO(5," ASSIGNDLY "<<nodep<<endl);
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
if (m_check == CT_INITIAL) {
nodep->v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=).");
} else {
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
}
AstNode* newp = new AstAssign (nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
@ -182,7 +188,7 @@ private:
}
}
virtual void visit(AstAssign* nodep, AstNUser*) {
if (!m_combo) {
if (m_check == CT_SEQ) {
AstNode* las = m_assignp;
m_assignp = nodep;
nodep->lhsp()->iterateAndNext(*this);
@ -191,7 +197,7 @@ private:
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
AstVar* varp=nodep->varp();
if (!m_combo
if (m_check == CT_SEQ
&& m_assignp
&& !varp->isUsedLoopIdx() // Ignore loop indicies
&& !varp->isTemp()
@ -213,9 +219,9 @@ private:
}
public:
// CONSTUCTORS
ActiveDlyVisitor(AstNode* nodep, bool combo) {
ActiveDlyVisitor(AstNode* nodep, CheckType check) {
m_alwaysp = nodep;
m_combo = combo;
m_check = check;
m_assignp = NULL;
nodep->accept(*this);
}
@ -252,6 +258,7 @@ private:
virtual void visit(AstInitial* nodep, AstNUser*) {
// Relink to IACTIVE, unless already under it
UINFO(4," INITIAL "<<nodep<<endl);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
AstActive* wantactivep = m_namer.getIActive(nodep->fileline());
nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep);
@ -284,6 +291,7 @@ private:
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
return;
}
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
if (!m_scopeFinalp) {
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
@ -354,10 +362,10 @@ private:
// Warn and/or convert any delayed assignments
if (combo && !sequent) {
ActiveDlyVisitor dlyvisitor (nodep, true);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO);
}
else if (!combo && sequent) {
ActiveDlyVisitor dlyvisitor (nodep, false);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ);
}
}
virtual void visit(AstAlways* nodep, AstNUser*) {

View File

@ -76,6 +76,7 @@ public:
IMPLICIT, // Implicit wire
IMPURE, // Impure function not being inlined
INCABSPATH, // Include has absolute path
INITIALDLY, // Initial delayed statement
LITENDIAN, // Little bit endian vector
MODDUP, // Duplicate module
MULTIDRIVEN, // Driven from multiple blocks
@ -119,7 +120,8 @@ public:
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
"COMBDLY", "DEFPARAM", "DECLFILENAME",
"ENDLABEL", "GENCLK",
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "INCABSPATH",
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
"INCABSPATH", "INITIALDLY",
"LITENDIAN", "MODDUP",
"MULTIDRIVEN",
"PINMISSING", "PINNOCONNECT",

View File

@ -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 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 (
verilator_flags2 => ['-Wno-INITIALDLY'],
);
execute (
check_finished=>1,
);
ok(1);
1;

View File

@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc; initial cyc = 0;
integer a;
integer b;
initial begin
a <= 22;
b <= 33;
end
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc==99) begin
if (a != 22) $stop;
if (b != 33) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule

View File

@ -0,0 +1,21 @@
#!/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.
top_filename("t_initial_dlyass.v");
compile (
v_flags2 => ["--lint-only"],
fails=>1,
expect=>
qr{%Warning-INITIALDLY: t/t_initial_dlyass.v:\d+: Delayed assignments .*
%Error: Exiting due to.*},
);
ok(1);
1;