diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 3486d277f..1028ac62e 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2234,6 +2234,12 @@ private: } } } + void importSymbolsFromExtended(AstClass* const nodep, AstClassExtends* const cextp) { + AstClass* const classp = cextp->classp(); + VSymEnt* const srcp = m_statep->getNodeSym(classp); + if (classp->isInterfaceClass()) importImplementsClass(nodep, srcp, classp); + if (!cextp->isImplements()) m_curSymp->importFromClass(m_statep->symsp(), srcp); + } // VISITs void visit(AstNetlist* nodep) override { @@ -3287,7 +3293,11 @@ private: cextp->v3error("Multiple inheritance illegal on non-interface classes" " (IEEE 1800-2017 8.13)"); } - if (cextp->childDTypep() || cextp->dtypep()) continue; // Already converted + if (cextp->childDTypep() || cextp->dtypep()) { + // Already converted. Update symbol table to link unlinked members + importSymbolsFromExtended(nodep, cextp); + continue; + } AstNode* cprp = cextp->classOrPkgsp(); VSymEnt* lookSymp = m_curSymp; if (AstDot* const dotp = VN_CAST(cextp->classOrPkgsp(), Dot)) { @@ -3371,13 +3381,7 @@ private: cextp->childDTypep(classRefDtypep); classp->isExtended(true); nodep->isExtended(true); - VSymEnt* const srcp = m_statep->getNodeSym(classp); - if (classp->isInterfaceClass()) { - importImplementsClass(nodep, srcp, classp); - } - if (!cextp->isImplements()) { - m_curSymp->importFromClass(m_statep->symsp(), srcp); - } + importSymbolsFromExtended(nodep, cextp); VL_DO_DANGLING( cextp->classOrPkgsp()->unlinkFrBack()->deleteTree(), cpackagerefp); diff --git a/test_regress/t/t_randomize_srandom.v b/test_regress/t/t_randomize_srandom.v index 4fb3a3e8e..218565138 100644 --- a/test_regress/t/t_randomize_srandom.v +++ b/test_regress/t/t_randomize_srandom.v @@ -52,10 +52,39 @@ class Cls; endfunction endclass +class Foo; +endclass + +class Bar extends Foo; + bit [63:0] m_sum; + rand int m_r; + function void hash_init(); + m_sum = 64'h5aef0c8d_d70a4497; + endfunction + function void hash(int res); + $display(" res %x", res); + m_sum = {32'h0, res} ^ {m_sum[62:0], m_sum[63] ^ m_sum[2] ^ m_sum[0]}; + endfunction + + function void this_srandom(int seed); + this.srandom(seed); + endfunction + + function bit [63:0] test2; + $display(" init for seeded randomize"); + hash_init; + $display("%d", m_r); + hash(m_r); + return m_sum; + endfunction +endclass + module t(/*AUTOARG*/); Cls ca; Cls cb; + Bar b1; + Bar b2; bit [63:0] sa; bit [63:0] sb; @@ -66,6 +95,8 @@ module t(/*AUTOARG*/); $display("New"); ca = new; cb = new; + b1 = new; + b2 = new; sa = ca.test1(); sb = cb.test1(); @@ -90,6 +121,23 @@ module t(/*AUTOARG*/); sb = cb.test2(3); `checkeq(sa, sb); + $display("this.srandom - Bar class"); + b1.this_srandom(1); + b2.this_srandom(2); + void'(b1.randomize()); + void'(b2.randomize()); + sa = b1.test2; + sb = b2.test2; + `checkne(sa, sb); + + b1.this_srandom(3); + b2.this_srandom(3); + void'(b1.randomize()); + void'(b2.randomize()); + sa = b1.test2; + sb = b2.test2; + `checkeq(sa, sb); + // Check using direct call $display("srandom"); sa = ca.test3(1);