Add support

This commit is contained in:
Wilson Snyder 2008-06-27 08:45:05 -04:00
parent 8afd19648f
commit fdcbedef8f
11 changed files with 59 additions and 2 deletions

View File

@ -5,7 +5,7 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.66* * Verilator 3.66*
*** Support $feof. [Holger Waechtler] *** Support $feof, $fflush. [Holger Waechtler]
* Verilator 3.665 2008/06/25 * Verilator 3.665 2008/06/25

View File

@ -1554,7 +1554,7 @@ them with a $write with the appropriate format specifier.
The rarely used optional parameter to $finish and $stop is ignored. The rarely used optional parameter to $finish and $stop is ignored.
=item $fopen, $fclose, $fdisplay, $feof, $fwrite =item $fopen, $fclose, $fdisplay, $feof, $fflush, $fwrite
File descriptors passed to the file PLI calls must be file descriptors, not File descriptors passed to the file PLI calls must be file descriptors, not
MCDs, which includes the mode parameter to $fopen being mandatory. MCDs, which includes the mode parameter to $fopen being mandatory.

View File

@ -1323,6 +1323,29 @@ struct AstFOpen : public AstNodeStmt {
AstNode* modep() const { return op3p(); } AstNode* modep() const { return op3p(); }
}; };
struct AstFFlush : public AstNodeStmt {
// Parents: stmtlist
// Children: file which must be a varref
AstFFlush(FileLine* fileline, AstNode* filep)
: AstNodeStmt (fileline) {
setNOp2p(filep);
}
virtual ~AstFFlush() {}
virtual AstType type() const { return AstType::FFLUSH;}
virtual AstNode* clone() { return new AstFFlush(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return "$fflush"; };
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isSplittable() const { return false; }
virtual bool isOutputter() const { return true; }
virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
};
struct AstReadMem : public AstNodeStmt { struct AstReadMem : public AstNodeStmt {
private: private:
bool m_isHex; // readmemh, not readmemb bool m_isHex; // readmemh, not readmemb

View File

@ -299,6 +299,13 @@ public:
nodep->filep()->iterateAndNext(*this); nodep->filep()->iterateAndNext(*this);
puts(")) : true)"); // Non-existant filehandle should return EOF puts(")) : true)"); // Non-existant filehandle should return EOF
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
puts("if (");
nodep->filep()->iterateAndNext(*this);
puts(") { fflush (VL_CVT_Q_FP(");
nodep->filep()->iterateAndNext(*this);
puts(")); ");
}
virtual void visit(AstWhile* nodep, AstNUser*) { virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->precondsp()->iterateAndNext(*this); nodep->precondsp()->iterateAndNext(*this);
puts("while ("); puts("while (");

View File

@ -192,6 +192,12 @@ public:
if (nodep->filep()) nodep->filep()->iterateChildren(*this); if (nodep->filep()) nodep->filep()->iterateChildren(*this);
puts(");\n"); puts(");\n");
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
putbs(nodep->verilogKwd());
putbs(" (");
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
puts(");\n");
}
virtual void visit(AstReadMem* nodep, AstNUser*) { virtual void visit(AstReadMem* nodep, AstNUser*) {
putbs(nodep->verilogKwd()); putbs(nodep->verilogKwd());
putbs(" ("); putbs(" (");

View File

@ -108,6 +108,14 @@ private:
} }
m_setRefLvalue = last_setRefLvalue; m_setRefLvalue = last_setRefLvalue;
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
bool last_setRefLvalue = m_setRefLvalue;
{
m_setRefLvalue = true;
nodep->filep()->iterateAndNext(*this);
}
m_setRefLvalue = last_setRefLvalue;
}
virtual void visit(AstReadMem* nodep, AstNUser*) { virtual void visit(AstReadMem* nodep, AstNUser*) {
bool last_setRefLvalue = m_setRefLvalue; bool last_setRefLvalue = m_setRefLvalue;
{ {

View File

@ -328,6 +328,10 @@ private:
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
}
virtual void visit(AstDisplay* nodep, AstNUser*) { virtual void visit(AstDisplay* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());

View File

@ -574,6 +574,9 @@ private:
nodep->lhsp()->iterateAndNext(*this,WidthVP(64,64,BOTH).p()); nodep->lhsp()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
nodep->width(1,1); nodep->width(1,1);
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
}
virtual void visit(AstReadMem* nodep, AstNUser*) { virtual void visit(AstReadMem* nodep, AstNUser*) {
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());

View File

@ -133,6 +133,7 @@ escid \\[^ \t\f\r\n]+
"$fclose" {yylval.fileline = CRELINE(); return yD_FCLOSE;} "$fclose" {yylval.fileline = CRELINE(); return yD_FCLOSE;}
"$fdisplay" {yylval.fileline = CRELINE(); return yD_FDISPLAY;} "$fdisplay" {yylval.fileline = CRELINE(); return yD_FDISPLAY;}
"$feof" {yylval.fileline = CRELINE(); return yD_FEOF;} "$feof" {yylval.fileline = CRELINE(); return yD_FEOF;}
"$fflush" {yylval.fileline = CRELINE(); return yD_FFLUSH;}
"$finish" {yylval.fileline = CRELINE(); return yD_FINISH;} "$finish" {yylval.fileline = CRELINE(); return yD_FINISH;}
"$fopen" {yylval.fileline = CRELINE(); return yD_FOPEN;} "$fopen" {yylval.fileline = CRELINE(); return yD_FOPEN;}
"$fullskew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;} "$fullskew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}

View File

@ -227,6 +227,7 @@ class AstSenTree;
%token<fileline> yD_FCLOSE "$fclose" %token<fileline> yD_FCLOSE "$fclose"
%token<fileline> yD_FDISPLAY "$fdisplay" %token<fileline> yD_FDISPLAY "$fdisplay"
%token<fileline> yD_FEOF "$feof" %token<fileline> yD_FEOF "$feof"
%token<fileline> yD_FFLUSH "$fflush"
%token<fileline> yD_FINISH "$finish" %token<fileline> yD_FINISH "$finish"
%token<fileline> yD_FOPEN "$fopen" %token<fileline> yD_FOPEN "$fopen"
%token<fileline> yD_FWRITE "$fwrite" %token<fileline> yD_FWRITE "$fwrite"
@ -896,6 +897,9 @@ stmt: ';' { $$ = NULL; }
| '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); } | '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); }
| yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); } | yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); } | yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); }
| yD_FFLUSH ';' { $1->v3error("Unsupported: $fflush of all handles does not map to C++.\n"); }
| yD_FFLUSH '(' ')' ';' { $1->v3error("Unsupported: $fflush of all handles does not map to C++.\n"); }
| yD_FFLUSH '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); }
| yD_FINISH parenE ';' { $$ = new AstFinish($1); } | yD_FINISH parenE ';' { $$ = new AstFinish($1); }
| yD_FINISH '(' expr ')' ';' { $$ = new AstFinish($1); } | yD_FINISH '(' expr ')' ';' { $$ = new AstFinish($1); }
| yD_STOP parenE ';' { $$ = new AstStop($1); } | yD_STOP parenE ';' { $$ = new AstStop($1); }

View File

@ -21,6 +21,7 @@ module t;
$fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667); $fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667);
$fwrite(file, "[%0t] %s\n", $time, "Hello2"); $fwrite(file, "[%0t] %s\n", $time, "Hello2");
$fflush(file);
$fclose(file); $fclose(file);
`ifdef verilator `ifdef verilator