Support .

This commit is contained in:
Wilson Snyder 2011-11-20 02:01:48 -05:00
parent 9ab3bcdde3
commit b30b2a183b
10 changed files with 141 additions and 0 deletions

View File

@ -12,6 +12,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Support constants in sensitivity lists, bug412. [Jeremy Bennett]
**** Support $system. [Ruben Diez]
**** Support $sscanf with %g. [Holger Wächtler]
**** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez]

View File

@ -937,6 +937,17 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
}
}
IData VL_SYSTEM_IQ(QData lhs) {
IData lhsw[2]; VL_SET_WQ(lhsw, lhs);
return VL_SYSTEM_IW(2, lhsw);
}
IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(lhswords*VL_WORDSIZE, filenamez, filenamep);
int code = system(filenamez);
return code >> 8; // Want exit status
}
IData VL_TESTPLUSARGS_I(const char* formatp) {
string match = VerilatedImp::argPlusMatch(formatp);
if (match == "") return 0;

View File

@ -349,6 +349,10 @@ extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...);
extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs);
extern IData VL_SYSTEM_IQ(QData lhs);
inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); }
extern IData VL_TESTPLUSARGS_I(const char* formatp);
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish

View File

@ -1895,6 +1895,45 @@ public:
AstNode* msbp() const { return op4p()->castNode(); }
};
struct AstSystemT : public AstNodeStmt {
// $system used as task
AstSystemT(FileLine* fileline, AstNode* lhsp)
: AstNodeStmt (fileline) {
setOp1p(lhsp);
}
ASTNODE_NODE_FUNCS(SystemT, SYSTEMT)
virtual string verilogKwd() const { return "$system"; }
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* lhsp() const { return op1p(); }
};
struct AstSystemF : public AstNodeMath {
// $system used as function
AstSystemF(FileLine* fileline, AstNode* lhsp)
: AstNodeMath (fileline) {
setOp1p(lhsp);
}
ASTNODE_NODE_FUNCS(SystemF, SYSTEMF)
virtual string verilogKwd() const { return "$system"; }
virtual string emitVerilog() { return verilogKwd(); }
virtual string emitC() { return "VL_SYSTEM_%nq(%lw, %P)"; }
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 bool cleanOut() { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNode* lhsp() const { return op1p(); }
};
struct AstValuePlusArgs : public AstNodeMath {
// Parents: expr
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs

View File

@ -361,6 +361,30 @@ public:
puts(")); }\n");
}
}
virtual void visit(AstSystemT* nodep, AstNUser*) {
puts("(void)VL_SYSTEM_I");
emitIQW(nodep->lhsp());
puts("(");
if (nodep->lhsp()->isWide()) {
puts(cvtToStr(nodep->lhsp()->widthWords()));
putbs(", ");
}
checkMaxWords(nodep->lhsp());
nodep->lhsp()->iterateAndNext(*this);
puts(");\n");
}
virtual void visit(AstSystemF* nodep, AstNUser*) {
puts("VL_SYSTEM_I");
emitIQW(nodep->lhsp());
puts("(");
if (nodep->lhsp()->isWide()) {
puts(cvtToStr(nodep->lhsp()->widthWords()));
putbs(", ");
}
checkMaxWords(nodep->lhsp());
nodep->lhsp()->iterateAndNext(*this);
puts(")");
}
virtual void visit(AstJumpGo* nodep, AstNUser*) {
puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n");
}

View File

@ -1041,6 +1041,14 @@ private:
virtual void visit(AstSysIgnore* nodep, AstNUser* vup) {
nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
}
virtual void visit(AstSystemF* nodep, AstNUser*) {
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->numeric(AstNumeric::UNSIGNED);
nodep->width(32,32);
}
virtual void visit(AstSystemT* nodep, AstNUser*) {
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
}
virtual void visit(AstReadMem* nodep, AstNUser*) {
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());

View File

@ -215,6 +215,7 @@ word [a-zA-Z0-9_]+
"$stime" { FL; return yD_STIME; }
"$stop" { FL; return yD_STOP; }
"$swrite" { FL; return yD_SWRITE; }
"$system" { FL; return yD_SYSTEM; }
"$test$plusargs" { FL; return yD_TESTPLUSARGS; }
"$time" { FL; return yD_TIME; }
"$timeskew" { FL; return yaTIMINGSPEC; }

View File

@ -425,6 +425,7 @@ class AstSenTree;
%token<fl> yD_STIME "$stime"
%token<fl> yD_STOP "$stop"
%token<fl> yD_SWRITE "$swrite"
%token<fl> yD_SYSTEM "$system"
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
%token<fl> yD_TIME "$time"
%token<fl> yD_UNIT "$unit"
@ -2133,6 +2134,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
//
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| 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); }
@ -2184,6 +2186,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); }
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); }
| yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); }
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }

18
test_regress/t/t_sys_system.pl Executable file
View 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;

View File

@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t;
integer i;
initial begin
`ifndef VERILATOR
`ifndef VCS
`ifndef NC
$system(); // Legal per spec, but not supported everywhere and nonsensical
`endif
`endif
`endif
$system("exit 0");
$system("echo hello");
`ifndef VCS
i = $system("exit 0");
if (i!==0) $stop;
i = $system("exit 10");
if (i!==10) $stop;
`endif
$write("*-* All Finished *-*\n");
$finish;
end
endmodule