Can I use a dynamic array to set a distribution?

Hi All

I have a class that defines a packet. I am now adding the ability to force errors. The error type is defined in a integer enum. The distribution is a a dynamic array of unsigned inegers that I want the user to be able to set. Because I want the code to be easily expandable I want to use a foreach inside a constraint to set the dist on the error variable:

rand pkt_err_t pkt_err;
int unsigned pkt_err_dist;
bit enable_errors = 0;

constraint c_error_select { pkt_err dist { foreach(pkt_err_dist[i]) i := pkt_err_dist[i] }; }

The problem here is the compiler doesnt like the foreach inside the dist. My intention is that if more errors are added in the future, they are added to the enum and it all cascades neatly into the class, and I dont need an explicit dist assignment here, like this:

constraint c_error_select { pkt_err dist { ERROR_1_E := pkt_err_dist[ERROR_1_E], ERROR_2_E = pkt_err_dist[ERROR_2_E] }; }

Because doing this would require an update to the enum and to the error distribution table.

So can I do what Im trying to do above?

Here are two different approaches to meet your requirements

You can build an array of error types with each error enum inserted into the array as many times as needed to get the proper distribution.

rand pkt_err_t pkt_err, pkt_err_q;
int unsigned pkt_err_dist[pkt_err_t];
foreach(pkt_err_dist[t]) repeat(pkt_err_dist[t]) pkt_err_q.push_back(t);

Then you can either select a random index

pkt_err =pkt_err_q[random_var];

or shuffle the queue.

pkt_err_q.shuffle();
pkt_err =pkt_err_q[0];

Another approach is similar to a memory allocation manager. Suppose your distribution array had value 4 error types: 10, 5,20, 10. You can map those values into 4 ranges 0-9,10-14,15-34, and 35-44. Then you can pick a random value between 0-44 and select the error that is inside the range for that error type.