Keeping Your Constraints in One Basket

Doing constrained random verification is pretty easy on paper. You know what the transactions look like and what constraints you want to apply to their fields. It gets trickier when you want to convert this intent into a real life verification environment by building all the sequence items and sequences. If done improperly, this can lead to a lot of doubled up work. A problem I've hit a couple of times is how to handle my constraints so as to avoid scattering them all over the place.

This is a companion discussion topic for the original entry at

constraint dont_cross_1kb_c {
burst inside { VGM_AHB_INCR4, VGM_AHB_INCR8, VGM_AHB_INCR16 }
→ addr[10:0] <= 'h4_00 - vgm_ahb_get_num_transfers(burst) * 2**size;

This constraint is producing:
Warning: RC_1013 …/sv/vgm_ahb_seq_lib.svh(45): Randomization failed. Cyclic dependency between functions with random arguments detected.

burst inside { VGM_AHB_INCR4, VGM_AHB_INCR8, VGM_AHB_INCR16 }
a constraint or a conditional?

It should be interpreted as a conditional in thit context. The idea is that the solver chooses a value for ‘burst’ and then based on the value it chose it constraints ‘addr[10:0]’.

The constraint is uni-directional (because given an ‘addr’ we can’t constrain the ‘burst’), but it doesn’t create any cyclical dependency, just an ordering. This is described in the IEEE 1800-2012 standard in section ‘18.5.12 Functions in constraints’.

It might be that your simulator doesn’t like ‘->’. Try using ‘if (burst …) addr == …’ instead.