From 281f4e04ee26adae5873659675de54eb95a0fe13 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 23 Oct 2015 21:53:16 -0400 Subject: [PATCH] Fix $fwrite to constant stderr/stdout, bug961. --- Changes | 2 ++ src/V3LinkResolve.cpp | 16 ---------------- src/verilog.y | 34 ++++++++++++++++----------------- test_regress/t/t_display_mcd.pl | 27 ++++++++++++++++++++++++++ test_regress/t/t_display_mcd.v | 14 ++++++++++++++ 5 files changed, 60 insertions(+), 33 deletions(-) create mode 100755 test_regress/t/t_display_mcd.pl create mode 100644 test_regress/t/t_display_mcd.v diff --git a/Changes b/Changes index 52b74c8fb..ee78d4b71 100644 --- a/Changes +++ b/Changes @@ -27,6 +27,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix package:scope.scope variable references. +**** Fix $fwrite to constant stderr/stdout, bug961. [Wei Song] + * Verilator 3.876 2015-08-12 diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 24bb6b441..a11db34af 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -309,23 +309,8 @@ private: nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } - virtual void visit(AstFFlush* nodep, AstNUser*) { - nodep->iterateChildren(*this); - if (nodep->filep()) { - expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); - } - } - virtual void visit(AstFGetC* nodep, AstNUser*) { - nodep->iterateChildren(*this); - expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); - } - virtual void visit(AstFGetS* nodep, AstNUser*) { - nodep->iterateChildren(*this); - expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); - } virtual void visit(AstFScanF* nodep, AstNUser*) { nodep->iterateChildren(*this); - expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); expectFormat(nodep, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSScanF* nodep, AstNUser*) { @@ -342,7 +327,6 @@ private: } virtual void visit(AstDisplay* nodep, AstNUser* vup) { nodep->iterateChildren(*this); - if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstUdpTable* nodep, AstNUser*) { diff --git a/src/verilog.y b/src/verilog.y index 8f8feaf60..2ac1ad217 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2576,7 +2576,7 @@ system_t_call: // IEEE: system_tf_call (as task) | yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); } | yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); } | yD_FFLUSH parenE { $1->v3error("Unsupported: $fflush of all handles does not map to C++."); } - | yD_FFLUSH '(' idClassSel ')' { $$ = new AstFFlush($1, $3); } + | yD_FFLUSH '(' expr ')' { $$ = new AstFFlush($1, $3); } | yD_FINISH parenE { $$ = new AstFinish($1); } | yD_FINISH '(' expr ')' { $$ = new AstFinish($1); DEL($3); } | yD_STOP parenE { $$ = new AstStop($1); } @@ -2586,22 +2586,22 @@ system_t_call: // IEEE: system_tf_call (as task) | yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); } | yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); } // - | yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); } - | yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); } - | yD_WRITE parenE { $$ = NULL; } // NOP - | yD_WRITE '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$3,NULL,$4); } - | yD_FDISPLAY '(' idClassSel ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"",$3,NULL); } - | yD_FDISPLAY '(' idClassSel ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$5,$3,$6); } - | yD_FWRITE '(' idClassSel ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$5,$3,$6); } - | yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, "", NULL,NULL); } - | yD_INFO '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, *$3,NULL,$4); } - | yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,"", NULL,NULL); } - | yD_WARNING '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,*$3,NULL,$4); } - | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); } - | yD_ERROR '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); } - | yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } - | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); DEL($3); } - | yD_FATAL '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); DEL($3); } + | yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); } + | yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); } + | yD_WRITE parenE { $$ = NULL; } // NOP + | yD_WRITE '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$3,NULL,$4); } + | yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"",$3,NULL); } + | yD_FDISPLAY '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$5,$3,$6); } + | yD_FWRITE '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$5,$3,$6); } + | yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, "", NULL,NULL); } + | yD_INFO '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, *$3,NULL,$4); } + | yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,"", NULL,NULL); } + | yD_WARNING '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,*$3,NULL,$4); } + | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); } + | yD_ERROR '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); } + | yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } + | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); DEL($3); } + | yD_FATAL '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); DEL($3); } // | yD_READMEMB '(' expr ',' idClassSel ')' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); } | yD_READMEMB '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); } diff --git a/test_regress/t/t_display_mcd.pl b/test_regress/t/t_display_mcd.pl new file mode 100755 index 000000000..13b318c77 --- /dev/null +++ b/test_regress/t/t_display_mcd.pl @@ -0,0 +1,27 @@ +#!/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, + expect=>quotemeta(dequote( +'To stdout +To stderr +*-* All Finished *-* +')), + ); + +ok(1); + +# Don't put control chars into our source repository, pre-compress instead +sub dequote { my $s = shift; $s =~ s/<#013>/\r/g; $s; } + +1; diff --git a/test_regress/t/t_display_mcd.v b/test_regress/t/t_display_mcd.v new file mode 100644 index 000000000..db3c3e143 --- /dev/null +++ b/test_regress/t/t_display_mcd.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Wilson Snyder. + +module t; + initial begin + $fwrite(32'h8000_0001, "To stdout\n"); + $fflush(32'h8000_0001); + $fwrite(32'h8000_0002, "To stderr\n"); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule