Add INITIALDLY warning on initial assignments, bug478.
This commit is contained in:
parent
74c4c1bf44
commit
c75de0f37c
2
Changes
2
Changes
|
|
@ -13,6 +13,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
*** Support nmos and pmos, bug488. [Alex Solomatnikov]
|
*** Support nmos and pmos, bug488. [Alex Solomatnikov]
|
||||||
|
|
||||||
|
*** Add INITIALDLY warning on initial assignments, bug478. [Alex Solomatnikov]
|
||||||
|
|
||||||
*** Add PINMISSING and PINNOCONNECT lint checks.
|
*** Add PINMISSING and PINNOCONNECT lint checks.
|
||||||
|
|
||||||
*** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett]
|
*** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett]
|
||||||
|
|
|
||||||
|
|
@ -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
|
Disabled by default as this is a code style warning; it will simulate
|
||||||
correctly.
|
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
|
=item LITENDIAN
|
||||||
|
|
||||||
Warns that a vector is declared with little endian bit numbering
|
Warns that a vector is declared with little endian bit numbering
|
||||||
|
|
|
||||||
|
|
@ -164,16 +164,22 @@ public:
|
||||||
// Active AssignDly replacement functions
|
// Active AssignDly replacement functions
|
||||||
|
|
||||||
class ActiveDlyVisitor : public ActiveBaseVisitor {
|
class ActiveDlyVisitor : public ActiveBaseVisitor {
|
||||||
|
public:
|
||||||
|
enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL };
|
||||||
private:
|
private:
|
||||||
bool m_combo; // Combo logic
|
CheckType m_check; // Combo logic or other
|
||||||
AstNode* m_alwaysp; // Always we're under
|
AstNode* m_alwaysp; // Always we're under
|
||||||
AstNode* m_assignp; // In assign
|
AstNode* m_assignp; // In assign
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||||
if (m_combo) {
|
if (m_check != CT_SEQ) {
|
||||||
// Convert to a non-delayed assignment
|
// Convert to a non-delayed assignment
|
||||||
UINFO(5," ASSIGNDLY "<<nodep<<endl);
|
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(),
|
AstNode* newp = new AstAssign (nodep->fileline(),
|
||||||
nodep->lhsp()->unlinkFrBack(),
|
nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->rhsp()->unlinkFrBack());
|
||||||
|
|
@ -182,7 +188,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstAssign* nodep, AstNUser*) {
|
virtual void visit(AstAssign* nodep, AstNUser*) {
|
||||||
if (!m_combo) {
|
if (m_check == CT_SEQ) {
|
||||||
AstNode* las = m_assignp;
|
AstNode* las = m_assignp;
|
||||||
m_assignp = nodep;
|
m_assignp = nodep;
|
||||||
nodep->lhsp()->iterateAndNext(*this);
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
|
|
@ -191,7 +197,7 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
AstVar* varp=nodep->varp();
|
AstVar* varp=nodep->varp();
|
||||||
if (!m_combo
|
if (m_check == CT_SEQ
|
||||||
&& m_assignp
|
&& m_assignp
|
||||||
&& !varp->isUsedLoopIdx() // Ignore loop indicies
|
&& !varp->isUsedLoopIdx() // Ignore loop indicies
|
||||||
&& !varp->isTemp()
|
&& !varp->isTemp()
|
||||||
|
|
@ -213,9 +219,9 @@ private:
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
ActiveDlyVisitor(AstNode* nodep, bool combo) {
|
ActiveDlyVisitor(AstNode* nodep, CheckType check) {
|
||||||
m_alwaysp = nodep;
|
m_alwaysp = nodep;
|
||||||
m_combo = combo;
|
m_check = check;
|
||||||
m_assignp = NULL;
|
m_assignp = NULL;
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +258,7 @@ private:
|
||||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||||
// Relink to IACTIVE, unless already under it
|
// Relink to IACTIVE, unless already under it
|
||||||
UINFO(4," INITIAL "<<nodep<<endl);
|
UINFO(4," INITIAL "<<nodep<<endl);
|
||||||
|
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
|
||||||
AstActive* wantactivep = m_namer.getIActive(nodep->fileline());
|
AstActive* wantactivep = m_namer.getIActive(nodep->fileline());
|
||||||
nodep->unlinkFrBack();
|
nodep->unlinkFrBack();
|
||||||
wantactivep->addStmtsp(nodep);
|
wantactivep->addStmtsp(nodep);
|
||||||
|
|
@ -284,6 +291,7 @@ private:
|
||||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
|
||||||
if (!m_scopeFinalp) {
|
if (!m_scopeFinalp) {
|
||||||
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
|
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
|
||||||
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
|
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
|
||||||
|
|
@ -354,10 +362,10 @@ private:
|
||||||
|
|
||||||
// Warn and/or convert any delayed assignments
|
// Warn and/or convert any delayed assignments
|
||||||
if (combo && !sequent) {
|
if (combo && !sequent) {
|
||||||
ActiveDlyVisitor dlyvisitor (nodep, true);
|
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO);
|
||||||
}
|
}
|
||||||
else if (!combo && sequent) {
|
else if (!combo && sequent) {
|
||||||
ActiveDlyVisitor dlyvisitor (nodep, false);
|
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ public:
|
||||||
IMPLICIT, // Implicit wire
|
IMPLICIT, // Implicit wire
|
||||||
IMPURE, // Impure function not being inlined
|
IMPURE, // Impure function not being inlined
|
||||||
INCABSPATH, // Include has absolute path
|
INCABSPATH, // Include has absolute path
|
||||||
|
INITIALDLY, // Initial delayed statement
|
||||||
LITENDIAN, // Little bit endian vector
|
LITENDIAN, // Little bit endian vector
|
||||||
MODDUP, // Duplicate module
|
MODDUP, // Duplicate module
|
||||||
MULTIDRIVEN, // Driven from multiple blocks
|
MULTIDRIVEN, // Driven from multiple blocks
|
||||||
|
|
@ -119,7 +120,8 @@ public:
|
||||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
|
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
|
||||||
"COMBDLY", "DEFPARAM", "DECLFILENAME",
|
"COMBDLY", "DEFPARAM", "DECLFILENAME",
|
||||||
"ENDLABEL", "GENCLK",
|
"ENDLABEL", "GENCLK",
|
||||||
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "INCABSPATH",
|
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
|
||||||
|
"INCABSPATH", "INITIALDLY",
|
||||||
"LITENDIAN", "MODDUP",
|
"LITENDIAN", "MODDUP",
|
||||||
"MULTIDRIVEN",
|
"MULTIDRIVEN",
|
||||||
"PINMISSING", "PINNOCONNECT",
|
"PINMISSING", "PINNOCONNECT",
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
Loading…
Reference in New Issue