DPI: Constify new $sformatf
This commit is contained in:
parent
72b596efb3
commit
27e4503dc6
|
|
@ -83,6 +83,34 @@ public:
|
|||
virtual int instrCount() const { return widthInstrs(); }
|
||||
};
|
||||
|
||||
struct AstConstString : public AstNodeMath {
|
||||
// A constant string
|
||||
private:
|
||||
string m_name;
|
||||
public:
|
||||
AstConstString(FileLine* fl, const string& name)
|
||||
: AstNodeMath(fl), m_name(name) {
|
||||
rewidth();
|
||||
}
|
||||
void rewidth() {
|
||||
if (m_name.length()==0) {
|
||||
width(1,1); // 0 width isn't allowed due to historic special cases
|
||||
} else {
|
||||
width(m_name.length()*8, m_name.length()*8);
|
||||
}
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ConstString, CONSTSTRING)
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(name()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return name()==samep->castConstString()->name(); }
|
||||
virtual int instrCount() const { return 2; } // C just loads a pointer
|
||||
virtual string name() const { return m_name; }
|
||||
void name(const string& flag) { m_name = flag; rewidth(); }
|
||||
};
|
||||
|
||||
struct AstRange : public AstNode {
|
||||
// Range specification, for use under variables and cells
|
||||
private:
|
||||
|
|
@ -1511,10 +1539,12 @@ public:
|
|||
|
||||
class AstSFormatF : public AstNode {
|
||||
// Convert format to string, generally under a AstDisplay or AstSFormat
|
||||
// Also used as "real" function for /*verilator sformat*/ functions
|
||||
string m_text;
|
||||
bool m_hidden; // Under display, etc
|
||||
public:
|
||||
AstSFormatF(FileLine* fl, const string& text, AstNode* exprsp)
|
||||
: AstNode(fl), m_text(text) {
|
||||
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp)
|
||||
: AstNode(fl), m_text(text), m_hidden(hidden) {
|
||||
addNOp1p(exprsp); addNOp2p(NULL); }
|
||||
ASTNODE_NODE_FUNCS(SFormatF, SFORMATF)
|
||||
virtual string name() const { return m_text; }
|
||||
|
|
@ -1530,6 +1560,7 @@ public:
|
|||
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
|
||||
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
|
||||
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
|
||||
bool hidden() const { return m_hidden; }
|
||||
};
|
||||
|
||||
struct AstDisplay : public AstNode {
|
||||
|
|
@ -1541,7 +1572,7 @@ private:
|
|||
public:
|
||||
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
|
||||
: AstNode (fileline) {
|
||||
setNOp1p(new AstSFormatF(fileline,text,exprsp));
|
||||
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
|
||||
setNOp3p(filep);
|
||||
m_displayType = dispType;
|
||||
}
|
||||
|
|
@ -1573,7 +1604,7 @@ struct AstSFormat : public AstNode {
|
|||
// Children: SFORMATF to generate print string
|
||||
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
|
||||
: AstNode (fileline) {
|
||||
setOp1p(new AstSFormatF(fileline,text,exprsp));
|
||||
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
|
||||
setOp3p(lhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(SFormat, SFORMAT)
|
||||
|
|
|
|||
|
|
@ -432,6 +432,15 @@ private:
|
|||
replaceNum(nodep, num); nodep=NULL;
|
||||
}
|
||||
|
||||
void replaceConstString (AstNode* oldp, const string& num) {
|
||||
// Replace oldp node with a constant set to specified value
|
||||
UASSERT (oldp, "Null old\n");
|
||||
AstNode* newp = new AstConstString(oldp->fileline(), num);
|
||||
if (debug()>5) oldp->dumpTree(cout," const_old: ");
|
||||
if (debug()>5) newp->dumpTree(cout," _new: ");
|
||||
oldp->replaceWith(newp);
|
||||
oldp->deleteTree(); oldp=NULL;
|
||||
}
|
||||
//----------------------------------------
|
||||
// Replacement functions.
|
||||
// These all take a node and replace it with something else
|
||||
|
|
@ -1459,6 +1468,12 @@ private:
|
|||
nodep->text(dispout);
|
||||
//UINFO(9," Display out "<<nodep->text()<<endl);
|
||||
}
|
||||
if (!nodep->exprsp()
|
||||
&& nodep->name().find("%") == string::npos
|
||||
&& !nodep->hidden()) {
|
||||
// Just a simple constant string - the formatting is pointless
|
||||
replaceConstString(nodep, nodep->name()); nodep=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstFuncRef* nodep, AstNUser*) {
|
||||
|
|
@ -1712,6 +1727,9 @@ private:
|
|||
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
|
||||
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
|
||||
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
|
||||
// Strings
|
||||
TREEOP ("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())");
|
||||
|
||||
|
||||
// Possible futures:
|
||||
// (a?(b?y:x):y) -> (a&&!b)?x:y
|
||||
|
|
|
|||
|
|
@ -563,6 +563,9 @@ public:
|
|||
emitConstant(nodep, NULL, "");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConstString* nodep, AstNUser*) {
|
||||
putsQuoted(nodep->name());
|
||||
}
|
||||
|
||||
// Just iterate
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
|
|
|
|||
|
|
@ -456,6 +456,10 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
putfs(nodep,nodep->num().ascii(true,true));
|
||||
}
|
||||
virtual void visit(AstConstString* nodep, AstNUser*) {
|
||||
putfs(nodep,"");
|
||||
putsQuoted(nodep->name());
|
||||
}
|
||||
|
||||
// Just iterate
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
|
|
|
|||
|
|
@ -448,6 +448,9 @@ private:
|
|||
// We don't size the constant until we commit the widths, as need parameters
|
||||
// to remain unsized, and numbers to remain unsized to avoid backp() warnings
|
||||
}
|
||||
virtual void visit(AstConstString* nodep, AstNUser* vup) {
|
||||
nodep->rewidth();
|
||||
}
|
||||
virtual void visit(AstRand* nodep, AstNUser* vup) {
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->width(32,32); // Says the spec
|
||||
|
|
@ -962,7 +965,7 @@ private:
|
|||
string format;
|
||||
if (pinp->castConst()) format = pinp->castConst()->num().toString();
|
||||
else pinp->v3error("Format to $display-like function must have constant format string");
|
||||
AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, argsp);
|
||||
AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp);
|
||||
if (!newp->scopeNamep() && newp->formatScopeTracking()) {
|
||||
newp->scopeNamep(new AstScopeName(newp->fileline()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2066,7 +2066,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
|
|||
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
|
||||
| yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
|
||||
| yD_RANDOM parenE { $$ = new AstRand($1); }
|
||||
//| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,$4); } // Have AST, just need testing and debug
|
||||
//| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,false,$4); } // Have AST, just need testing and debug
|
||||
| yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); }
|
||||
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
|
||||
| yD_TIME parenE { $$ = new AstTime($1); }
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ module t ();
|
|||
|
||||
bit [127:0] wide;
|
||||
|
||||
bit [6*8:1] string6;
|
||||
|
||||
initial begin
|
||||
wide = 128'h36f3e51d15caff7a73c48afee4ffcb57;
|
||||
|
||||
|
|
@ -165,6 +167,11 @@ module t ();
|
|||
if (dpii_f_strlen ("stri")!=4) $stop;
|
||||
if (dpii_f_strlen ("string_l")!=8) $stop;
|
||||
if (dpii_f_strlen ("string_len")!=10) $stop;
|
||||
string6 = "hello6";
|
||||
`ifdef VERILATOR
|
||||
string6 = $c48(string6); // Don't optimize away - want to see the constant conversion function
|
||||
`endif
|
||||
if (dpii_f_strlen (string6) != 6) $stop;
|
||||
|
||||
dpii_f_void();
|
||||
dpii_t_void();
|
||||
|
|
|
|||
Loading…
Reference in New Issue