user3070156
user3070156

Reputation: 11

systemverilog constraint dist using weights array

I need to be able to set a constraint dist with 64 different, changeble weights:

I need to random pick an index of range 0~63, when every index has its own weight / probability to be chosen.

I can write something like:

constraint pick_chan_constraint {pick_channel dist{ 0:=channel_weight[0], 1:=channel_weight[1], 2:=channel_weight[2], 3:=channel_weight[3], 4:=channel_weight[4], 5:=channel_weight[5], 6:=channel_weight[6], 7:=channel_weight[7], 8:=channel_weight[8], 9:=channel_weight[9], 10:=channel_weight[10], 11:=channel_weight[11], 12:=channel_weight[12], 13:=channel_weight[13], 14:=channel_weight[14], … ...

NUM_OF_CHANS-1 := channel_weight[NUM_OF_CHANS-1] }}

Obviously it's bad writing and a bad idea, out of 2 reasons:

No flexibility- if NUM_OF_CHANS changes, I'll need to change the code.

It's long and ugly and almost unreadable.

Any ideas?

Thanks

Upvotes: 1

Views: 3426

Answers (1)

Greg
Greg

Reputation: 19112

IEEE Std 1800-2012 § 18.5.4 Distribution shows the dist_list needs to be a list of dist_items and a dist_item is defined as a value_range [ dist_weight ]. In other words the distribution needs to be listed out.

Instead of using a constraint you could create a queue array (§ 7.10 Queues) and then use the shuffle method (§ 7.12.2 Array ordering methods). Example:

int channel_weight [64];
int pick_channel;
int weight_chain [$];

weight_chain.delete(); // make sure it is empty
foreach (channel_weight[i]) begin
  repeat (channel_weight[i]) begin
    weight_chain.push_back(i);
  end
end
weight_chain.shuffle(); // randomize order
assert( weight_chain.size() > 0) else $error("all channel_weights are 0");
pick_channel = weight_chain[0];

Upvotes: 1

Related Questions