forked from github/verilator
Internals: Move PLI errors into linker, and better test.
This commit is contained in:
parent
6a882f9dc6
commit
57621a93ad
@ -2731,6 +2731,7 @@ private:
|
||||
string m_dotted; // Dotted part of scope the name()ed task/func is under or ""
|
||||
string m_inlinedDots; // Dotted hierarchy flattened out
|
||||
AstNodeModule* m_packagep; // Package hierarchy
|
||||
bool m_pli; // Pli system call ($name)
|
||||
public:
|
||||
AstNodeFTaskRef(AstType t, FileLine* fl, bool statement, AstNode* namep, AstNode* pinsp)
|
||||
: AstNodeStmt(t, fl, statement)
|
||||
@ -2767,6 +2768,8 @@ public:
|
||||
void dotted(const string& name) { m_dotted = name; }
|
||||
AstNodeModule* packagep() const { return m_packagep; }
|
||||
void packagep(AstNodeModule* nodep) { m_packagep = nodep; }
|
||||
bool pli() const { return m_pli; }
|
||||
void pli(bool flag) { m_pli = flag; }
|
||||
// op1 = namep
|
||||
AstNode* namep() const { return op1p(); }
|
||||
// op2 = reserved for AstMethodCall
|
||||
|
@ -2491,11 +2491,39 @@ private:
|
||||
} else if (VN_IS(nodep, New) && m_statep->forPrearray()) {
|
||||
// Resolved in V3Width
|
||||
} else if (nodep->dotted() == "") {
|
||||
string suggest = m_statep->suggestSymFallback(dotSymp, nodep->name(),
|
||||
LinkNodeMatcherFTask());
|
||||
nodep->v3error("Can't find definition of task/function: "
|
||||
<< nodep->prettyNameQ() << endl
|
||||
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
|
||||
if (nodep->pli()) {
|
||||
if (v3Global.opt.bboxSys()) {
|
||||
AstNode* newp;
|
||||
if (VN_IS(nodep, FuncRef)) {
|
||||
newp = new AstConst(nodep->fileline(), AstConst::StringToParse(),
|
||||
"'0");
|
||||
} else {
|
||||
AstNode* outp = NULL;
|
||||
while (nodep->pinsp()) {
|
||||
AstNode* pinp = nodep->pinsp()->unlinkFrBack();
|
||||
AstNode* addp = pinp;
|
||||
if (AstArg* argp = VN_CAST(pinp, Arg)) {
|
||||
addp = argp->exprp()->unlinkFrBack();
|
||||
VL_DO_DANGLING(pinp->deleteTree(), pinp);
|
||||
}
|
||||
outp = AstNode::addNext(outp, addp);
|
||||
}
|
||||
newp = new AstSysIgnore(nodep->fileline(), outp);
|
||||
}
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
return;
|
||||
} else {
|
||||
nodep->v3error("Unsupported or unknown PLI call: "
|
||||
<< nodep->prettyNameQ() << endl);
|
||||
}
|
||||
} else {
|
||||
string suggest = m_statep->suggestSymFallback(dotSymp, nodep->name(),
|
||||
LinkNodeMatcherFTask());
|
||||
nodep->v3error("Can't find definition of task/function: "
|
||||
<< nodep->prettyNameQ() << endl
|
||||
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
|
||||
}
|
||||
} else {
|
||||
string suggest = m_statep->suggestSymFallback(dotSymp, nodep->name(),
|
||||
LinkNodeMatcherFTask());
|
||||
|
@ -65,15 +65,20 @@ void V3ParseImp::parserClear() {
|
||||
//======================================================================
|
||||
// V3ParseGrammar functions requiring bison state
|
||||
|
||||
void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) {
|
||||
AstNode* V3ParseGrammar::argWrapList(AstNode* nodep) {
|
||||
// Convert list of expressions to list of arguments
|
||||
if (!nodep) return NULL;
|
||||
AstNode* outp = NULL;
|
||||
while (nodep->pinsp()) {
|
||||
AstNode* exprp = nodep->pinsp()->unlinkFrBack();
|
||||
AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
|
||||
while (nodep) {
|
||||
AstNode* nextp = nodep->nextp();
|
||||
AstNode* exprp = nodep->unlinkFrBack();
|
||||
nodep = nextp;
|
||||
// addNext can handle nulls:
|
||||
outp = AstNode::addNext(outp, new AstArg(exprp->fileline(), "", exprp));
|
||||
}
|
||||
if (outp) nodep->addPinsp(outp);
|
||||
VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
return outp;
|
||||
}
|
||||
|
||||
AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, const string& name, int value) {
|
||||
|
@ -44,10 +44,6 @@ extern void yyerrorf(const char* format, ...);
|
||||
|
||||
#define FL { FL_FWD; yylval.fl = CRELINE(); }
|
||||
|
||||
#define RETURN_BBOX_SYS_OR_MSG(msg,yytext) { \
|
||||
if (!v3Global.opt.bboxSys()) { yyerrorf(msg, yytext); FL_BRK; } \
|
||||
return yaD_IGNORE; }
|
||||
|
||||
#define ERROR_RSVD_WORD(language) \
|
||||
do { FL_FWD; \
|
||||
yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \
|
||||
@ -601,10 +597,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
<V95,V01,V05,VA5,S05,S09,S12,S17,SAX>{
|
||||
"$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext, yyleng);
|
||||
yylval.strp = PARSEP->newString(AstNode::encodeName(str));
|
||||
// Lookup unencoded name including the $, to avoid hitting normal signals
|
||||
if (SYMP->symCurrentp()->findIdFallback(str)) {
|
||||
FL; return yaD_DPI;
|
||||
} else { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported or unknown PLI call: %s", yytext); }
|
||||
FL; return yaD_PLI;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
}
|
||||
|
||||
// METHODS
|
||||
void argWrapList(AstNodeFTaskRef* nodep);
|
||||
AstNode* argWrapList(AstNode* nodep);
|
||||
bool allTracingOn(FileLine* fl) {
|
||||
return v3Global.opt.trace() && m_tracingParse && fl->tracingOn();
|
||||
}
|
||||
@ -311,8 +311,7 @@ class AstSenTree;
|
||||
%token<fl> yVLT_D_TASK "--task"
|
||||
%token<fl> yVLT_D_VAR "--var"
|
||||
|
||||
%token<strp> yaD_IGNORE "${ignored-bbox-sys}"
|
||||
%token<strp> yaD_DPI "${dpi-sys}"
|
||||
%token<strp> yaD_PLI "${pli-system}"
|
||||
|
||||
%token<fl> yaT_RESETALL "`resetall"
|
||||
|
||||
@ -3264,12 +3263,7 @@ function_subroutine_callNoMethod<nodep>: // IEEE: function_subroutine_call (as f
|
||||
|
||||
system_t_call<nodep>: // IEEE: system_tf_call (as task)
|
||||
//
|
||||
yaD_IGNORE parenE { $$ = new AstSysIgnore($<fl>1,NULL); }
|
||||
| yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($<fl>1,$3); }
|
||||
//
|
||||
| yaD_DPI parenE { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
|
||||
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($<fl>1, *$1, $3);
|
||||
GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); }
|
||||
yaD_PLI systemDpiArgsE { $$ = new AstTaskRef($<fl>1, *$1, $2); VN_CAST($$, TaskRef)->pli(true); }
|
||||
//
|
||||
| yD_DUMPPORTS '(' idDotted ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $5); DEL($3);
|
||||
$$->addNext(new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
|
||||
@ -3369,11 +3363,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
|
||||
;
|
||||
|
||||
system_f_call<nodep>: // IEEE: system_tf_call (as func)
|
||||
yaD_IGNORE parenE { $$ = new AstConst($<fl>1, AstConst::StringToParse(), "'b0"); } // Unsized 0
|
||||
| yaD_IGNORE '(' exprList ')' { $$ = new AstConst($<fl>1, AstConst::StringToParse(), "'b0"); } // Unsized 0
|
||||
//
|
||||
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
|
||||
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($<fl>1,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); }
|
||||
yaD_PLI systemDpiArgsE { $$ = new AstFuncRef($<fl>1, *$1, $2); VN_CAST($$, FuncRef)->pli(true); }
|
||||
//
|
||||
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
|
||||
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
|
||||
@ -3381,6 +3371,11 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
|
||||
| system_f_call_or_t { $$ = $1; }
|
||||
;
|
||||
|
||||
systemDpiArgsE<nodep>: // IEEE: part of system_if_call for aruments of $dpi call
|
||||
parenE { $$ = NULL; }
|
||||
| '(' exprList ')' { $$ = GRAMMARP->argWrapList($2); }
|
||||
;
|
||||
|
||||
system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
|
||||
yD_ACOS '(' expr ')' { $$ = new AstAcosD($1,$3); }
|
||||
| yD_ACOSH '(' expr ')' { $$ = new AstAcoshD($1,$3); }
|
||||
|
13
test_regress/t/t_pli_bad.out
Normal file
13
test_regress/t/t_pli_bad.out
Normal file
@ -0,0 +1,13 @@
|
||||
%Error: t/t_pli_bad.v:10:7: Unsupported or unknown PLI call: '$unknown_pli_task'
|
||||
10 | $unknown_pli_task;
|
||||
| ^~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_pli_bad.v:11:7: Unsupported or unknown PLI call: '$unknown_pli_task'
|
||||
11 | $unknown_pli_task("arg", i);
|
||||
| ^~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_pli_bad.v:12:11: Unsupported or unknown PLI call: '$unknown_pli_function'
|
||||
12 | i = $unknown_pli_function;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_pli_bad.v:13:11: Unsupported or unknown PLI call: '$unknown_pli_function'
|
||||
13 | i = $unknown_pli_function("arg", i);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
20
test_regress/t/t_pli_bad.pl
Executable file
20
test_regress/t/t_pli_bad.pl
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
||||
1;
|
16
test_regress/t/t_pli_bad.v
Normal file
16
test_regress/t/t_pli_bad.v
Normal file
@ -0,0 +1,16 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2019 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
integer i;
|
||||
initial begin
|
||||
$unknown_pli_task;
|
||||
$unknown_pli_task("arg", i);
|
||||
i = $unknown_pli_function;
|
||||
i = $unknown_pli_function("arg", i);
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
21
test_regress/t/t_pli_bbox.pl
Executable file
21
test_regress/t/t_pli_bbox.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
top_filename("t/t_pli_bad.v");
|
||||
|
||||
lint(
|
||||
verilator_flags2 => ["--bbox-sys"],
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user