Addressing review comments
- Renamed the command line option to specify the array limit size - Added a new test to test the command line option - Fixed the existing test to verify all the supported operators
This commit is contained in:
parent
92ff52f16e
commit
b88fc74c57
|
|
@ -1825,7 +1825,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-U", CbPartialMatch, &V3PreShell::undef);
|
||||
DECL_OPTION("-underline-zero", OnOff, &m_underlineZero).undocumented(); // Deprecated
|
||||
DECL_OPTION("-no-unlimited-stack", CbCall, []() {}); // Processed only in bin/verilator shell
|
||||
DECL_OPTION("-constraint-with-limit", Set, &m_constraintWithLimit).undocumented();
|
||||
DECL_OPTION("-constraint-array-limit", Set, &m_constraintArrayLimit).undocumented();
|
||||
DECL_OPTION("-unroll-count", Set, &m_unrollCount).undocumented(); // Optimization tweak
|
||||
DECL_OPTION("-unroll-limit", Set, &m_unrollLimit);
|
||||
DECL_OPTION("-unroll-stmts", Set, &m_unrollStmts).undocumented(); // Optimization tweak
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ private:
|
|||
int m_unrollCount = 64; // main switch: --unroll-count
|
||||
int m_unrollLimit = 16384; // main switch: --unroll-limit
|
||||
int m_unrollStmts = 30000; // main switch: --unroll-stmts
|
||||
int m_constraintWithLimit = 64; // main switch: --constraint-with-limit
|
||||
int m_constraintArrayLimit = 64; // main switch: --constraint-array-limit
|
||||
int m_verilateJobs = -1; // main switch: --verilate-jobs
|
||||
|
||||
int m_compLimitBlocks = 0; // compiler selection; number of nested blocks
|
||||
|
|
@ -636,7 +636,7 @@ public:
|
|||
int unrollCount() const { return m_unrollCount; }
|
||||
int unrollLimit() const { return m_unrollLimit; }
|
||||
int unrollStmts() const { return m_unrollStmts; }
|
||||
int constraintWithLimit() const { return m_constraintWithLimit; }
|
||||
int constraintArrayLimit() const { return m_constraintArrayLimit; }
|
||||
int verilateJobs() const { return m_verilateJobs; }
|
||||
|
||||
int compLimitBlocks() const { return m_compLimitBlocks; }
|
||||
|
|
|
|||
|
|
@ -1513,11 +1513,11 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
if (AstUnpackArrayDType* const adtypep
|
||||
= VN_CAST(nodep->fromp()->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
const int arraySize = adtypep->elementsConst();
|
||||
if (arraySize > v3Global.opt.constraintWithLimit()) {
|
||||
if (arraySize > v3Global.opt.constraintArrayLimit()) {
|
||||
nodep->v3warn(CONSTRAINTIGN, "Constraint array reduction ignored (array size "
|
||||
+ cvtToStr(arraySize)
|
||||
+ " exceeds --constraint-with-limit of "
|
||||
+ cvtToStr(v3Global.opt.constraintWithLimit())
|
||||
+ " exceeds --constraint-array-limit of "
|
||||
+ cvtToStr(v3Global.opt.constraintArrayLimit())
|
||||
+ "), treating as state");
|
||||
nodep->user1(false);
|
||||
if (editFormat(nodep)) return;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
%Warning-CONSTRAINTIGN: t/t_constraint_array_limit.v:15:12: Constraint array reduction ignored (array size 100 exceeds --constraint-array-limit of 64), treating as state
|
||||
15 | data.sum() with (item) < 1000;
|
||||
| ^~~
|
||||
... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest
|
||||
... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expectations 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('linter')
|
||||
|
||||
test.lint(fails=test.vlt_all, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Ravi Behl.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test that array reduction constraints are ignored when array size exceeds --constraint-array-limit
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
|
||||
class Packet;
|
||||
rand int data[100]; // Array size 100 > default limit of 64
|
||||
|
||||
constraint c {
|
||||
data.sum() with (item) < 1000; // This should be ignored due to array size
|
||||
}
|
||||
|
||||
function void verify();
|
||||
int i;
|
||||
i = randomize();
|
||||
`checkd(i, 1);
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
Packet p;
|
||||
int success_count;
|
||||
|
||||
p = new;
|
||||
|
||||
// Try randomization -- should fail with a warning
|
||||
p.verify();
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test case for array reduction methods with 'with' clause in constraints (issue #6455)
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
|
||||
class test_sum;
|
||||
rand byte array[5];
|
||||
|
|
@ -20,14 +22,18 @@ class test_sum;
|
|||
}
|
||||
}
|
||||
|
||||
function bit verify();
|
||||
function void verify();
|
||||
int count_map[byte];
|
||||
int repeated_count = 0;
|
||||
int i;
|
||||
|
||||
i = randomize();
|
||||
`checkd(i, 1);
|
||||
|
||||
// Count occurrences
|
||||
foreach (array[i]) begin
|
||||
if (!count_map.exists(array[i])) count_map[array[i]] = 0;
|
||||
count_map[array[i]]++;
|
||||
foreach (array[idx]) begin
|
||||
if (!count_map.exists(array[idx])) count_map[array[idx]] = 0;
|
||||
count_map[array[idx]]++;
|
||||
end
|
||||
|
||||
// Check repeated_value appears exactly 3 times
|
||||
|
|
@ -36,22 +42,20 @@ class test_sum;
|
|||
if (repeated_count != 3) begin
|
||||
$display("%%Error: sum test - repeated_value=%0d appears %0d times, expected 3",
|
||||
repeated_value, repeated_count);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
end else begin
|
||||
$display("%%Error: sum test - repeated_value=%0d doesn't appear in array", repeated_value);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
|
||||
// Check all other values appear exactly once
|
||||
foreach (count_map[val]) begin
|
||||
if (val != repeated_value && count_map[val] != 1) begin
|
||||
$display("%%Error: sum test - value=%0d appears %0d times, expected 1", val, count_map[val]);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
|
|
@ -65,28 +69,30 @@ class test_product;
|
|||
array.sum() with (int'(item != 0)) >= 2;
|
||||
}
|
||||
|
||||
function bit verify();
|
||||
function void verify();
|
||||
int prod = 1;
|
||||
int nonzero_count = 0;
|
||||
int i;
|
||||
|
||||
foreach (array[i]) begin
|
||||
if (array[i] != 0) begin
|
||||
prod *= array[i];
|
||||
i = randomize();
|
||||
`checkd(i, 1);
|
||||
|
||||
foreach (array[idx]) begin
|
||||
if (array[idx] != 0) begin
|
||||
prod *= array[idx];
|
||||
nonzero_count++;
|
||||
end
|
||||
end
|
||||
|
||||
if (prod > 100) begin
|
||||
$display("%%Error: product test - product %0d > 100", prod);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
|
||||
if (nonzero_count < 2) begin
|
||||
$display("%%Error: product test - only %0d non-zero elements", nonzero_count);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
|
|
@ -98,19 +104,21 @@ class test_and;
|
|||
array.and() with (item & 8'hF0) == 8'h50;
|
||||
}
|
||||
|
||||
function bit verify();
|
||||
function void verify();
|
||||
bit [7:0] result = 8'hFF;
|
||||
int i;
|
||||
|
||||
foreach (array[i]) begin
|
||||
result &= (array[i] & 8'hF0);
|
||||
i = randomize();
|
||||
`checkd(i, 1);
|
||||
|
||||
foreach (array[idx]) begin
|
||||
result &= (array[idx] & 8'hF0);
|
||||
end
|
||||
|
||||
if (result != 8'h50) begin
|
||||
$display("%%Error: and test - result 0x%0h != 0x50", result);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
|
|
@ -124,19 +132,21 @@ class test_or;
|
|||
array.sum() with (int'((item & 8'h08) != 0)) >= 1;
|
||||
}
|
||||
|
||||
function bit verify();
|
||||
function void verify();
|
||||
bit [7:0] result = 8'h00;
|
||||
int i;
|
||||
|
||||
foreach (array[i]) begin
|
||||
result |= (array[i] & 8'h08);
|
||||
i = randomize();
|
||||
`checkd(i, 1);
|
||||
|
||||
foreach (array[idx]) begin
|
||||
result |= (array[idx] & 8'h08);
|
||||
end
|
||||
|
||||
if (result != 8'h08) begin
|
||||
$display("%%Error: or test - result 0x%0h != 0x08", result);
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
|
|
@ -150,19 +160,21 @@ class test_xor;
|
|||
array.sum() with (int'(item != 0)) >= 2;
|
||||
}
|
||||
|
||||
function bit verify();
|
||||
function void verify();
|
||||
bit [7:0] result = 8'h00;
|
||||
int i;
|
||||
|
||||
foreach (array[i]) begin
|
||||
result ^= array[i];
|
||||
i = randomize();
|
||||
`checkd(i, 1);
|
||||
|
||||
foreach (array[idx]) begin
|
||||
result ^= array[idx];
|
||||
end
|
||||
|
||||
if (result == 0) begin
|
||||
$display("%%Error: xor test - result is 0");
|
||||
return 0;
|
||||
$stop;
|
||||
end
|
||||
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
|
|
@ -176,57 +188,27 @@ module t;
|
|||
initial begin
|
||||
// Test sum
|
||||
sum_inst = new();
|
||||
repeat (3) begin
|
||||
if (sum_inst.randomize() == 0) begin
|
||||
$display("%%Error: Failed to randomize sum test");
|
||||
$stop;
|
||||
end
|
||||
if (!sum_inst.verify()) $stop;
|
||||
end
|
||||
repeat (20) sum_inst.verify();
|
||||
$display("sum test PASSED");
|
||||
|
||||
// Test product
|
||||
product_inst = new();
|
||||
repeat (3) begin
|
||||
if (product_inst.randomize() == 0) begin
|
||||
$display("%%Error: Failed to randomize product test");
|
||||
$stop;
|
||||
end
|
||||
if (!product_inst.verify()) $stop;
|
||||
end
|
||||
repeat (20) product_inst.verify();
|
||||
$display("product test PASSED");
|
||||
|
||||
// Test and
|
||||
and_inst = new();
|
||||
repeat (3) begin
|
||||
if (and_inst.randomize() == 0) begin
|
||||
$display("%%Error: Failed to randomize and test");
|
||||
$stop;
|
||||
end
|
||||
if (!and_inst.verify()) $stop;
|
||||
end
|
||||
repeat (20) and_inst.verify();
|
||||
$display("and test PASSED");
|
||||
|
||||
// Test or
|
||||
or_inst = new();
|
||||
repeat (3) begin
|
||||
if (or_inst.randomize() == 0) begin
|
||||
$display("%%Error: Failed to randomize or test");
|
||||
$stop;
|
||||
end
|
||||
if (!or_inst.verify()) $stop;
|
||||
end
|
||||
repeat (20) or_inst.verify();
|
||||
$display("or test PASSED");
|
||||
|
||||
// Test xor
|
||||
xor_inst = new();
|
||||
repeat (3) begin
|
||||
if (xor_inst.randomize() == 0) begin
|
||||
$display("%%Error: Failed to randomize xor test");
|
||||
$stop;
|
||||
end
|
||||
if (!xor_inst.verify()) $stop;
|
||||
end
|
||||
repeat (20) xor_inst.verify();
|
||||
$display("xor test PASSED");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue