Merge d3ffaae6b0 into a0b89dde8e
This commit is contained in:
commit
d53ead6775
|
|
@ -136,6 +136,7 @@ Julie Schwartz
|
|||
Julien Margetts
|
||||
Justin Thiel
|
||||
Kaleb Barrett
|
||||
Kamil Danecki
|
||||
Kamil Rakoczy
|
||||
Kanad Kanhere
|
||||
Kefa Chen
|
||||
|
|
|
|||
|
|
@ -1354,6 +1354,102 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
iterate(resultp);
|
||||
}
|
||||
void visit(AstPow* nodep) override {
|
||||
if (AstConst* const exponentp = VN_CAST(nodep->rhsp(), Const)) {
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNodeExpr* const basep = nodep->lhsp();
|
||||
V3Number numOne{nodep, basep->width(), 1};
|
||||
AstNodeExpr* productp = new AstConst{fl, numOne};
|
||||
for (uint32_t i = 0; i < exponentp->toUInt(); i++) {
|
||||
productp = new AstMul{fl, productp, basep->cloneTreePure(false)};
|
||||
productp->user1(true);
|
||||
}
|
||||
nodep->replaceWith(productp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
iterate(productp);
|
||||
} else {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: power expression with non constant exponent in constraint");
|
||||
}
|
||||
}
|
||||
void visit(AstPowSS* nodep) override {
|
||||
if (AstConst* const exponentp = VN_CAST(nodep->rhsp(), Const)) {
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNodeExpr* const basep = nodep->lhsp();
|
||||
V3Number numOne{nodep, basep->width(), 1};
|
||||
int32_t const exponent = exponentp->toSInt();
|
||||
AstNodeExpr* powerp = new AstConst{fl, numOne};
|
||||
if (exponent > 0) {
|
||||
for (int32_t i = 0; i < exponent; i++) {
|
||||
powerp = new AstMulS{fl, powerp, basep->cloneTreePure(false)};
|
||||
powerp->user1(true);
|
||||
}
|
||||
} else if (exponent < 0) {
|
||||
// Limit chain of divisions to max 2, because operations are on integers.
|
||||
// Two divisions are needed to preserve the sign.
|
||||
powerp = new AstDivS{fl, powerp, basep->cloneTreePure(false)};
|
||||
powerp->user1(true);
|
||||
if (exponent % 2 == 0) {
|
||||
powerp = new AstDivS{fl, powerp, basep->cloneTreePure(false)};
|
||||
powerp->user1(true);
|
||||
}
|
||||
}
|
||||
nodep->replaceWith(powerp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
iterate(powerp);
|
||||
} else {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: power expression with non constant exponent in constraint");
|
||||
}
|
||||
}
|
||||
void visit(AstPowSU* nodep) override {
|
||||
if (AstConst* const exponentp = VN_CAST(nodep->rhsp(), Const)) {
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNodeExpr* const basep = nodep->lhsp();
|
||||
V3Number numOne{nodep, basep->width(), 1};
|
||||
AstNodeExpr* productp = new AstConst{fl, numOne};
|
||||
for (uint32_t i = 0; i < exponentp->toUInt(); i++) {
|
||||
productp = new AstMulS{fl, productp, basep->cloneTreePure(false)};
|
||||
productp->user1(true);
|
||||
}
|
||||
nodep->replaceWith(productp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
iterate(productp);
|
||||
} else {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: power expression with non constant exponent in constraint");
|
||||
}
|
||||
}
|
||||
void visit(AstPowUS* nodep) override {
|
||||
if (AstConst* const exponentp = VN_CAST(nodep->rhsp(), Const)) {
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNodeExpr* const basep = nodep->lhsp();
|
||||
V3Number numOne{nodep, basep->width(), 1};
|
||||
AstNodeExpr* powerp = new AstConst{fl, numOne};
|
||||
int32_t const exponent = exponentp->toSInt();
|
||||
if (exponent > 0) {
|
||||
for (int32_t i = 0; i < std::abs(exponent); i++) {
|
||||
powerp = new AstMul{fl, powerp, basep->cloneTreePure(false)};
|
||||
powerp->user1(true);
|
||||
}
|
||||
} else if (exponent < 0) {
|
||||
// Only one division in needed because operations are on integers and base is
|
||||
// unsigned. More divisions would still result in same results.
|
||||
powerp = new AstDiv{fl, powerp, basep->cloneTreePure(false)};
|
||||
powerp->user1(true);
|
||||
}
|
||||
nodep->replaceWith(powerp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
iterate(powerp);
|
||||
} else {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: power expression with non constant exponent in constraint");
|
||||
}
|
||||
}
|
||||
void visit(AstNodeBiop* nodep) override {
|
||||
if (editFormat(nodep)) return;
|
||||
editSMT(nodep, nodep->lhsp(), nodep->rhsp());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
%Error-UNSUPPORTED: t/t_constraint_non_const_exp_pow_unsup.v:11:27: Unsupported: power expression with non constant exponent in constraint
|
||||
11 | constraint c_power { x ** y < 10000; }
|
||||
| ^~
|
||||
... 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
|
||||
#
|
||||
# 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('vlt')
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// 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
|
||||
|
||||
class Packet;
|
||||
rand int x;
|
||||
rand int y;
|
||||
|
||||
constraint c_power { x ** y < 10000; }
|
||||
endclass
|
||||
|
||||
module t;
|
||||
|
||||
Packet p;
|
||||
|
||||
initial begin
|
||||
p = new;
|
||||
void'(p.randomize());
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -8,9 +8,13 @@ class Packet;
|
|||
rand int x;
|
||||
rand int y;
|
||||
rand int z;
|
||||
rand int w;
|
||||
rand int v;
|
||||
rand bit [31:0] b;
|
||||
rand bit [31:0] c;
|
||||
rand bit [31:0] d;
|
||||
rand bit [31:0] e;
|
||||
rand bit [31:0] f;
|
||||
rand bit tiny;
|
||||
rand bit zero;
|
||||
rand bit one;
|
||||
|
|
@ -32,6 +36,15 @@ class Packet;
|
|||
z < 0;
|
||||
z > -4;
|
||||
}
|
||||
constraint c_power { e ** 32'h5 < 10000; }
|
||||
constraint c_power_ss { w ** 5 < 10000; }
|
||||
constraint c_power_us { f ** 5 < 10000; }
|
||||
constraint c_power_su { v ** 32'h5 < 10000; }
|
||||
// check for negative values in constant
|
||||
constraint c_power_neg_exp { v ** 4'shf == 0; }
|
||||
constraint c_power_u_neg_exp { f ** 4'shf == 0; }
|
||||
constraint c_power_zero_exp { v ** 0 == 1; }
|
||||
constraint c_power_u_zero_exp { f ** 0 == 1; }
|
||||
constraint impl { tiny == 1 -> x != 10; }
|
||||
constraint concat { {c, b} != 'h1111; }
|
||||
constraint unary { !(-~c == 'h22); }
|
||||
|
|
@ -91,6 +104,10 @@ module t;
|
|||
if (p.x * 9 == p.b * 3) $stop;
|
||||
if (p.y != 2) $stop;
|
||||
if (p.z != -2) $stop;
|
||||
if (p.w ** 5 >= 10000) $stop;
|
||||
if (p.e ** 32'h5 >= 10000) $stop;
|
||||
if (p.v ** 32'h5 >= 10000) $stop;
|
||||
if (p.f ** 5 >= 10000) $stop;
|
||||
if (p.tiny && p.x == 10) $stop;
|
||||
if ({p.c, p.b} == 'h1111) $stop;
|
||||
if (-~p.c == 'h22) $stop;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
%Error-UNSUPPORTED: t/t_constraint_unsup.v:9:27: Unsupported expression inside constraint
|
||||
9 | constraint cons { m_one ** 2 > 0; }
|
||||
| ^~
|
||||
%Error-UNSUPPORTED: t/t_constraint_unsup.v:9:29: Unsupported expression inside constraint
|
||||
: ... note: In instance 't'
|
||||
9 | constraint cons { x + 1.0 > 0.0; }
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Packet;
|
||||
rand int m_one;
|
||||
constraint cons { m_one ** 2 > 0; }
|
||||
rand real x;
|
||||
constraint cons { x + 1.0 > 0.0; }
|
||||
endclass
|
||||
|
||||
module t;
|
||||
|
|
|
|||
Loading…
Reference in New Issue