diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 76f359bf1..b80679b27 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -2188,7 +2188,7 @@ class CaptureVisitor final : public VNVisitor { newVarp->fileline(fileline); newVarp->varType(VVarType::BLOCKTEMP); newVarp->funcLocal(true); - newVarp->direction(m_targetp ? VDirection::INPUT : VDirection::REF); + newVarp->direction(VDirection::INPUT); newVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); m_varCloneMap.emplace(varrefp->varp(), newVarp); varp = newVarp; @@ -2458,6 +2458,13 @@ class RandomizeVisitor final : public VNVisitor { if (VN_IS(argExpr, ArraySel) && VN_IS(withExpr, ArraySel)) { const AstArraySel* const withASp = VN_AS(withExpr, ArraySel); const AstArraySel* const argASp = VN_AS(argExpr, ArraySel); + // Before checking Sel type index, check if both are Const + if (VN_IS(withASp->bitp(), Const) && VN_IS(argASp->bitp(), Const)) { + const AstConst* const withIdxp = VN_AS(withASp->bitp(), Const); + const AstConst* const argIdxp = VN_AS(argASp->bitp(), Const); + return isSimilarNode(withASp->fromp(), argASp->fromp()) + && withIdxp->num().isCaseEq(argIdxp->num()); + } // Index must be Sel type, extract VarRef using fromp() if (!VN_IS(withASp->bitp(), Sel) || !VN_IS(argASp->bitp(), Sel)) return false; const AstNodeExpr* const withIdxp = VN_AS(withASp->bitp(), Sel)->fromp(); diff --git a/test_regress/t/t_std_randomize.v b/test_regress/t/t_std_randomize.v index 40f4906d7..989ad72f6 100644 --- a/test_regress/t/t_std_randomize.v +++ b/test_regress/t/t_std_randomize.v @@ -36,6 +36,8 @@ class std_randomize_class; endclass +parameter int PARAM = 123; + module t_scope_std_randomize; bit [7:0] addr; bit [15:0] data; @@ -45,6 +47,10 @@ module t_scope_std_randomize; bit [30:0] limit_31bits[10]; bit [62:0] limit_63bits[10]; bit [94:0] limit_95bits[10]; + int x; + int y = 50; + int arr1[2]; + int arr2[2]; function bit run(); int ready; @@ -120,6 +126,17 @@ module t_scope_std_randomize; if (test.addr <= addr || test.addr >= 8'd100) `stop; if (limit_31bits[0] <= 31'(test.addr) || limit_31bits[0] >= 31'd200) `stop; + // Test parameter in with clause + void'(std::randomize(x) with { x > PARAM; }); + if (x <= PARAM) $stop; + void'(std::randomize(x) with { x < PARAM; x > y; }); + if (x >= PARAM || x <= y) $stop; + + arr1[0] = 1000; + arr2[0] = 42; + void'(std::randomize(arr1[0]) with { arr1[0] == arr2[0]; }); + if (arr1[0] != 42) $stop; + $write("*-* All Finished *-*\n"); $finish; end