From 5d0352ab46b886fa121abafe69d7bddb7e9a5e38 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Tue, 17 Feb 2026 17:40:15 +0100 Subject: [PATCH] Fix conditional expressions in constraints (#7087) --- src/V3Randomize.cpp | 4 +++ test_regress/t/t_constraint_cond.py | 21 ++++++++++++++ test_regress/t/t_constraint_cond.v | 45 +++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100755 test_regress/t/t_constraint_cond.py create mode 100644 test_regress/t/t_constraint_cond.v diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 89423a6bd..158aa873e 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1423,6 +1423,10 @@ class ConstraintExprVisitor final : public VNVisitor { // Do not burden the solver if cond computable: (cond ? "then" : "else") iterate(nodep->thenp()); iterate(nodep->elsep()); + UASSERT_OBJ( + nodep->thenp()->isString() && nodep->elsep()->isString(), nodep, + "Branches of conditional expression in constraint not converted to strings"); + nodep->dtypeSetString(); return; } // Fall back to "(ite cond then else)" diff --git a/test_regress/t/t_constraint_cond.py b/test_regress/t/t_constraint_cond.py new file mode 100755 index 000000000..ab048b5e8 --- /dev/null +++ b/test_regress/t/t_constraint_cond.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2024 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_constraint_cond.v b/test_regress/t/t_constraint_cond.v new file mode 100644 index 000000000..538466a46 --- /dev/null +++ b/test_regress/t/t_constraint_cond.v @@ -0,0 +1,45 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +`define check_rand(cl, field, cond) \ +begin \ + automatic longint prev_result; \ + automatic int ok; \ + if (!bit'(cl.randomize())) $stop; \ + prev_result = longint'(field); \ + if (!(cond)) $stop; \ + repeat(9) begin \ + longint result; \ + if (!bit'(cl.randomize())) $stop; \ + result = longint'(field); \ + if (!(cond)) $stop; \ + if (result != prev_result) ok = 1; \ + prev_result = result; \ + end \ + if (ok != 1) $stop; \ +end + +class Cls; + int d; + rand int y; + rand bit i; + + constraint q { + if (i) { + ((d == 0) ? y == 0 : 1'b1); + } + } +endclass + +module t; + Cls cls = new; + initial begin + `check_rand(cls, cls.y, cls.i == 0 || cls.y == 0); + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule