Hi,
If I got huge int array and want to make sure every N (a big number, e.g 100) element, there is must have a specific value within this range.
for smaller N, I can handle in following way, how about big N range?
If N is huge, and constraint block doesn’t support for-loop, how can I achieve it?
Thanks for any suggestion.
example : N = 5 : every 5 entries, there is exact 1 specific value in this range.
class my_item;
rand int vec[1000];
rand int val;
constraint c {
val == 1;
foreach(vec[i]) {
// iterage array and check N=5 entry subgroup here
(i inside {[2:vec.size-3]}) ->
( (vec[i-2]==val) + (vec[i-1]==val) +
(vec[i]==val) + (vec[i+1]==val) +
(vec[i+2]==val)
) == 3'd1; // exact 1 entry == val is allowed
}
}
endclass
class A;
rand bit [7:0] vec[20];
rand bit [7:0] val;
int N=5;
constraint c_range {
foreach (vec[ii]) ii % N == 0 ->
vec.sum() with (int'(item == val && item.index inside {[ii:ii+N-1]})) == 1;
}
endclass
module top;
A a=new;
initial repeat (10) begin
assert(a.randomize());
$display("val: %0d %p",a.val,a.vec);
end
endmodule
In reply to dave_59:
Thanks, Dave.
It’s good to know we have item.index syntax!
level up!
I was also able to solve this question by
class A
rand bit [7:0] vec[20];
rand bit [7:0] val;
int N=5;
rand int j[];
function new();
j = new[20/5]; //calculate the number of indexes for val
endfunction
constraint c_range {
foreach(j[i]) j[i] inside {[0:N-1]}; //calculate those indexes
foreach(vec[ii]) {
if((ii % N) == 0) {
vec[ii + j[ii/N]] == val; //add the val to those indexes
}
}
solve j before vec;
}
endclass
In reply to jsaluja:
using extra memory to store random offset isn’t a great move.
prefer a light weighted solution to offload random solver, but thanks.
it like this code to me ha
int q[$];
int a[5];
int val = 111;
repeat(9999) begin
std::randomize(a) with { a.sum() with (int'(item==val)) == 1;};
q = {q, a};
end
In reply to dave_59:
class A;
rand bit [7:0] vec[20];
rand bit [7:0] val;
int N=5;
constraint c_range {
foreach (vec[ii]) ii % N == 0 ->
vec.sum() with (int'(item == val && item.index inside {[ii:ii+N-1]})) == 1;
}
endclass
module top;
A a=new;
initial repeat (10) begin
assert(a.randomize());
$display("val: %0d %p",a.val,a.vec);
end
endmodule
What if this was a 10x10 2D array, where I want a value of 1 to be present atleast once if the item index was between 3 and 7 ?
I have this so far but it doesn’t work:
rand int arr[10][10];
constraint C {foreach(arr[i,j]){arr[i][j] inside {[1:50]}};};
constraint C1{foreach(arr[item1,item2]){
arr.sum(item1) with (item1.sum(item2) with (int'(item2==1 && item2.index inside {[3:7]}))) ==1;
}}
In reply to Tr0408:
Not sure if you meant for both dimension indexes to be constrained or just one.
class A;
rand int arr[10][10];
constraint C {foreach(arr[i,j]){arr[i][j] inside {[1:20]}};}
constraint C1{
arr.sum(item1) with (item1.index inside {[3:7]} ?
item1.sum(item2) with (item2.index inside {[3:7]} ?
item2 == 1 : 0)
: 0 ) > 0; // at least once means a sum greater than 0
}
endclass
module top;
A a = new();
initial repeat (5) begin
assert(a.randomize());
$display("arr = ");
foreach(a.arr[i]) begin
foreach(a.arr[,j]) $write("%3d", a.arr[i][j]);
$display;
end
end
endmodule
In reply to dave_59:
Hi Dave,
Looks like you missed one thing in code. please review below code once
class A;
rand bit [7:0] vec[20];
rand bit [7:0] val;
int N=5;
constraint c_range {
foreach (vec[ii]) (ii % N == 0 && ii < (vec.size-N+1)) ->
vec.sum() with (int'(item == val && item.index inside {[ii:ii+N-1]})) == 1;
}
endclass
module top;
A a=new;
initial repeat (10) begin
assert(a.randomize());
$display("val: %0d %p",a.val,a.vec);
end
endmodule
In reply to rambabu_g:
I don’t think the
&& ii < (vec.size-N+1 is necessary. Can you explain a case where you think it is needed.