mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Improve error messages on DIDNOTSETTLE, bug1556.
This commit is contained in:
parent
c1a9ada279
commit
f1b10e2b4c
@ -3847,6 +3847,43 @@ as an unpacked struct or a large unpacked array. This typically occurs when
|
||||
|
||||
The solution is to break the loop, as described for UNOPTFLAT.
|
||||
|
||||
=item DIDNOTCONVERGE
|
||||
|
||||
Error at runtime when model did not properly settle.
|
||||
|
||||
Verilator sometimes has to evaluate combinatorial logic multiple times,
|
||||
usually around code where a UNOPTFLAT warning was issued, but disabled.
|
||||
For example:
|
||||
|
||||
always_comb b = ~a;
|
||||
always_comb a = b
|
||||
|
||||
This code will toggle forever, and thus to prevent an infinite loop, the
|
||||
executable will give the didn't converge error.
|
||||
|
||||
To debug this, first is to review any UNOPTFLAT warnings that were ignored.
|
||||
Though typically it is safe to ignore UNOPTFLAT (at a performance cost), at
|
||||
the time of issuing a UNOPTFLAT Verilator didn't know if they would
|
||||
eventually converge and assumed the would.
|
||||
|
||||
Next, run Verilator with --prof-cfuncs. Run make on the generated files
|
||||
with "CPP_FLAGS=-DVL_DEBUG", to allow enabling runtime debug messages.
|
||||
Rerun the test. Now just before the convergence error you should see
|
||||
additional output similar to this:
|
||||
|
||||
CHANGE: filename.v:1: b
|
||||
CHANGE: filename.v:2: a
|
||||
|
||||
This means that signal b and signal a keep changing, inspect the code that
|
||||
modifies these signals. Note if many signals are getting printed then most
|
||||
likely all of them are oscillating. It may also be that e.g. "a" may be
|
||||
oscillating, then "a" feeds signal "c" which then is also reported as
|
||||
oscillating.
|
||||
|
||||
Finally, rare, more difficult cases can be debugged like a "C" program;
|
||||
either enter GDB and use its tracing facilities, or edit the generated C++
|
||||
code to add appropriate prints to see what is going on.
|
||||
|
||||
=item ENDLABEL
|
||||
|
||||
Warns that a label attached to a "end"-something statement does not match
|
||||
@ -4378,42 +4415,6 @@ warnings or errors, submit a bug report.
|
||||
This error indicates that you are using a Verilog language construct
|
||||
that is not yet supported in Verilator. See the Limitations chapter.
|
||||
|
||||
=item Verilated model didn't converge
|
||||
|
||||
Verilator sometimes has to evaluate combinatorial logic multiple times,
|
||||
usually around code where a UNOPTFLAT warning was issued, but disabled.
|
||||
For example:
|
||||
|
||||
always @ (a) b=~a;
|
||||
always @ (b) a=b
|
||||
|
||||
will toggle forever and thus the executable will give the didn't converge
|
||||
error to prevent an infinite loop.
|
||||
|
||||
To debug this, first is to review any UNOPTFLAT warnings that were ignored,
|
||||
though typically these can be ignored (at a performance cost), convergence
|
||||
issues can also be flagged with this warning as Verilator didn't know if
|
||||
they would eventually converge.
|
||||
|
||||
Next, run Verilator with --prof-cfuncs. Run make on the generated
|
||||
files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in your
|
||||
main.cpp.
|
||||
|
||||
This will cause each change in a variable to print a message. Near the
|
||||
bottom you'll see the variables that causes the problem. For the program
|
||||
above:
|
||||
|
||||
CHANGE: filename.v:1: b
|
||||
CHANGE: filename.v:2: a
|
||||
|
||||
If many signals are getting printed then most likely each are oscillating
|
||||
(or there is a bug). It may also be that e.g. "a" may be oscillating, then
|
||||
"a" feeds signal "c" which then is also reported as oscillating.
|
||||
|
||||
Finally, rare more difficult cases can be debugged like a "C" program;
|
||||
either enter GDB and use its tracing facilities, or edit the generated C++
|
||||
code to add appropriate prints to see what is going on.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
@ -1785,7 +1785,8 @@ void Verilated::debug(int level) VL_MT_SAFE {
|
||||
" Message prefix indicates {<thread>,<sequence_number>}.\n"););
|
||||
#else
|
||||
VL_PRINTF_MT("- Verilated::debug attempted,"
|
||||
" but compiled without VL_DEBUG, so messages suppressed.\n");
|
||||
" but compiled without VL_DEBUG, so messages suppressed.\n"
|
||||
"- Suggest remake using 'make ... CPPFLAGS=-DVL_DEBUG'\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1196,7 +1196,7 @@ class EmitCImp : EmitCStmts {
|
||||
puts(")) VL_DBG_MSGF(\" CHANGE: ");
|
||||
puts(protect(nodep->fileline()->filename()));
|
||||
puts(":"+cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(": "+varname+"\\n\"); );\n");
|
||||
puts(varname+"\\n\"); );\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2056,7 +2056,7 @@ void EmitCImp::emitStaticDecl(AstNodeModule* modp) {
|
||||
|
||||
void EmitCImp::emitTextSection(AstType type) {
|
||||
int last_line = -999;
|
||||
for (AstNode* nodep = m_modp->stmtsp(); nodep != NULL; nodep = nodep->nextp()) {
|
||||
for (AstNode* nodep = m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstNodeText* textp = VN_CAST(nodep, NodeText)) {
|
||||
if (nodep->type() == type) {
|
||||
if (last_line != nodep->fileline()->lineno()) {
|
||||
@ -2131,7 +2131,7 @@ void EmitCImp::emitSettleLoop(const std::string& eval_call, bool initial) {
|
||||
puts("int __VclockLoop = 0;\n");
|
||||
puts("QData __Vchange = 1;\n");
|
||||
puts("do {\n");
|
||||
puts( eval_call + "\n");
|
||||
puts( eval_call+"\n");
|
||||
puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
|
||||
+")) {\n");
|
||||
puts( "// About to fail, so enable debug to see what's not settling.\n");
|
||||
@ -2140,9 +2140,15 @@ void EmitCImp::emitSettleLoop(const std::string& eval_call, bool initial) {
|
||||
puts( "Verilated::debug(1);\n");
|
||||
puts( "__Vchange = "+protect("_change_request")+"(vlSymsp);\n");
|
||||
puts( "Verilated::debug(__Vsaved_debug);\n");
|
||||
puts( "VL_FATAL_MT(__FILE__, __LINE__, __FILE__, \"Verilated model didn't ");
|
||||
puts( "VL_FATAL_MT(");
|
||||
putsQuoted(protect(m_modp->fileline()->filename()));
|
||||
puts(", ");
|
||||
puts(cvtToStr(m_modp->fileline()->lineno()));
|
||||
puts(", \"\",\n");
|
||||
puts("\"Verilated model didn't ");
|
||||
if (initial) puts("DC ");
|
||||
puts( "converge\");\n");
|
||||
puts("converge\\n\"\n");
|
||||
puts("\"- See DIDNOTCONVERGE in the Verilator manual\");\n");
|
||||
puts( "} else {\n");
|
||||
puts( "__Vchange = "+protect("_change_request")+"(vlSymsp);\n");
|
||||
puts( "}\n");
|
||||
|
@ -1960,6 +1960,7 @@ sub files_identical {
|
||||
} @l1;
|
||||
@l1 = map {
|
||||
s/(Internal Error: [^\n]+\.cpp):[0-9]+:/$1:#:/;
|
||||
s/^-V\{t[0-9]+,[0-9]+\}/-V{t#,#}/; # --vlt vs --vltmt run differences
|
||||
$_;
|
||||
} @l1;
|
||||
for (my $l=0; $l<=$#l1; ++$l) {
|
||||
|
5
test_regress/t/t_unopt_converge_initial_run_bad.out
Normal file
5
test_regress/t/t_unopt_converge_initial_run_bad.out
Normal file
@ -0,0 +1,5 @@
|
||||
-V{t#,#}- Verilated::debug is on. Message prefix indicates {<thread>,<sequence_number>}.
|
||||
-V{t#,#}+ Vt_unopt_converge_initial_run_bad::_change_request
|
||||
-V{t#,#} CHANGE: t/t_unopt_converge_initial.v:18: x
|
||||
%Error: t/t_unopt_converge_initial.v:6: Verilated model didn't DC converge
|
||||
Aborting...
|
@ -17,7 +17,7 @@ compile(
|
||||
|
||||
execute(
|
||||
fails => 1,
|
||||
expect => '%Error: \S+:\d+: Verilated model didn\'t DC converge',
|
||||
expect_filename => $Self->{golden_filename},
|
||||
) if $Self->{vlt_all};
|
||||
|
||||
ok(1);
|
||||
|
2
test_regress/t/t_unopt_converge_ndbg_bad.out
Normal file
2
test_regress/t/t_unopt_converge_ndbg_bad.out
Normal file
@ -0,0 +1,2 @@
|
||||
%Error: t/t_unopt_converge.v:6: Verilated model didn't converge
|
||||
Aborting...
|
25
test_regress/t/t_unopt_converge_ndbg_bad.pl
Executable file
25
test_regress/t/t_unopt_converge_ndbg_bad.pl
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2007 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_unopt_converge.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+ALLOW_UNOPT'],
|
||||
make_flags => 'CPPFLAGS_ADD=-UVL_DEBUG',
|
||||
);
|
||||
|
||||
execute(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
) if $Self->{vlt_all};
|
||||
|
||||
ok(1);
|
||||
1;
|
5
test_regress/t/t_unopt_converge_print_bad.out
Normal file
5
test_regress/t/t_unopt_converge_print_bad.out
Normal file
@ -0,0 +1,5 @@
|
||||
-V{t#,#}- Verilated::debug is on. Message prefix indicates {<thread>,<sequence_number>}.
|
||||
-V{t#,#}+ Vt_unopt_converge_print_bad::_change_request
|
||||
-V{t#,#} CHANGE: t/t_unopt_converge.v:18: x
|
||||
%Error: t/t_unopt_converge.v:6: Verilated model didn't converge
|
||||
Aborting...
|
@ -19,7 +19,7 @@ compile(
|
||||
|
||||
execute(
|
||||
fails => 1,
|
||||
expect => '%Error: \S+:\d+: Verilated model didn\'t converge',
|
||||
expect_filename => $Self->{golden_filename},
|
||||
) if $Self->{vlt_all};
|
||||
|
||||
ok(1);
|
||||
|
5
test_regress/t/t_unopt_converge_run_bad.out
Normal file
5
test_regress/t/t_unopt_converge_run_bad.out
Normal file
@ -0,0 +1,5 @@
|
||||
-V{t#,#}- Verilated::debug is on. Message prefix indicates {<thread>,<sequence_number>}.
|
||||
-V{t#,#}+ Vt_unopt_converge_run_bad::_change_request
|
||||
-V{t#,#} CHANGE: t/t_unopt_converge.v:18: x
|
||||
%Error: t/t_unopt_converge.v:6: Verilated model didn't converge
|
||||
Aborting...
|
@ -17,7 +17,7 @@ compile(
|
||||
|
||||
execute(
|
||||
fails => 1,
|
||||
expect => '%Error: \S+:\d+: Verilated model didn\'t converge',
|
||||
expect_filename => $Self->{golden_filename},
|
||||
) if $Self->{vlt_all};
|
||||
|
||||
ok(1);
|
||||
|
@ -1,24 +1,24 @@
|
||||
-V{t0,1}- Verilated::debug is on. Message prefix indicates {<thread>,<sequence_number>}.
|
||||
-V{t0,2}+ Vt_verilated_debug::_ctor_var_reset
|
||||
-V{t#,#}- Verilated::debug is on. Message prefix indicates {<thread>,<sequence_number>}.
|
||||
-V{t#,#}+ Vt_verilated_debug::_ctor_var_reset
|
||||
internalsDump:
|
||||
Version: Verilator ###
|
||||
Argv: obj_vlt/t_verilated_debug/Vt_verilated_debug
|
||||
scopesDump:
|
||||
|
||||
-V{t0,3}+++++TOP Evaluate Vt_verilated_debug::eval
|
||||
-V{t0,4}+ Vt_verilated_debug::_eval_debug_assertions
|
||||
-V{t0,5}+ Vt_verilated_debug::_eval_initial
|
||||
-V{t0,6}+ Vt_verilated_debug::_eval_settle
|
||||
-V{t0,7}+ Vt_verilated_debug::_eval
|
||||
-V{t0,8}+ Vt_verilated_debug::_change_request
|
||||
-V{t0,9}+ Clock loop
|
||||
-V{t0,10}+ Vt_verilated_debug::_eval
|
||||
-V{t0,11}+ Vt_verilated_debug::_change_request
|
||||
-V{t0,12}+++++TOP Evaluate Vt_verilated_debug::eval
|
||||
-V{t0,13}+ Vt_verilated_debug::_eval_debug_assertions
|
||||
-V{t0,14}+ Clock loop
|
||||
-V{t0,15}+ Vt_verilated_debug::_eval
|
||||
-V{t0,16}+ Vt_verilated_debug::_sequent__TOP__1
|
||||
-V{t#,#}+++++TOP Evaluate Vt_verilated_debug::eval
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval_debug_assertions
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval_initial
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval_settle
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval
|
||||
-V{t#,#}+ Vt_verilated_debug::_change_request
|
||||
-V{t#,#}+ Clock loop
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval
|
||||
-V{t#,#}+ Vt_verilated_debug::_change_request
|
||||
-V{t#,#}+++++TOP Evaluate Vt_verilated_debug::eval
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval_debug_assertions
|
||||
-V{t#,#}+ Clock loop
|
||||
-V{t#,#}+ Vt_verilated_debug::_eval
|
||||
-V{t#,#}+ Vt_verilated_debug::_sequent__TOP__1
|
||||
*-* All Finished *-*
|
||||
-V{t0,17}+ Vt_verilated_debug::_change_request
|
||||
-V{t0,18}+ Vt_verilated_debug::final
|
||||
-V{t#,#}+ Vt_verilated_debug::_change_request
|
||||
-V{t#,#}+ Vt_verilated_debug::final
|
||||
|
Loading…
Reference in New Issue
Block a user