forked from github/verilator
Support elaboration assertions, bug973.
This commit is contained in:
parent
040b1b06d5
commit
4fde6ee7af
2
Changes
2
Changes
@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
** Support $sformatf, bug977. [Johan Bjork]
|
||||
|
||||
*** Support elaboration assertions, bug973. [Johan Bjork]
|
||||
|
||||
**** Add VerilatedScopeNameMap for introspection, bug966. [Todd Strader]
|
||||
|
||||
**** Fix very long module names, bug937. [Todd Strader]
|
||||
|
@ -3340,6 +3340,10 @@ with "unused" in the name, or put the appropriate lint_off around the wire.
|
||||
Having unused signals in one place makes it easy to find what is unused,
|
||||
and reduces the number of lint_off pragmas, reducing bugs.
|
||||
|
||||
=item USERINFO, USERWARN, USERERROR, USERFATAL
|
||||
|
||||
A SystemVerilog elaboration-time assertion print was executed.
|
||||
|
||||
=item VARHIDDEN
|
||||
|
||||
Warns that a task, function, or begin/end block is declaring a variable by
|
||||
|
@ -96,6 +96,10 @@ public:
|
||||
UNPACKED, // Unsupported unpacked
|
||||
UNSIGNED, // Comparison is constant due to unsigned arithmetic
|
||||
UNUSED, // No receivers
|
||||
USERERROR, // Elaboration time $error
|
||||
USERFATAL, // Elaboration time $fatal
|
||||
USERINFO, // Elaboration time $info
|
||||
USERWARN, // Elaboration time $warning
|
||||
VARHIDDEN, // Hiding variable
|
||||
WIDTH, // Width mismatch
|
||||
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
|
||||
@ -132,6 +136,7 @@ public:
|
||||
"REALCVT", "REDEFMACRO",
|
||||
"SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNPACKED", "UNSIGNED", "UNUSED",
|
||||
"USERERROR", "USERFATAL", "USERINFO", "USERWARN",
|
||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||
" MAX"
|
||||
};
|
||||
|
@ -343,13 +343,6 @@ private:
|
||||
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
if (!m_assertp
|
||||
&& (nodep->displayType() == AstDisplayType::DT_INFO
|
||||
|| nodep->displayType() == AstDisplayType::DT_WARNING
|
||||
|| nodep->displayType() == AstDisplayType::DT_ERROR
|
||||
|| nodep->displayType() == AstDisplayType::DT_FATAL)) {
|
||||
nodep->v3error(nodep->verilogKwd()+" only allowed under an assertion.");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstUdpTable* nodep, AstNUser*) {
|
||||
|
@ -580,6 +580,7 @@ private:
|
||||
}
|
||||
}
|
||||
virtual void visit(AstStop* nodep, AstNUser*) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
if (m_params) { // This message seems better than an obscure $stop
|
||||
// The spec says $stop is just ignored, it seems evil to ignore assertions
|
||||
clearOptimizable(nodep,"$stop executed during function constification; maybe indicates assertion firing");
|
||||
@ -695,9 +696,78 @@ private:
|
||||
if (!m_params) { badNodeType(nodep); return; }
|
||||
}
|
||||
|
||||
virtual void visit(AstSFormatF *nodep, AstNUser *) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_params) {
|
||||
AstNode* nextArgp = nodep->exprsp();
|
||||
|
||||
string result = "";
|
||||
string format = nodep->text();
|
||||
string::const_iterator pos = format.begin();
|
||||
bool inPct = false;
|
||||
for (; pos != format.end(); ++pos) {
|
||||
if (!inPct && pos[0] == '%') {
|
||||
inPct = true;
|
||||
} else if (!inPct) { // Normal text
|
||||
result += *pos;
|
||||
} else { // Format character
|
||||
AstNode* argp = nextArgp;
|
||||
inPct = false;
|
||||
nextArgp = nextArgp->nextp();
|
||||
|
||||
if (V3Number::displayedFmtLegal(tolower(pos[0]))) {
|
||||
V3Number* nump = fetchNumberNull(argp);
|
||||
if (!nump) {
|
||||
clearOptimizable(nodep, "Argument for $display like statement is not constant");
|
||||
break;
|
||||
}
|
||||
string format = string("%") + pos[0];
|
||||
result += nump->displayed(format);
|
||||
} else {
|
||||
switch (tolower(pos[0])) {
|
||||
case '%':
|
||||
result += "%";
|
||||
break;
|
||||
default:
|
||||
clearOptimizable(nodep, "Unknown $display-like format code.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodep->text(result);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstDisplay *nodep, AstNUser *) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_params) {
|
||||
switch (nodep->displayType()) {
|
||||
case AstDisplayType::DT_DISPLAY: // FALLTHRU
|
||||
case AstDisplayType::DT_INFO:
|
||||
v3warn(USERINFO, nodep->fmtp()->text());
|
||||
break;
|
||||
case AstDisplayType::DT_ERROR:
|
||||
v3warn(USERERROR, nodep->fmtp()->text());
|
||||
break;
|
||||
case AstDisplayType::DT_WARNING:
|
||||
v3warn(USERWARN, nodep->fmtp()->text());
|
||||
break;
|
||||
case AstDisplayType::DT_FATAL:
|
||||
v3warn(USERFATAL, nodep->fmtp()->text());
|
||||
break;
|
||||
case AstDisplayType::DT_WRITE: // FALLTHRU
|
||||
default:
|
||||
clearOptimizable(nodep, "Unexpected display type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default
|
||||
// These types are definately not reducable
|
||||
// AstCoverInc, AstDisplay, AstArraySel, AstStop, AstFinish,
|
||||
// AstCoverInc, AstArraySel, AstFinish,
|
||||
// AstRand, AstTime, AstUCFunc, AstCCall, AstCStmt, AstUCStmt
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
|
18
test_regress/t/t_assert_elab.pl
Executable file
18
test_regress/t/t_assert_elab.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/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 (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
24
test_regress/t/t_assert_elab.v
Normal file
24
test_regress/t/t_assert_elab.v
Normal file
@ -0,0 +1,24 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Johan Bjork.
|
||||
|
||||
module t;
|
||||
localparam str = "string";
|
||||
function logic checkParameter(input logic [8:0] N);
|
||||
if (N == 1)
|
||||
return 0;
|
||||
$fatal(1, "Parameter %d is invalid...%s and %s", N, str, "constant both work");
|
||||
endfunction
|
||||
|
||||
`ifdef FAILING_ASSERTIONS
|
||||
localparam x = checkParameter(5);
|
||||
`else
|
||||
localparam x = checkParameter(1);
|
||||
`endif
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
28
test_regress/t/t_assert_elab_bad.pl
Executable file
28
test_regress/t/t_assert_elab_bad.pl
Executable file
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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/t_assert_elab.v");
|
||||
unlink("$Self->{obj_dir}/t_assert_elab_bad.log");
|
||||
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+FAILING_ASSERTIONS',
|
||||
$Self->{v3}?'--assert':($Self->{nc}?'+assert':'')],
|
||||
fails => 1,
|
||||
);
|
||||
|
||||
execute (
|
||||
fails => $Self->{vlt},
|
||||
);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/vlt_compile.log",
|
||||
qr/%Warning-USERFATAL: Parameter 5 is invalid...string and constant both work/);
|
||||
|
||||
ok(1);
|
||||
1;
|
Loading…
Reference in New Issue
Block a user