Fix self references when param class instantiated (#3833)

This commit is contained in:
Ryszard Rozak 2022-12-30 12:05:01 +01:00 committed by GitHub
parent 5dbff89a90
commit bf4a844f2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 0 deletions

View File

@ -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);

View File

@ -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

View File

@ -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