diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index a1c4d9a29..98f93c0fc 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -330,6 +330,7 @@ class RandomizeMarkVisitor final : public VNVisitor { m_baseToDerivedMap[basep].insert(nodep); } for (AstConstraint* const constrp : m_clonedConstraints) m_classp->addStmtsp(constrp); + m_clonedConstraints.clear(); } void visit(AstNodeStmt* nodep) override { VL_RESTORER(m_stmtp); @@ -1572,9 +1573,6 @@ class RandomizeVisitor final : public VNVisitor { std::map m_randcDtypes; // RandC data type deduplication AstConstraint* m_constraintp = nullptr; // Current constraint - // Map of the class to the cloned constraint from the instantiated object - std::map m_clonedConstraints; - // METHODS void createRandomGenerator(AstClass* const classp) { if (classp->user3p()) return; diff --git a/test_regress/t/t_constraint_global_random.v b/test_regress/t/t_constraint_global_random.v index b135c40dd..e0dec8f4c 100755 --- a/test_regress/t/t_constraint_global_random.v +++ b/test_regress/t/t_constraint_global_random.v @@ -7,7 +7,18 @@ class Inner; rand int m_val; constraint c_local { m_val inside {[1:5]}; } - function new(); m_val = 0; endfunction + + class NestedInner; + rand int nested_val; + constraint c_nested { nested_val inside {[1:3]}; } + endclass + + rand NestedInner nested_obj; + + function new(); + m_val = 0; + nested_obj = new(); + endfunction endclass class Mid; @@ -31,6 +42,9 @@ class Top; m_y > m_m1.m_x; m_y < m_m2.m_x; m_m1.m_inner.m_val + m_m2.m_inner.m_val < 8; + // Global constraint on nested class variable (3-level deep) + m_m1.m_inner.nested_obj.nested_val == 1; + m_m2.m_inner.nested_obj.nested_val == 3; } function new(); @@ -40,9 +54,26 @@ class Top; endfunction endclass +// Second independent class with global constraints + +class AnotherTop; + rand Mid m_m3; + rand int m_z; + + constraint c_another { + m_z < m_m3.m_x; + } + + function new(); + m_m3 = new(10); + m_z = 0; + endfunction +endclass + module t_constraint_global_random; int success; Top t; + AnotherTop t2; initial begin t = new(); @@ -51,9 +82,6 @@ module t_constraint_global_random; success = t.randomize(); if (success != 1) $stop; - // $display("m1.x=%0d, m2.x=%0d, y=%0d", t.m_m1.m_x, t.m_m2.m_x, t.m_y); - // $display("m1.inner.val=%0d, m2.inner.val=%0d", t.m_m1.m_inner.m_val, t.m_m2.m_inner.m_val); - if (t.m_m1.m_x != 3 || t.m_m2.m_x != 5) $stop; if (t.m_m1.m_inner.m_val >= t.m_m2.m_inner.m_val) $stop; if (t.m_y <= t.m_m1.m_x || t.m_y >= t.m_m2.m_x) $stop; @@ -61,6 +89,10 @@ module t_constraint_global_random; if (t.m_m1.m_inner.m_val < 1 || t.m_m1.m_inner.m_val > 5 || t.m_m2.m_inner.m_val < 1 || t.m_m2.m_inner.m_val > 5) $stop; + // Verify nested class global constraints (3-level deep: Top -> Mid -> Inner -> NestedInner) + if (t.m_m1.m_inner.nested_obj.nested_val != 1) $stop; + if (t.m_m2.m_inner.nested_obj.nested_val != 3) $stop; + // Test 2: randomize() with inline constraint on global-constrained members success = 0; success = t.randomize() with { @@ -79,6 +111,13 @@ module t_constraint_global_random; if (t.m_y <= t.m_m1.m_x || t.m_y >= t.m_m2.m_x) $stop; if (t.m_m1.m_inner.m_val + t.m_m2.m_inner.m_val >= 8) $stop; + // Test 3: Second independent class (tests m_clonedConstraints.clear() bug) + t2 = new(); + success = t2.randomize(); + if (success != 1) $stop; + if (t2.m_z >= t2.m_m3.m_x) $stop; + if (t2.m_m3.m_x != 10) $stop; + $write("*-* All Finished *-*\n"); $finish; end