forked from github/verilator
Support task name in $display %m (#3211).
This commit is contained in:
parent
cd737065f2
commit
c6dae40cf6
1
Changes
1
Changes
@ -19,6 +19,7 @@ Verilator 4.215 devel
|
||||
|
||||
* Internal code cleanups and improvements. [Geza Lore]
|
||||
* Improve --thread verilation-time performance.
|
||||
* Support task name in $display %m (#3211). [Julie Schwartz]
|
||||
* Fix array method names with parenthesis (#3181) (#3183). [Teng Huang]
|
||||
* Fix split_var assign merging (#3177) (#3179). [Yutetsu TAKATSUKASA]
|
||||
* Fix nested generate if genblk naming (#3189). [yanx21]
|
||||
|
@ -62,7 +62,7 @@ private:
|
||||
}
|
||||
nodep->fmtp()->addExprsp(timenewp);
|
||||
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
|
||||
nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
nodep->fmtp()->scopeNamep(new AstScopeName{nodep->fileline(), true});
|
||||
}
|
||||
}
|
||||
AstVarRef* newMonitorNumVarRefp(AstNode* nodep, VAccess access) {
|
||||
|
@ -1700,6 +1700,11 @@ void AstScope::dump(std::ostream& str) const {
|
||||
str << " [cellp=" << reinterpret_cast<const void*>(aboveCellp()) << "]";
|
||||
str << " [modp=" << reinterpret_cast<const void*>(modp()) << "]";
|
||||
}
|
||||
void AstScopeName::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (dpiExport()) str << " [DPIEX]";
|
||||
if (forFormat()) str << " [FMT]";
|
||||
}
|
||||
void AstSenTree::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (isMulti()) str << " [MULTI]";
|
||||
|
@ -5379,21 +5379,26 @@ class AstScopeName final : public AstNodeMath {
|
||||
// Children: TEXT
|
||||
private:
|
||||
bool m_dpiExport = false; // Is for dpiExport
|
||||
const bool m_forFormat = false; // Is for a format %m
|
||||
string scopeNameFormatter(AstText* scopeTextp) const;
|
||||
string scopePrettyNameFormatter(AstText* scopeTextp) const;
|
||||
|
||||
public:
|
||||
explicit AstScopeName(FileLine* fl)
|
||||
: ASTGEN_SUPER_ScopeName(fl) {
|
||||
class ForFormat {};
|
||||
AstScopeName(FileLine* fl, bool forFormat)
|
||||
: ASTGEN_SUPER_ScopeName(fl)
|
||||
, m_forFormat{forFormat} {
|
||||
dtypeSetUInt64();
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ScopeName)
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
return m_dpiExport == static_cast<const AstScopeName*>(samep)->m_dpiExport;
|
||||
return (m_dpiExport == static_cast<const AstScopeName*>(samep)->m_dpiExport
|
||||
&& m_forFormat == static_cast<const AstScopeName*>(samep)->m_forFormat);
|
||||
}
|
||||
virtual string emitVerilog() override { return ""; }
|
||||
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
virtual bool cleanOut() const override { return true; }
|
||||
virtual void dump(std::ostream& str = std::cout) const override;
|
||||
AstText* scopeAttrp() const { return VN_AS(op1p(), Text); }
|
||||
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstText* scopeEntrp() const { return VN_AS(op2p(), Text); }
|
||||
@ -5412,6 +5417,7 @@ public:
|
||||
}
|
||||
bool dpiExport() const { return m_dpiExport; }
|
||||
void dpiExport(bool flag) { m_dpiExport = flag; }
|
||||
bool forFormat() const { return m_forFormat; }
|
||||
};
|
||||
|
||||
class AstUdpTable final : public AstNode {
|
||||
|
@ -63,6 +63,7 @@ private:
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp
|
||||
string m_displayScope; // Name of %m in $display/AstScopeName
|
||||
string m_namedScope; // Name of begin blocks above us
|
||||
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
|
||||
int m_ifDepth = 0; // Current if depth
|
||||
@ -111,9 +112,11 @@ private:
|
||||
// naming; so that any begin's inside the function will rename
|
||||
// inside the function.
|
||||
// Process children
|
||||
VL_RESTORER(m_displayScope);
|
||||
VL_RESTORER(m_namedScope);
|
||||
VL_RESTORER(m_unnamedScope);
|
||||
{
|
||||
m_displayScope = dot(m_displayScope, nodep->name());
|
||||
m_namedScope = "";
|
||||
m_unnamedScope = "";
|
||||
m_ftaskp = nodep;
|
||||
@ -134,6 +137,7 @@ private:
|
||||
virtual void visit(AstBegin* nodep) override {
|
||||
// Begin blocks were only useful in variable creation, change names and delete
|
||||
UINFO(8, " " << nodep << endl);
|
||||
VL_RESTORER(m_displayScope);
|
||||
VL_RESTORER(m_namedScope);
|
||||
VL_RESTORER(m_unnamedScope);
|
||||
{
|
||||
@ -145,7 +149,10 @@ private:
|
||||
while ((pos = dottedname.find("__DOT__")) != string::npos) {
|
||||
const string ident = dottedname.substr(0, pos);
|
||||
dottedname = dottedname.substr(pos + strlen("__DOT__"));
|
||||
if (nodep->name() != "") m_namedScope = dot(m_namedScope, ident);
|
||||
if (nodep->name() != "") {
|
||||
m_displayScope = dot(m_displayScope, ident);
|
||||
m_namedScope = dot(m_namedScope, ident);
|
||||
}
|
||||
m_unnamedScope = dot(m_unnamedScope, ident);
|
||||
// Create CellInline for dotted var resolution
|
||||
if (!m_ftaskp) {
|
||||
@ -220,11 +227,13 @@ private:
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Inline
|
||||
if (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
if (m_namedScope != "") {
|
||||
// DPI svGetScope doesn't include function name, but %m does
|
||||
const string scname = nodep->forFormat() ? m_displayScope : m_namedScope;
|
||||
if (!scname.empty()) {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* const afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), string("__DOT__") + m_namedScope));
|
||||
nodep->scopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname});
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
|
@ -136,12 +136,12 @@ private:
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
m_ftaskp = nullptr;
|
||||
if (nodep->dpiExport()) nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
if (nodep->dpiExport()) nodep->scopeNamep(new AstScopeName{nodep->fileline(), false});
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->taskp() && (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) {
|
||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
nodep->scopeNamep(new AstScopeName{nodep->fileline(), false});
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,7 +459,7 @@ private:
|
||||
if ((VN_IS(nodep->backp(), Display)
|
||||
&& VN_AS(nodep->backp(), Display)->displayType().needScopeTracking())
|
||||
|| nodep->formatScopeTracking()) {
|
||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
nodep->scopeNamep(new AstScopeName{nodep->fileline(), true});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4493,7 +4493,7 @@ private:
|
||||
AstSFormatF* const newp
|
||||
= new AstSFormatF(nodep->fileline(), format, false, argsp);
|
||||
if (!newp->scopeNamep() && newp->formatScopeTracking()) {
|
||||
newp->scopeNamep(new AstScopeName(newp->fileline()));
|
||||
newp->scopeNamep(new AstScopeName{newp->fileline(), true});
|
||||
}
|
||||
handle.relink(new AstArg(newp->fileline(), "", newp));
|
||||
// Connection list is now incorrect (has extra args in it).
|
||||
|
@ -92,12 +92,10 @@ module t (/*AUTOARG*/);
|
||||
c = new;
|
||||
|
||||
s = mod_func_name();
|
||||
`checks(s, "tmf top.t");
|
||||
// UNSUP `checks(s, "tmf top.t.mod_func_name");
|
||||
`checks(s, "tmf top.t.mod_func_name");
|
||||
|
||||
s = unit_name();
|
||||
`checks(s, "u top.$unit");
|
||||
// UNSUP `checks(s, "u top.$unit.unit_name");
|
||||
`checks(s, "u top.$unit.unit_name");
|
||||
// Others: "u $unit_????::unit_name
|
||||
// Others: "u $unit::unit_name
|
||||
// Others: "u \\package UnitScopePackage_1\ .UnitScopePackage_1.unit_name
|
||||
@ -105,14 +103,12 @@ module t (/*AUTOARG*/);
|
||||
// *** Below results vary with simulator.
|
||||
|
||||
s = Cls::static_name();
|
||||
`checks(s, "c top.$unit.Cls");
|
||||
// UNSUP `checks(s, "c top.$unit.Cls.static_name");
|
||||
`checks(s, "c top.$unit.Cls.static_name");
|
||||
// Others: "c $unit_????.Cls.static_name
|
||||
// Others: "c $unit::\Cls::static_name
|
||||
// Others: "c Cls.static_name
|
||||
s = c.c_auto_name();
|
||||
`checks(s, "c top.$unit.Cls");
|
||||
// UNSUP `checks(s, "c top.$unit.Cls.c_auto_name");
|
||||
`checks(s, "c top.$unit.Cls.c_auto_name");
|
||||
// Others: "c $unit_????.Cls.c_auto_name
|
||||
// Others: "c $unit::\Cls::c_auto_name
|
||||
// Others: "c Cls.c_auto_name
|
||||
@ -126,33 +122,28 @@ module t (/*AUTOARG*/);
|
||||
// Others: "p \\package P\ .Cls.static_name
|
||||
|
||||
s = p.p_auto_name();
|
||||
`checks(s, "p top.P.Cls");
|
||||
// UNSUP `checks(s, "p top.P.Cls.p_auto_name");
|
||||
`checks(s, "p top.P.Cls.p_auto_name");
|
||||
// Others: "p P.Cls.p_auto_name
|
||||
// Others: "p P::Cls.p_auto_name
|
||||
// Others: "p P::\Cls::p_auto_name
|
||||
// Others: "p \\package P\ .Cls.p_auto_name
|
||||
|
||||
s = m.cls_static_name();
|
||||
`checks(s, "m top.t.m.Cls");
|
||||
// UNSUP `checks(s, "m top.t.m.Cls.static_name");
|
||||
`checks(s, "m top.t.m.Cls.static_name");
|
||||
// Others: "m top.t.m.Cls.static_name
|
||||
// Others: "m top.t.m.\Cls::static_name
|
||||
|
||||
s = m.cls_auto_name();
|
||||
`checks(s, "m top.t.m.Cls");
|
||||
// UNSUP `checks(s, "m top.t.m.Cls.m_auto_name");
|
||||
`checks(s, "m top.t.m.Cls.m_auto_name");
|
||||
// Others: "m top.t.m.Cls.m_auto_name
|
||||
// Others: "m top.t.m.\Cls::m_auto_name
|
||||
|
||||
s = m.sub.cls_static_name();
|
||||
`checks(s, "ms top.t.m.sub.Cls");
|
||||
// UNSUP `checks(s, "ms top.t.m.sub.Cls.static_name");
|
||||
`checks(s, "ms top.t.m.sub.Cls.static_name");
|
||||
// Others: "ms top.t.m.sub.Cls.static_name
|
||||
// Others: "ms top.t.m.sub.\Cls::static_name
|
||||
s = m.sub.cls_auto_name();
|
||||
`checks(s, "ms top.t.m.sub.Cls");
|
||||
// UNSUP `checks(s, "ms top.t.m.sub.Cls.ms_auto_name");
|
||||
`checks(s, "ms top.t.m.sub.Cls.ms_auto_name");
|
||||
// Others: "ms top.t.m.sub.Cls.ms_auto_name
|
||||
// Others: "ms top.t.m.sub.\Cls::ms_auto_name
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
[0] In top.t: Hi
|
||||
[0] In top.t.sub (sub)
|
||||
[0] In top.t.sub.subblock (sub)
|
||||
[0] In top.t.sub2 (sub2)
|
||||
[0] In top.t.sub2.subblock2 (sub2)
|
||||
[0] In top.t.sub.write_m (sub)
|
||||
[0] In top.t.sub.write_m.subblock (sub)
|
||||
[0] In top.t.sub2.write_m (sub2)
|
||||
[0] In top.t.sub2.write_m.subblock2 (sub2)
|
||||
[0] Back \ Quote "
|
||||
[0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000
|
||||
[0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000
|
||||
|
@ -15,13 +15,22 @@
|
||||
|
||||
//======================================================================
|
||||
|
||||
#ifdef VERILATOR
|
||||
#include "Vt_dpi_qw__Dpi.h"
|
||||
#else
|
||||
extern "C" {
|
||||
extern void set_value(const svBitVecVal* v);
|
||||
extern void poke_value(int i);
|
||||
}
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
|
||||
// Called from our Verilog code to run the tests
|
||||
void poke_value(int i) {
|
||||
printf("poke_value(%d)\n", i);
|
||||
const char* const scopeNamep = svGetNameFromScope(svGetScope());
|
||||
printf("svGetNameFromScope=\"%s\"\n", scopeNamep);
|
||||
|
||||
// clang-format off
|
||||
#ifdef VERILATOR
|
||||
@ -34,7 +43,7 @@ void poke_value(int i) {
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
svScope scope = svGetScopeFromName("top.t.a");
|
||||
const svScope scope = svGetScopeFromName("top.t.a");
|
||||
if (scope == NULL) {
|
||||
printf("%%Error: null scope for top.t.a\n");
|
||||
return;
|
||||
|
@ -4,6 +4,6 @@ b2: {mod} top.t.unnamedblk2
|
||||
b3n: {mod}.b3named: top.t.unnamedblk2.b3named
|
||||
b3: {mod} top.t.unnamedblk2.unnamedblk3
|
||||
b4: {mod} top.t.unnamedblk2.unnamedblk3.unnamedblk4
|
||||
t1 {mod}.tsk top.t
|
||||
t2 {mod}.tsk top.t.unnamedblk7
|
||||
t1 {mod}.tsk top.t.tsk
|
||||
t2 {mod}.tsk top.t.tsk.unnamedblk7
|
||||
*-* All Finished *-*
|
||||
|
Loading…
Reference in New Issue
Block a user