add an unsup test for case 'one var but in two different global constraints'

This commit is contained in:
Yilou Wang 2025-11-01 07:46:06 +01:00
parent 6ab926877a
commit fcc4da9d66
4 changed files with 89 additions and 3 deletions

View File

@ -236,14 +236,27 @@ class RandomizeMarkVisitor final : public VNVisitor {
// Process a single constraint during nested constraint cloning
void processNestedConstraint(AstConstraint* const constrp, AstVarRef* rootVarRefp,
const std::vector<AstVar*>& newPath) {
AstConstraint* const cloneConstrp = constrp->cloneTree(false);
std::string pathPrefix = rootVarRefp->name();
for (AstVar* pathMemberVarp : newPath) {
pathPrefix += GLOBAL_CONSTRAINT_SEPARATOR + pathMemberVarp->name();
}
cloneConstrp->name(pathPrefix + GLOBAL_CONSTRAINT_SEPARATOR + cloneConstrp->name());
const std::string newName = pathPrefix + GLOBAL_CONSTRAINT_SEPARATOR + constrp->name();
for (const AstConstraint* existingConstrp : m_clonedConstraints) {
if (existingConstrp->name() == newName) {
// Multiple paths lead to same constraint - unsupported pattern
std::string fullPath = rootVarRefp->name();
for (AstVar* pathVar : newPath) { fullPath += "." + pathVar->name(); }
constrp->v3warn(E_UNSUPPORTED, "Unsupported: One variable '"
<< fullPath
<< "' cannot have multiple global constraints");
return;
}
}
AstConstraint* const cloneConstrp = constrp->cloneTree(false);
cloneConstrp->name(newName);
cloneConstrp->foreach([&](AstVarRef* varRefp) {
AstNodeExpr* const chainp = buildMemberSelChain(rootVarRefp, newPath);
AstMemberSel* const finalSelp

View File

@ -0,0 +1,6 @@
%Error-UNSUPPORTED: t/t_constraint_global_nested_unsup.v:9:14: Unsupported: Variable 'm_mid.m_inner' cannot have multiple global constraints
: ... note: In instance 't'
9 | constraint c_inner { m_val inside {[1:10]}; }
| ^~~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.lint(fails=test.vlt_all, expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,51 @@
// DESCRIPTION: Verilator: Test for unsupported multiple global constraints
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by PlanV GmbH.
// SPDX-License-Identifier: CC0-1.0
class Inner;
rand int m_val;
constraint c_inner { m_val inside {[1:10]}; }
function new(); m_val = 0; endfunction
endclass
class Mid;
rand Inner m_inner;
rand int m_x;
// Mid has global constraint on m_inner.m_val
constraint c_mid_global {
m_x > m_inner.m_val;
m_x inside {[5:15]};
}
function new();
m_inner = new();
m_x = 0;
endfunction
endclass
class Top;
rand Mid m_mid;
rand int m_y;
// Top also has global constraint on m_mid.m_inner.m_val
constraint c_top_global {
m_y < m_mid.m_inner.m_val;
m_y inside {[1:5]};
}
function new();
m_mid = new();
m_y = 0;
endfunction
endclass
module t;
Top top;
/* verilator lint_off WIDTHTRUNC */
initial begin
top = new();
if (!top.randomize()) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
/* verilator lint_off WIDTHTRUNC */
endmodule