Specman e: Is there a way to constrain the amount of set bits in a number?

1.2k Views Asked by At

I have unit field events:

events:uint;

The values of events not so interesting as the amount of set bits in it. I would like to constrain the ranges of the amount of set bits in the events. Is there a way to do it? Thank you for your help.

3

There are 3 best solutions below

0
On BEST ANSWER

There might be an easier way to do it, but you can use bit slicing to constrain a list of uints to equal the bits of your variable, and use sum to constrain their amount.

The following example does what you need (limited to a 4 bit variable for brevity):

<'
extend sys {
    events : uint(bits:4);
    b: list of uint(bits:1);
    keep b.size() == 4;

    keep b[0] == events[0:0];
    keep b[1] == events[1:1];
    keep b[2] == events[2:2];
    keep b[3] == events[3:3];

    keep (b.sum(it) == 2);
};
'>

Writing all the constraints is probably a little ugly, but it can easily be done using a define as computed macro.

0
On

This is only a partial answer.

You can use events[..] or %{events} to convert from a vector to a list containing the bits of that vector. Using it directly in a constraint directly doesn't work, because it complains there's no generative element:

extend sys {
  events : uint(bits:4);

  // neither of these compile
  keep events[..].sum(it) == value(2);
  keep %{events}.sum(it) == value(2);
};

This is probably a case for Cadence.

What is allowed however is to create an intermediate list and assign that to the output of either of these operators:

extend sys {
  events_bits : list of bit;
  keep events_bits == events[..];
};

You would think that you could then constrain this list to have a certain number of 1s:

extend sys {
  // these constraints apply, but aren't enforced
  keep events_bits.sum(it) == value(2);
  keep events_bits.count(it == 1) == value(2);
};

This doesn't work however. Even though the constraints are there, they don't get enforced for some reason. This is another issue for Cadence to look at.

Summarizing, if these issues weren't there, you could probably count the number of ones easily. Maybe in a future version of Specman. I still hope that at least seeing that the [..] and the %{} operators exist will help you for other things.

0
On

The operations [..] and %{} aren't generative therefore they considered as inputs in the constraints.

The constraint:

keep events_bits == events[..];

is equivalent to:

keep events_bits == read_only(events[..]);

The generator will generate events and only then will enforce the constraints on `events_bits.

You can do the following:

extend sys {
    events : uint;
    events_bits_on [32] : list of bool;
    keep for each in events_bits_on {
        it == (events[index:index] == 1);
    };
    keep events_bits_on.count(it) == 2;
};