Hi,
I am writing a constraint and the snippet is below:
constraint next_con {
foreach (next[i])
next[i] inside {current [0 : (total_count[i]/2)]};
}
}
total_count value is constrained using a different constraint. I am seeing error during compilation.
I did try using, +: operator. But that didn’t help.
Kindly help.
In reply to naveensv:
The ‘+:’ is meant to be used when slicing a vector, not when specifying a range. The inside operator takes a range as an input, not a slice.
In reply to Tudor Timi:
Thanks for the reply Tudor.
Probably I should have been more clear when explaining the question.
I have tried to explain this a little more detailed.
current[i] is a dynamic array of size greater than that of next[i]
I need to have a constraint where next[i] is one of the values of current[i] with one more constraint on the indices of current
One typical output should look like this:
Lets assume the size of current is 10, size of next is 1 and size of total_count is 5.
next[0] should take one of the values of current [0 : 5]
Kindly let me know if I can specify a dynamic range in the constraint.
In reply to naveensv:
You can’t specify a dynamic range when slicing a dynamic array (regardless of whether it’s in a constraint or anywhere else). This is an LRM limitation. You can work around this by using an intermediary variable:
class some_class;
rand int current[], next[];
rand int unsigned total_count[];
constraint legal_total_counts {
total_count.size() == current.size();
foreach (total_count[ i]) {
total_count[ i] > 0;
total_count[ i] < total_count.size();
}
}
local rand int legal_nexts[][];
constraint next_vals {
next.size() == current.size();
legal_nexts.size() == next.size();
foreach (legal_nexts[ i])
legal_nexts[ i].size() == total_count[ i];
foreach (legal_nexts[ i, j])
legal_nexts[ i][j] == current[j];
foreach (next[ i])
next[ i] inside { legal_nexts[ i] };
}
endclass
The ‘legal_nexts’ 2D array will hold all valid values for each value of the next array. You need to construct it “yourself” using constraints. After you’re finished with it, it might be a good idea to destroy it to free up memory:
function void post_randomize();
legal_nexts = '{};
endfunction
In reply to Tudor Timi:
Brilliant !
It works for me.
But just to cross check my coding, I am trying to print the contents of legal_nexts array.
However I try to print, my simulation is getting stuck.
If I comment out that printing section, simulation proceeds smoothly.
Any idea?
In reply to naveensv:
I am retaining the legal_nexts declaration as local only and not freeing up in the post_randomize().
Should this affect the simulation so badly?
In reply to naveensv:
I’m not sure how you’re printing. I used:
$display("%p", legal_nexts);
and it worked fine for me, but I was using a small number for the array size.
W.r.t. not freeing up in post_randomize(), it depends on how big your arrays are. You’re going to be allocating a lot of memory during randomization that’s just going to get wasted afterwards. If you anyway throw away the object after randomization or only create a few objects of that class, you shouldn’t see any big improvement. The only way to say for sure if it noticeably affects performance is to do a profiler run.
In reply to Tudor Timi:
Yep, $display worked for me!
I used nested-for loop to print out the 2D contents. Probably that made the testbench slow, I believe.
I use Questa for running simulations. I will check if I can perform profiling there.
In reply to naveensv:
Hi Tudor,
I am stuck at one point where I need to get a 2D array from a one dimensional array in a constraint.
Snippet:
rand int total_count[];
local rand int legal_next[][];
constraint
total_count.size() == 2;
foreach (legal_next[i])
legal_next.size() == 2; //I am hard-coding here intentionally
foreach (legal_next[i])
legal_next[i].size() == total_count[i];
foreach (even[i])
single_dimension[2*i] = even[i];
foreach (odd[i])
single_dimension[2*i +1] = odd[i];
Now single_dimension has all elements and I need to select legal range in them.
Now I am trying to split single_dimension and assign to legal_next portion by portion
For ex:
If single_dimension = {1,2,3,4,5,6,7,8,9,10};
total_count[0] = 4 and total_count[1] = 5
Then,
legal_next[0] = {1,2,3,4}
legal_next[1] = {5,6,7,8,9}
Unfortunately I cannot use for loop in the constraint.
I tried my best to achieve this. But that didn’t help much.
Could you suggest any best way to do this?
In reply to naveensv:
It’s not really clear how total_count and legal_next are related to each other. Is it that total_count[0] selects the first t0 elements from single_dimension, followed by total_count[i] selecting the next t1 elements and so on?
In reply to naveensv:
I don’t see any way of doing it, since this would ultimately mean using a random variable to index single_dimension, which isn’t allowed by the LRM.
In reply to Tudor Timi:
Thanks Tudor for confirmation.
I made use of different single dimensional arrays to achieve the same.
Regards,
Naveen