Add support for $test$plusargs(expr) (#3489)

This commit is contained in:
Arkadiusz Kozdra 2022-07-11 12:21:35 +02:00 committed by GitHub
parent d8ea989eda
commit 8377514127
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 32 additions and 23 deletions

View File

@ -10,6 +10,7 @@ Alex Chadwick
Aliaksei Chapyzhenka
Ameya Vikram Singh
Andreas Kuster
Arkadiusz Kozdra
Chris Randall
Chuxuan Wang
Conor McCullough

View File

@ -1606,8 +1606,8 @@ IData VL_SYSTEM_IW(int lhswords, const WDataInP lhsp) VL_MT_SAFE {
return code >> 8; // Want exit status
}
IData VL_TESTPLUSARGS_I(const char* formatp) VL_MT_SAFE {
const std::string& match = Verilated::threadContextp()->impp()->argPlusMatch(formatp);
IData VL_TESTPLUSARGS_I(const std::string& format) VL_MT_SAFE {
const std::string& match = Verilated::threadContextp()->impp()->argPlusMatch(format.c_str());
return match.empty() ? 0 : 1;
}

View File

@ -146,7 +146,7 @@ extern IData VL_SYSTEM_IW(int lhswords, WDataInP const lhsp);
extern IData VL_SYSTEM_IQ(QData lhs);
inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); }
extern IData VL_TESTPLUSARGS_I(const char* formatp);
extern IData VL_TESTPLUSARGS_I(const std::string& format);
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
//=========================================================================

View File

@ -4551,26 +4551,21 @@ public:
class AstTestPlusArgs final : public AstNodeMath {
// Parents: expr
// Child: variable to set. If nullptr then this is a $test$plusargs instead of $value$plusargs
private:
string m_text;
public:
AstTestPlusArgs(FileLine* fl, const string& text)
: ASTGEN_SUPER_TestPlusArgs(fl)
, m_text{text} {}
AstTestPlusArgs(FileLine* fl, AstNode* searchp)
: ASTGEN_SUPER_TestPlusArgs(fl) {
setOp1p(searchp);
}
ASTNODE_NODE_FUNCS(TestPlusArgs)
virtual string name() const override { return m_text; }
virtual string verilogKwd() const override { return "$test$plusargs"; }
virtual string emitVerilog() override { return verilogKwd(); }
virtual string emitC() override { return "VL_VALUEPLUSARGS_%nq(%lw, %P, nullptr)"; }
virtual bool isGateOptimizable() const override { return false; }
virtual bool isPredictOptimizable() const override { return false; }
virtual bool cleanOut() const override { return true; }
virtual bool same(const AstNode* samep) const override {
return text() == static_cast<const AstTestPlusArgs*>(samep)->text();
}
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text = text; }
virtual bool same(const AstNode* samep) const override { return true; }
AstNode* searchp() const { return op1p(); } // op1 = Search expression
void searchp(AstNode* nodep) { setOp1p(nodep); }
};
class AstGenFor final : public AstNodeFor {

View File

@ -581,7 +581,7 @@ public:
}
virtual void visit(AstTestPlusArgs* nodep) override {
puts("VL_TESTPLUSARGS_I(");
putsQuoted(nodep->text());
emitCvtPackStr(nodep->searchp());
puts(")");
}
virtual void visit(AstFError* nodep) override {

View File

@ -225,11 +225,6 @@ private:
m_hash += nodep->text();
});
}
virtual void visit(AstTestPlusArgs* nodep) override {
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
m_hash += nodep->text();
});
}
virtual void visit(AstAddrOfCFunc* nodep) override {
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
iterateNull(nodep->funcp());

View File

@ -210,6 +210,13 @@ private:
iterateAndNextNull(nodep->msbp());
}
}
virtual void visit(AstTestPlusArgs* nodep) override {
VL_RESTORER(m_setRefLvalue);
{
m_setRefLvalue = VAccess::NOCHANGE;
iterateAndNextNull(nodep->searchp());
}
}
virtual void visit(AstValuePlusArgs* nodep) override {
VL_RESTORER(m_setRefLvalue);
{

View File

@ -448,7 +448,6 @@ private:
// Widths: Constant, terminal
virtual void visit(AstTime* nodep) override { nodep->dtypeSetUInt64(); }
virtual void visit(AstTimeD* nodep) override { nodep->dtypeSetDouble(); }
virtual void visit(AstTestPlusArgs* nodep) override { nodep->dtypeSetSigned32(); }
virtual void visit(AstScopeName* nodep) override {
nodep->dtypeSetUInt64(); // A pointer, but not that it matters
}
@ -4350,6 +4349,12 @@ private:
userIterateAndNext(nodep->lsbp(), WidthVP(SELF, BOTH).p());
userIterateAndNext(nodep->msbp(), WidthVP(SELF, BOTH).p());
}
virtual void visit(AstTestPlusArgs* nodep) override {
if (m_vup->prelim()) {
userIterateAndNext(nodep->searchp(), WidthVP{SELF, BOTH}.p());
nodep->dtypeChgWidthSigned(32, 1, VSigning::SIGNED); // Spec says integer return
}
}
virtual void visit(AstValuePlusArgs* nodep) override {
if (m_vup->prelim()) {
userIterateAndNext(nodep->searchp(), WidthVP(SELF, BOTH).p());

View File

@ -3917,7 +3917,7 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or
| yD_STABLE '(' expr ',' expr ')' { $$ = $3; BBUNSUP($1, "Unsupported: $stable and clock arguments"); }
| yD_TAN '(' expr ')' { $$ = new AstTanD($1,$3); }
| yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); }
| yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); }
| yD_TESTPLUSARGS '(' expr ')' { $$ = new AstTestPlusArgs($1, $3); }
| yD_TIME parenE { $$ = new AstTime($1, VTimescale(VTimescale::NONE)); }
| yD_TYPENAME '(' exprOrDataType ')' { $$ = new AstAttrOf($1, VAttrType::TYPENAME, $3); }
| yD_UNGETC '(' expr ',' expr ')' { $$ = new AstFUngetC($1, $5, $3); } // Arg swap to file first

View File

@ -22,6 +22,12 @@ module t;
//if ($test$plusargs("")!==1) $stop; // Simulators differ in this answer
if ($test$plusargs("NOTTHERE")!==0) $stop;
sv_in = "PLUS";
`ifdef VERILATOR
if ($c1(0)) sv_in = "NEVER"; // Prevent constant propagation
`endif
if ($test$plusargs(sv_in)!==1) $stop;
p_i = 10;
if ($value$plusargs("NOTTHERE%d", p_i) !== 0) $stop;
if ($value$plusargs("NOTTHERE%0d", p_i) !== 0) $stop;