forked from github/verilator
Fix self references when param class instantiated (#3833)
This commit is contained in:
parent
5dbff89a90
commit
bf4a844f2b
@ -542,12 +542,27 @@ class ParamProcessor final {
|
||||
hash.insert(V3Os::trueRandom(64));
|
||||
}
|
||||
}
|
||||
void replaceRefsRecurse(AstNode* const nodep, const AstClass* const oldClassp,
|
||||
AstClass* const newClassp) {
|
||||
if (AstClassRefDType* const classRefp = VN_CAST(nodep, ClassRefDType)) {
|
||||
if (classRefp->classp() == oldClassp) classRefp->classp(newClassp);
|
||||
}
|
||||
if (nodep->op1p()) replaceRefsRecurse(nodep->op1p(), oldClassp, newClassp);
|
||||
if (nodep->op2p()) replaceRefsRecurse(nodep->op2p(), oldClassp, newClassp);
|
||||
if (nodep->op3p()) replaceRefsRecurse(nodep->op3p(), oldClassp, newClassp);
|
||||
if (nodep->op4p()) replaceRefsRecurse(nodep->op4p(), oldClassp, newClassp);
|
||||
if (nodep->nextp()) replaceRefsRecurse(nodep->nextp(), oldClassp, newClassp);
|
||||
}
|
||||
void deepCloneModule(AstNodeModule* srcModp, AstNode* cellp, AstPin* paramsp,
|
||||
const string& newname, const IfaceRefRefs& ifaceRefRefs) {
|
||||
// Deep clone of new module
|
||||
// Note all module internal variables will be re-linked to the new modules by clone
|
||||
// However links outside the module (like on the upper cells) will not.
|
||||
AstNodeModule* const newmodp = srcModp->cloneTree(false);
|
||||
if (VN_IS(srcModp, Class)) {
|
||||
replaceRefsRecurse(newmodp->stmtsp(), VN_AS(newmodp, Class), VN_AS(srcModp, Class));
|
||||
}
|
||||
|
||||
newmodp->name(newname);
|
||||
newmodp->user5(false); // We need to re-recurse this module once changed
|
||||
newmodp->recursive(false);
|
||||
|
@ -45,6 +45,15 @@ endclass
|
||||
|
||||
typedef Cls#(8) Cls8_t;
|
||||
|
||||
class SelfRefClassTypeParam #(type T=logic);
|
||||
typedef SelfRefClassTypeParam #(int) self_int_t;
|
||||
T field;
|
||||
endclass
|
||||
|
||||
class SelfRefClassIntParam #(int P=1);
|
||||
typedef SelfRefClassIntParam #(10) self_int_t;
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
Cls c12;
|
||||
@ -52,12 +61,20 @@ module t (/*AUTOARG*/);
|
||||
Cls8_t c8;
|
||||
Wrap #(.P(16)) w16;
|
||||
Wrap2 #(.P(32)) w32;
|
||||
SelfRefClassTypeParam src_logic;
|
||||
SelfRefClassTypeParam::self_int_t src_int;
|
||||
SelfRefClassIntParam src1;
|
||||
SelfRefClassIntParam::self_int_t src10;
|
||||
initial begin
|
||||
c12 = new;
|
||||
c4 = new;
|
||||
c8 = new;
|
||||
w16 = new;
|
||||
w32 = new;
|
||||
src_int = new;
|
||||
src_logic = new;
|
||||
src1 = new;
|
||||
src10 = new;
|
||||
if (Cls#()::PBASE != 12) $stop;
|
||||
if (Cls#(4)::PBASE != 4) $stop;
|
||||
if (Cls8_t::PBASE != 8) $stop;
|
||||
@ -92,6 +109,11 @@ module t (/*AUTOARG*/);
|
||||
`checks($sformatf("%p", c12), "'{member:'haaa}");
|
||||
`checks($sformatf("%p", c4), "'{member:'ha}");
|
||||
|
||||
if ($bits(src_logic.field) != 1) $stop;
|
||||
if ($bits(src_int.field) != 32) $stop;
|
||||
if (src1.P != 1) $stop;
|
||||
if (src10.P != 10) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
@ -45,17 +45,34 @@ endclass
|
||||
|
||||
typedef Cls#(8) Cls8_t;
|
||||
|
||||
class SelfRefClassTypeParam #(type T=logic);
|
||||
typedef SelfRefClassTypeParam #(int) self_int_t;
|
||||
T field;
|
||||
endclass
|
||||
|
||||
class SelfRefClassIntParam #(int P=1);
|
||||
typedef SelfRefClassIntParam #(10) self_int_t;
|
||||
endclass
|
||||
|
||||
Cls c12;
|
||||
Cls #(.PBASE(4)) c4;
|
||||
Cls8_t c8;
|
||||
Wrap #(.P(16)) w16;
|
||||
Wrap2 #(.P(32)) w32;
|
||||
SelfRefClassTypeParam src_logic;
|
||||
SelfRefClassTypeParam::self_int_t src_int;
|
||||
SelfRefClassIntParam src1;
|
||||
SelfRefClassIntParam::self_int_t src10;
|
||||
initial begin
|
||||
c12 = new;
|
||||
c4 = new;
|
||||
c8 = new;
|
||||
w16 = new;
|
||||
w32 = new;
|
||||
src_int = new;
|
||||
src_logic = new;
|
||||
src1 = new;
|
||||
src10 = new;
|
||||
if (Cls#()::PBASE != 12) $stop;
|
||||
if (Cls#(4)::PBASE != 4) $stop;
|
||||
if (Cls8_t::PBASE != 8) $stop;
|
||||
@ -90,6 +107,11 @@ endclass
|
||||
`checks($sformatf("%p", c12), "'{member:'haaa}");
|
||||
`checks($sformatf("%p", c4), "'{member:'ha}");
|
||||
|
||||
if ($bits(src_logic.field) != 1) $stop;
|
||||
if ($bits(src_int.field) != 32) $stop;
|
||||
if (src1.P != 1) $stop;
|
||||
if (src10.P != 10) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user