forked from github/verilator
parent
8a347248f5
commit
038d57070b
@ -1273,6 +1273,22 @@ public:
|
||||
bool cleanOut() const override { return true; }
|
||||
bool same(const AstNode* /*samep*/) const override { return true; }
|
||||
};
|
||||
class AstThisRef final : public AstNodeMath {
|
||||
// Reference to 'this'.
|
||||
// @astgen op1 := childDTypep : Optional[AstClassRefDType] // dtype of the node
|
||||
public:
|
||||
explicit AstThisRef(FileLine* fl, AstClassRefDType* dtypep)
|
||||
: ASTGEN_SUPER_ThisRef(fl) {
|
||||
childDTypep(dtypep);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstThisRef;
|
||||
string emitC() override { return "this"; }
|
||||
string emitVerilog() override { return "this"; }
|
||||
bool same(const AstNode* /*samep*/) const override { return true; }
|
||||
bool cleanOut() const override { return true; }
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||
};
|
||||
class AstUCFunc final : public AstNodeMath {
|
||||
// User's $c function
|
||||
// Perhaps this should be an AstNodeListop; but there's only one list math right now
|
||||
|
@ -1168,6 +1168,12 @@ public:
|
||||
emitConstant(nodep, nullptr, "");
|
||||
}
|
||||
}
|
||||
void visit(AstThisRef* nodep) override {
|
||||
putbs(nodep->dtypep()->cType("", false, false));
|
||||
puts("{");
|
||||
puts(m_useSelfForThis ? "vlSelf" : "this");
|
||||
puts("}");
|
||||
}
|
||||
|
||||
//
|
||||
void visit(AstMTaskBody* nodep) override {
|
||||
|
@ -2054,6 +2054,13 @@ private:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
VSymEnt* getThisClassSymp() {
|
||||
VSymEnt* classSymp = m_ds.m_dotSymp;
|
||||
do {
|
||||
classSymp = classSymp->parentp();
|
||||
} while (classSymp && !VN_IS(classSymp->nodep(), Class));
|
||||
return classSymp;
|
||||
}
|
||||
|
||||
// VISITs
|
||||
void visit(AstNetlist* nodep) override {
|
||||
@ -2201,10 +2208,7 @@ private:
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
|
||||
if (VN_IS(nodep->lhsp(), ParseRef) && nodep->lhsp()->name() == "this") {
|
||||
VSymEnt* classSymp = m_ds.m_dotSymp;
|
||||
do {
|
||||
classSymp = classSymp->parentp();
|
||||
} while (classSymp && !VN_IS(classSymp->nodep(), Class));
|
||||
VSymEnt* classSymp = getThisClassSymp();
|
||||
if (!classSymp) {
|
||||
nodep->v3error("'this' used outside class (IEEE 1800-2017 8.11)");
|
||||
m_ds.m_dotErr = true;
|
||||
@ -2213,10 +2217,7 @@ private:
|
||||
UINFO(8, " this. " << m_ds.ascii() << endl);
|
||||
}
|
||||
} else if (VN_IS(nodep->lhsp(), ParseRef) && nodep->lhsp()->name() == "super") {
|
||||
const VSymEnt* classSymp = m_ds.m_dotSymp;
|
||||
do {
|
||||
classSymp = classSymp->parentp();
|
||||
} while (classSymp && !VN_IS(classSymp->nodep(), Class));
|
||||
const VSymEnt* classSymp = getThisClassSymp();
|
||||
if (!classSymp) {
|
||||
nodep->v3error("'super' used outside class (IEEE 1800-2017 8.15)");
|
||||
m_ds.m_dotErr = true;
|
||||
@ -2310,6 +2311,22 @@ private:
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: super");
|
||||
m_ds.m_dotErr = true;
|
||||
}
|
||||
if (nodep->name() == "this") {
|
||||
iterateChildren(nodep);
|
||||
if (m_statep->forPrimary()) return; // The class might be parametrized somewhere
|
||||
const VSymEnt* classSymp = getThisClassSymp();
|
||||
if (!classSymp) {
|
||||
nodep->v3error("'this' used outside class (IEEE 1800-2017 8.11)");
|
||||
return;
|
||||
}
|
||||
AstClass* const classp = VN_AS(classSymp->nodep(), Class);
|
||||
AstClassRefDType* const dtypep
|
||||
= new AstClassRefDType{nodep->fileline(), classp, nullptr};
|
||||
AstThisRef* const newp = new AstThisRef{nodep->fileline(), dtypep};
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
}
|
||||
if (m_ds.m_dotPos == DP_FINAL && VN_IS(m_ds.m_unlinkedScopep, LambdaArgRef)
|
||||
&& nodep->name() == "index") {
|
||||
// 'with' statement's 'item.index'
|
||||
|
@ -2465,6 +2465,10 @@ private:
|
||||
userIterateChildren(nodep, nullptr); // First size all members
|
||||
nodep->repairCache();
|
||||
}
|
||||
void visit(AstThisRef* nodep) override {
|
||||
if (nodep->didWidthAndSet()) return;
|
||||
nodep->dtypep(iterateEditMoveDTypep(nodep, nodep->childDTypep()));
|
||||
}
|
||||
void visit(AstClassRefDType* nodep) override {
|
||||
if (nodep->didWidthAndSet()) return;
|
||||
// TODO this maybe eventually required to properly resolve members,
|
||||
|
@ -11,13 +11,25 @@ class Cls;
|
||||
this.addr = addr;
|
||||
end : body
|
||||
endfunction
|
||||
function void set2(bit [3:0] addr);
|
||||
begin : body
|
||||
Cls c2 = this;
|
||||
c2.addr = addr;
|
||||
end : body
|
||||
endfunction
|
||||
extern function void setext(bit [3:0] addr);
|
||||
extern function void setext2(bit [3:0] addr);
|
||||
endclass
|
||||
|
||||
function void Cls::setext(bit [3:0] addr);
|
||||
this.addr = addr;
|
||||
endfunction
|
||||
|
||||
function void Cls::setext2(bit [3:0] addr);
|
||||
Cls c2 = this;
|
||||
c2.addr = addr;
|
||||
endfunction
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
@ -34,8 +46,12 @@ module t(/*AUTOARG*/
|
||||
$display(baz.addr);
|
||||
`endif
|
||||
if (bar.addr != 4) $stop;
|
||||
bar.set2(1);
|
||||
if (bar.addr != 1) $stop;
|
||||
bar.setext(2);
|
||||
if (bar.addr != 2) $stop;
|
||||
bar.setext2(3);
|
||||
if (bar.addr != 3) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user