Add --autoflush option
This commit is contained in:
parent
f0a06182ca
commit
4591f35b7c
2
Changes
2
Changes
|
|
@ -8,6 +8,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
** Add --x-assign=fast option, and make it the default.
|
||||
This chooses performance over reset debugging. See the manual.
|
||||
|
||||
** Add --autoflush, for flushing streams after $display. [Steve Tong]
|
||||
|
||||
*** Add $feof, $fgetc, $fgets, $fflush, $fscanf, $sscanf. [Holger Waechtler]
|
||||
|
||||
*** Add $stime. [Holger Waechtler]
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ descriptions in the next sections for more information.
|
|||
{file.c/cc/cpp} Optional C++ files to link in
|
||||
|
||||
--assert Enable all assertions
|
||||
--autoflush Flush streams after all $displays
|
||||
--bin <filename> Override Verilator binary
|
||||
--cc Create C++ output
|
||||
--compiler <compiler-name> Tune for specified C++ compiler
|
||||
|
|
@ -254,6 +255,12 @@ desired, but other assertions are, use --assert --nopsl.)
|
|||
|
||||
See also --x-assign; setting "--x-assign unique" may be desirable.
|
||||
|
||||
=item --autoflush
|
||||
|
||||
After every $display or $fdisplay, flush the output stream. This insures
|
||||
that messages will appear immediately but may reduce performance. Defaults
|
||||
off, which will buffer output as provided by the normal C stdio calls.
|
||||
|
||||
=item --bin I<filename>
|
||||
|
||||
Rarely needed. Override the default filename for Verilator itself. When a
|
||||
|
|
|
|||
|
|
@ -306,11 +306,15 @@ public:
|
|||
puts("=0; }\n");
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||
puts("if (");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(") { fflush (VL_CVT_Q_FP(");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(")); ");
|
||||
if (!nodep->filep()) {
|
||||
puts("fflush (stdout);\n");
|
||||
} else {
|
||||
puts("if (");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(") { fflush (VL_CVT_Q_FP(");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(")); }\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
nodep->precondsp()->iterateAndNext(*this);
|
||||
|
|
|
|||
|
|
@ -368,7 +368,9 @@ private:
|
|||
}
|
||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
if (nodep->filep()) {
|
||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFGetC* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
|
|||
|
|
@ -563,6 +563,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
|||
else if ( onoff (sw, "-MMD", flag/*ref*/) ) { m_makeDepend = flag; }
|
||||
else if ( onoff (sw, "-MP", flag/*ref*/) ) { m_makePhony = flag; }
|
||||
else if ( onoff (sw, "-assert", flag/*ref*/) ) { m_assert = flag; m_psl = flag; }
|
||||
else if ( onoff (sw, "-autoflush", flag/*ref*/) ) { m_autoflush = flag; }
|
||||
else if ( !strcmp (sw, "-cc") ) { m_outFormatOk = true; m_systemC = false; m_systemPerl = false; }
|
||||
else if ( onoff (sw, "-coverage", flag/*ref*/) ) { coverage(flag); }
|
||||
else if ( onoff (sw, "-coverage-line", flag/*ref*/) ){ m_coverageLine = flag; }
|
||||
|
|
@ -793,6 +794,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename) {
|
|||
V3Options::V3Options() {
|
||||
m_impp = new V3OptionsImp;
|
||||
|
||||
m_autoflush = false;
|
||||
m_coverageLine = false;
|
||||
m_coverageUser = false;
|
||||
m_debugCheck = false;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class V3Options {
|
|||
bool m_makeDepend; // main switch: -MMD
|
||||
bool m_makePhony; // main switch: -MP
|
||||
bool m_assert; // main switch: --assert
|
||||
bool m_autoflush; // main switch: --autoflush
|
||||
bool m_coverageLine; // main switch: --coverage-block
|
||||
bool m_coverageUser; // main switch: --coverage-func
|
||||
bool m_debugCheck; // main switch: --debug-check
|
||||
|
|
@ -182,6 +183,7 @@ class V3Options {
|
|||
bool skipIdentical() const { return m_skipIdentical; }
|
||||
bool stats() const { return m_stats; }
|
||||
bool assertOn() const { return m_assert; } // assertOn as "assert" may be defined
|
||||
bool autoflush() const { return m_autoflush; }
|
||||
bool coverage() const { return m_coverageUser || m_coverageLine; }
|
||||
bool coverageLine() const { return m_coverageLine; }
|
||||
bool coverageUser() const { return m_coverageUser; }
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
// For each wide OP, make a a temporary variable with the wide value
|
||||
// For each deep expression, assign expression to temporary.
|
||||
//
|
||||
// Each display (independant transformation; here as Premit is a good point)
|
||||
// If autoflush, insert a flush
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
|
|
@ -264,6 +267,26 @@ private:
|
|||
checkNode(nodep);
|
||||
}
|
||||
|
||||
// Autoflush
|
||||
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
|
||||
startStatement(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
m_stmtp = NULL;
|
||||
if (v3Global.opt.autoflush()) {
|
||||
AstNode* searchp = nodep->nextp();
|
||||
while (searchp && searchp->castComment()) searchp = searchp->nextp();
|
||||
if (searchp
|
||||
&& searchp->castDisplay()
|
||||
&& nodep->filep()->sameTree(searchp->castDisplay()->filep())) {
|
||||
// There's another display next; we can just wait to flush
|
||||
} else {
|
||||
UINFO(4,"Autoflush "<<nodep<<endl);
|
||||
nodep->addNextHere(new AstFFlush(nodep->fileline(),
|
||||
nodep->filep()->cloneTree(true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars
|
||||
|
|
|
|||
|
|
@ -586,8 +586,10 @@ private:
|
|||
widthCheck(nodep,"file_descriptor (see docs)",nodep->filep(),64,64);
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||
widthCheck(nodep,"file_descriptor (see docs)",nodep->filep(),64,64);
|
||||
if (nodep->filep()) {
|
||||
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||
widthCheck(nodep,"file_descriptor (see docs)",nodep->filep(),64,64);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFGetC* nodep, AstNUser* vup) {
|
||||
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_sys_file_basic.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+incdir+../include',
|
||||
'+define+AUTOFLUSH'],
|
||||
verilator_flags2 => ['--autoflush'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -9,6 +9,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
|||
unlink("obj_dir/t_sys_file_basic_test.log");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+incdir+../include'],
|
||||
);
|
||||
|
||||
execute (
|
||||
|
|
|
|||
|
|
@ -28,7 +28,13 @@ module t;
|
|||
if (!$feof(file)) $stop;
|
||||
`endif
|
||||
|
||||
file = $fopen("obj_dir/t_sys_file_basic_test.log","w"); // The "w" is required so we get a FD not a MFD
|
||||
`ifdef AUTOFLUSH
|
||||
// The "w" is required so we get a FD not a MFD
|
||||
file = $fopen("obj_dir/t_sys_file_autoflush.log","w");
|
||||
`else
|
||||
// The "w" is required so we get a FD not a MFD
|
||||
file = $fopen("obj_dir/t_sys_file_basic_test.log","w");
|
||||
`endif
|
||||
if ($feof(file)) $stop;
|
||||
|
||||
$fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667);
|
||||
|
|
|
|||
Loading…
Reference in New Issue