Internals: Pass class parameters through link.

This commit is contained in:
Wilson Snyder 2020-11-27 22:48:42 -05:00
parent cf2810db8b
commit 1299b70945
7 changed files with 93 additions and 9 deletions

View File

@ -988,14 +988,16 @@ public:
class AstClassRefDType final : public AstNodeDType {
// Reference to a class
// Children: PINs (for parameter settings)
private:
AstClass* m_classp; // data type pointed to, BELOW the AstTypedef
AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy
public:
AstClassRefDType(FileLine* fl, AstClass* classp)
AstClassRefDType(FileLine* fl, AstClass* classp, AstNode* paramsp)
: ASTGEN_SUPER(fl)
, m_classp{classp} {
dtypep(this);
addNOp4p(paramsp);
}
ASTNODE_NODE_FUNCS(ClassRefDType)
// METHODS
@ -1032,6 +1034,7 @@ public:
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
AstClass* classp() const { return m_classp; }
void classp(AstClass* nodep) { m_classp = nodep; }
AstPin* paramsp() const { return VN_CAST(op4p(), Pin); }
};
class AstIfaceRefDType final : public AstNodeDType {

View File

@ -457,6 +457,13 @@ private:
UINFO(4, " Link Cell done: " << nodep << endl);
}
virtual void visit(AstRefDType* nodep) override {
for (AstPin* pinp = nodep->paramsp(); pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
pinp->param(true);
if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum()));
}
}
// Accelerate the recursion
// Must do statements to support Generates, math though...
virtual void visit(AstNodeMath*) override {}

View File

@ -1941,11 +1941,13 @@ private:
virtual void visit(AstCell* nodep) override {
// Cell: Recurse inside or cleanup not founds
checkNoDot(nodep);
m_cellp = nodep;
AstNode::user5ClearTree();
UASSERT_OBJ(nodep->modp(), nodep,
"Cell has unlinked module"); // V3LinkCell should have errored out
VL_RESTORER(m_cellp);
VL_RESTORER(m_pinSymp);
{
m_cellp = nodep;
if (VN_IS(nodep->modp(), NotFoundModule)) {
// Prevent warnings about missing pin connects
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
@ -1960,13 +1962,26 @@ private:
// if (debug()) nodep->dumpTree(cout, "linkcell:");
// if (debug()) nodep->modp()->dumpTree(cout, "linkcemd:");
iterateChildren(nodep);
m_pinSymp = nullptr;
}
}
m_cellp = nullptr;
// Parent module inherits child's publicity
// This is done bottom up in the LinkBotupVisitor stage
}
virtual void visit(AstClassRefDType* nodep) override {
// Cell: Recurse inside or cleanup not founds
checkNoDot(nodep);
AstNode::user5ClearTree();
UASSERT_OBJ(nodep->classp(), nodep, "ClassRef has unlinked class");
VL_RESTORER(m_pinSymp);
{
// ClassRef's have pins, so track
m_pinSymp = m_statep->getNodeSym(nodep->classp());
UINFO(4, "(Backto) Link ClassRefDType: " << nodep << endl);
// if (debug()) nodep->dumpTree(cout, "linkcell:");
// if (debug()) nodep->modp()->dumpTree(cout, "linkcemd:");
iterateChildren(nodep);
}
}
virtual void visit(AstPin* nodep) override {
// Pin: Link to submodule's port
checkNoDot(nodep);
@ -1976,7 +1991,8 @@ private:
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
const char* whatp = nodep->param() ? "parameter pin" : "pin";
if (!foundp) {
if (nodep->name() == "__paramNumber1" && VN_IS(m_cellp->modp(), Primitive)) {
if (nodep->name() == "__paramNumber1" && m_cellp
&& VN_IS(m_cellp->modp(), Primitive)) {
// Primitive parameter is really a delay we can just ignore
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
@ -2540,7 +2556,7 @@ private:
"Unsupported: " << AstNode::prettyNameQ(cpackagerefp->name()));
}
if (cpackagerefp->paramsp()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages for task calls");
}
UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link");
nodep->classOrPackagep(cpackagerefp->classOrPackagep());
@ -2817,8 +2833,10 @@ private:
cextp->v3error("Attempting to extend class "
<< nodep->prettyNameQ() << " from itself");
} else {
AstClassRefDType* newp
= new AstClassRefDType{nodep->fileline(), classp};
AstNode* paramsp = cpackagerefp->paramsp();
if (paramsp) paramsp = paramsp->cloneTree(true);
const auto newp
= new AstClassRefDType{nodep->fileline(), classp, paramsp};
cextp->childDTypep(newp);
classp->isExtended(true);
nodep->isExtended(true);
@ -2909,7 +2927,9 @@ private:
nodep->refDTypep(defp);
nodep->classOrPackagep(foundp->classOrPackagep());
} else if (AstClass* defp = foundp ? VN_CAST(foundp->nodep(), Class) : nullptr) {
AstClassRefDType* newp = new AstClassRefDType(nodep->fileline(), defp);
AstNode* paramsp = nodep->paramsp();
if (paramsp) paramsp->unlinkFrBackWithNext();
AstClassRefDType* newp = new AstClassRefDType{nodep->fileline(), defp, paramsp};
newp->classOrPackagep(foundp->classOrPackagep());
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);

View File

@ -0,0 +1,17 @@
%Error-UNSUPPORTED: t/t_class_param_bad.v:12:4: Unsupported: parameterized packages
12 | Cls #(.PARAMBAD(1)) c;
| ^~~
%Error: t/t_class_param_bad.v:12:11: Parameter pin not found: 'PARAMBAD'
: ... Suggested alternative: 'PARAMB'
12 | Cls #(.PARAMBAD(1)) c;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_class_param_bad.v:13:4: Unsupported: parameterized packages
13 | Cls #(13, 1) cd;
| ^~~
%Error: t/t_class_param_bad.v:13:14: Parameter pin not found: '__paramNumber2'
13 | Cls #(13, 1) cd;
| ^
%Error-UNSUPPORTED: t/t_class_param_bad.v:7:23: Unsupported: class parameter
7 | class Cls #(parameter PARAMB = 12);
| ^~~~~~
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2020 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;

View File

@ -0,0 +1,15 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2020 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class Cls #(parameter PARAMB = 12);
endclass
module t (/*AUTOARG*/);
Cls #(.PARAMBAD(1)) c; // Bad param name
Cls #(13, 1) cd; // Bad param number
endmodule

View File

@ -1,4 +1,7 @@
%Error-UNSUPPORTED: t/t_class_vparam.v:13:40: Unsupported: parameterized packages
13 | pure virtual function void funcname(paramed_class_t #(CTYPE_t) v);
| ^~~~~~~~~~~~~~~
%Error: t/t_class_vparam.v:13:58: Parameter pin not found: '__paramNumber1'
13 | pure virtual function void funcname(paramed_class_t #(CTYPE_t) v);
| ^~~~~~~
%Error: Exiting due to