add an unsup test for case 'one var but in two different global constraints'
This commit is contained in:
parent
6ab926877a
commit
fcc4da9d66
|
|
@ -236,14 +236,27 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
// Process a single constraint during nested constraint cloning
|
// Process a single constraint during nested constraint cloning
|
||||||
void processNestedConstraint(AstConstraint* const constrp, AstVarRef* rootVarRefp,
|
void processNestedConstraint(AstConstraint* const constrp, AstVarRef* rootVarRefp,
|
||||||
const std::vector<AstVar*>& newPath) {
|
const std::vector<AstVar*>& newPath) {
|
||||||
AstConstraint* const cloneConstrp = constrp->cloneTree(false);
|
|
||||||
|
|
||||||
std::string pathPrefix = rootVarRefp->name();
|
std::string pathPrefix = rootVarRefp->name();
|
||||||
for (AstVar* pathMemberVarp : newPath) {
|
for (AstVar* pathMemberVarp : newPath) {
|
||||||
pathPrefix += GLOBAL_CONSTRAINT_SEPARATOR + pathMemberVarp->name();
|
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) {
|
cloneConstrp->foreach([&](AstVarRef* varRefp) {
|
||||||
AstNodeExpr* const chainp = buildMemberSelChain(rootVarRefp, newPath);
|
AstNodeExpr* const chainp = buildMemberSelChain(rootVarRefp, newPath);
|
||||||
AstMemberSel* const finalSelp
|
AstMemberSel* const finalSelp
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue