@@ -105,7 +105,7 @@ struct RandModeTarget final {
105
105
union RandomizeMode final {
106
106
// MEMBERS
107
107
struct {
108
- bool usesMode : 1 ; // True if variable /constraint uses rand_mode/constraint_mode
108
+ bool usesMode : 1 ; // Variable /constraint uses rand_mode/constraint_mode
109
109
uint32_t index : 31 ; // Index of var/constraint in rand_mode/constraint_mode vector
110
110
};
111
111
int asInt; // Representation as int to be stored in nodep->user*
@@ -308,6 +308,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
308
308
if (constrp->isStatic ()) {
309
309
nodep->v3warn (E_UNSUPPORTED,
310
310
" Unsupported: 'constraint_mode()' on static constraint" );
311
+ valid = false ;
311
312
}
312
313
} else if (AstClassRefDType* classRefDtp
313
314
= VN_CAST (methodCallp->fromp ()->dtypep ()->skipRefp (), ClassRefDType)) {
@@ -1232,7 +1233,6 @@ class RandomizeVisitor final : public VNVisitor {
1232
1233
dynarrayNewp->dtypeSetVoid ();
1233
1234
AstNodeFTask* const newp = VN_AS (m_memberMap.findMember (classp, " new" ), NodeFTask);
1234
1235
UASSERT_OBJ (newp, classp, " No new() in class" );
1235
- fl = classp->fileline ();
1236
1236
newp->addStmtsp (dynarrayNewp->makeStmt ());
1237
1237
newp->addStmtsp (makeModeSetLoop (fl,
1238
1238
new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE},
@@ -1588,6 +1588,54 @@ class RandomizeVisitor final : public VNVisitor {
1588
1588
});
1589
1589
}
1590
1590
1591
+ // Creates a lvalue reference to the randomize mode var. Called by visit(AstNodeFTaskRef*)
1592
+ AstNodeExpr* makeModeAssignLhs (FileLine* const fl, AstClass* const classp,
1593
+ AstNodeExpr* const fromp, AstVar* const modeVarp) {
1594
+ if (classp == m_modp) {
1595
+ // Called on 'this' or a member of 'this'
1596
+ return new AstVarRef{fl, VN_AS (modeVarp->user2p (), NodeModule), modeVarp,
1597
+ VAccess::WRITE};
1598
+ } else {
1599
+ AstMemberSel* const memberselp = new AstMemberSel{fl, fromp->unlinkFrBack (), modeVarp};
1600
+ memberselp->foreach ([](AstVarRef* varrefp) { varrefp->access (VAccess::WRITE); });
1601
+ return memberselp;
1602
+ }
1603
+ }
1604
+ // Replace the node with an assignment to the mode variable. Called by visit(AstNodeFTaskRef*)
1605
+ void replaceWithModeAssign (AstNodeFTaskRef* const ftaskRefp, AstNode* const receiverp,
1606
+ AstNodeExpr* const lhsp) {
1607
+ FileLine* const fl = ftaskRefp->fileline ();
1608
+ if (ftaskRefp->pinsp ()) {
1609
+ UASSERT_OBJ (VN_IS (ftaskRefp->backp (), StmtExpr), ftaskRefp, " Should be a statement" );
1610
+ AstNodeExpr* const rhsp = VN_AS (ftaskRefp->pinsp (), Arg)->exprp ()->unlinkFrBack ();
1611
+ if (receiverp) {
1612
+ // Called on a rand member variable/constraint. Set the variable/constraint's
1613
+ // mode
1614
+ const RandomizeMode mode = {.asInt = receiverp->user1 ()};
1615
+ UASSERT_OBJ (mode.usesMode , ftaskRefp, " Failed to set usesMode" );
1616
+ AstCMethodHard* const atp
1617
+ = new AstCMethodHard{fl, lhsp, " at" , new AstConst{fl, mode.index }};
1618
+ atp->dtypeSetUInt32 ();
1619
+ m_stmtp->replaceWith (new AstAssign{fl, atp, rhsp});
1620
+ } else {
1621
+ // For rand_mode: Called on 'this' or a non-rand class instance.
1622
+ // For constraint_mode: Called on a class instance.
1623
+ // Set the rand mode of all members
1624
+ m_stmtp->replaceWith (makeModeSetLoop (fl, lhsp, rhsp, m_ftaskp));
1625
+ }
1626
+ pushDeletep (m_stmtp);
1627
+ } else {
1628
+ UASSERT_OBJ (receiverp, ftaskRefp, " Should have receiver" );
1629
+ const RandomizeMode mode = {.asInt = receiverp->user1 ()};
1630
+ UASSERT_OBJ (mode.usesMode , ftaskRefp, " Failed to set usesMode" );
1631
+ AstCMethodHard* const atp
1632
+ = new AstCMethodHard{fl, lhsp, " at" , new AstConst{fl, mode.index }};
1633
+ atp->dtypeSetUInt32 ();
1634
+ ftaskRefp->replaceWith (atp);
1635
+ VL_DO_DANGLING (pushDeletep (ftaskRefp), ftaskRefp);
1636
+ }
1637
+ };
1638
+
1591
1639
// Handle inline random variable control. After this, the randomize() call has no args
1592
1640
void handleRandomizeArgs (AstNodeFTaskRef* const nodep) {
1593
1641
if (!nodep->pinsp ()) return ;
@@ -1827,55 +1875,6 @@ class RandomizeVisitor final : public VNVisitor {
1827
1875
VL_DO_DANGLING (pushDeletep (nodep), nodep);
1828
1876
}
1829
1877
void visit (AstNodeFTaskRef* nodep) override {
1830
- // Common logic for rand_mode and constraint_mode
1831
- const auto makeModeAssignLhs
1832
- = [this , fl = nodep->fileline ()](AstClass* const classp, AstNodeExpr* const fromp,
1833
- AstVar* const modeVarp) -> AstNodeExpr* {
1834
- if (classp == m_modp) {
1835
- // Called on 'this' or a member of 'this'
1836
- return new AstVarRef{fl, VN_AS (modeVarp->user2p (), NodeModule), modeVarp,
1837
- VAccess::WRITE};
1838
- } else {
1839
- AstMemberSel* const memberselp
1840
- = new AstMemberSel{fl, fromp->unlinkFrBack (), modeVarp};
1841
- memberselp->foreach ([](AstVarRef* varrefp) { varrefp->access (VAccess::WRITE); });
1842
- return memberselp;
1843
- }
1844
- };
1845
- const auto replaceWithModeAssign = [this , nodep](AstNode* const receiverp,
1846
- AstNodeExpr* const lhsp) {
1847
- FileLine* const fl = nodep->fileline ();
1848
- if (nodep->pinsp ()) {
1849
- UASSERT_OBJ (VN_IS (nodep->backp (), StmtExpr), nodep, " Should be a statement" );
1850
- AstNodeExpr* const rhsp = VN_AS (nodep->pinsp (), Arg)->exprp ()->unlinkFrBack ();
1851
- if (receiverp) {
1852
- // Called on a rand member variable/constraint. Set the variable/constraint's
1853
- // mode
1854
- const RandomizeMode mode = {.asInt = receiverp->user1 ()};
1855
- UASSERT_OBJ (mode.usesMode , nodep, " Failed to set usesMode" );
1856
- AstCMethodHard* const atp
1857
- = new AstCMethodHard{fl, lhsp, " at" , new AstConst{fl, mode.index }};
1858
- atp->dtypeSetUInt32 ();
1859
- m_stmtp->replaceWith (new AstAssign{fl, atp, rhsp});
1860
- } else {
1861
- // For rand_mode: Called on 'this' or a non-rand class instance.
1862
- // For constraint_mode: Called on a class instance.
1863
- // Set the rand mode of all members
1864
- m_stmtp->replaceWith (makeModeSetLoop (fl, lhsp, rhsp, m_ftaskp));
1865
- }
1866
- pushDeletep (m_stmtp);
1867
- } else {
1868
- UASSERT_OBJ (receiverp, nodep, " Should have receiver" );
1869
- const RandomizeMode mode = {.asInt = receiverp->user1 ()};
1870
- UASSERT_OBJ (mode.usesMode , nodep, " Failed to set usesMode" );
1871
- AstCMethodHard* const atp
1872
- = new AstCMethodHard{fl, lhsp, " at" , new AstConst{fl, mode.index }};
1873
- atp->dtypeSetUInt32 ();
1874
- nodep->replaceWith (atp);
1875
- VL_DO_DANGLING (pushDeletep (nodep), nodep);
1876
- }
1877
- };
1878
-
1879
1878
if (nodep->name () == " rand_mode" ) {
1880
1879
AstMethodCall* const methodCallp = VN_CAST (nodep, MethodCall);
1881
1880
AstNodeExpr* const fromp = methodCallp ? methodCallp->fromp () : nullptr ;
@@ -1884,11 +1883,12 @@ class RandomizeVisitor final : public VNVisitor {
1884
1883
" Should have checked in RandomizeMarkVisitor" );
1885
1884
AstVar* const receiverp = randModeTarget.receiverp ;
1886
1885
AstVar* const randModeVarp = getRandModeVar (randModeTarget.classp );
1887
- AstNodeExpr* const lhsp
1888
- = makeModeAssignLhs (randModeTarget.classp , randModeTarget.fromp , randModeVarp);
1889
- replaceWithModeAssign (
1890
- // If the receiver is not rand, set the rand_mode for all members
1891
- receiverp && receiverp->rand ().isRand () ? receiverp : nullptr , lhsp);
1886
+ AstNodeExpr* const lhsp = makeModeAssignLhs (nodep->fileline (), randModeTarget.classp ,
1887
+ randModeTarget.fromp , randModeVarp);
1888
+ replaceWithModeAssign (nodep,
1889
+ // If the receiver is not rand, set the rand_mode for all members
1890
+ receiverp && receiverp->rand ().isRand () ? receiverp : nullptr ,
1891
+ lhsp);
1892
1892
return ;
1893
1893
}
1894
1894
@@ -1908,8 +1908,9 @@ class RandomizeVisitor final : public VNVisitor {
1908
1908
}
1909
1909
UASSERT_OBJ (classp, nodep, " Failed to find class" );
1910
1910
AstVar* const constraintModeVarp = getConstraintModeVar (classp);
1911
- AstNodeExpr* const lhsp = makeModeAssignLhs (classp, fromp, constraintModeVarp);
1912
- replaceWithModeAssign (constrp, lhsp);
1911
+ AstNodeExpr* const lhsp
1912
+ = makeModeAssignLhs (nodep->fileline (), classp, fromp, constraintModeVarp);
1913
+ replaceWithModeAssign (nodep, constrp, lhsp);
1913
1914
return ;
1914
1915
}
1915
1916
0 commit comments