Incorrectly written constraints can negatively impact aspects such as generation order or input sampling, leading to incorrect or problematic generation. A typical example is when a method accesses a generatable field which has not been passed as a parameter to the method; not passing the parameter violates the coding guidelines and prevents IntelliGen's analysis from determining the correct generation order.
The following test case demonstrates such a problem. Note that the ‘calc_checksum()' method is not passing ‘data' as a parameter, resulting in calling the method before the actual list is generated.
<'
struct packet {
checksum : uint;
data : list of byte;
zero: bool;
one : bool;
keep data == {1;1;1};
keep soft !zero;
keep soft !one;
keep checksum == calc_checksum(); // calc_checksum() samples data
keep checksum == 0 => zero == TRUE;
keep checksum == 1 => one == TRUE;
calc_checksum() : uint is {
for each (b) in data {
result = result ^ b;
};
};
post_generate() is also {
check that checksum == calc_checksum();
};
};
extend sys {
p:packet;
};
'>
The best way to detect and fix such code is through the IntelliGen guidelines linter. Running ‘gen lint -g' will trace all such issues in the user code and issue proper warning for each. For the given example, the following warning will be issued:
Specman my_cons2> gen lint -g
Gen Linter - analyzing...
Selected mode: guidelines mode
*** Warning: WARN_GEN_LINTER_G42: Accessing a generatable me field me.data
in methods called from constraints (at line 11 in @my_cons2 ) is not
recommended.
at line 16 in @my_cons2
for each (b) in data {
To change the severity, type:
set notify -severity=<new-severity-level> WARN_GEN_LINTER_G42
To see possible severity levels use 'set notify -help'
Gen Linter - analysis complete
In an ideal world, the linter can be used to keep the code 100% clean. However, in a world less ideal, the users do not often run the linter and are not always aware of the coding violations.
So suppose you ran a test and a specific constraint was ignored. The question remains how to understand what the problem is, and how to fix it. If the problem is the one discussed here, the solution is simple and composed of the following steps:
1. Open the Gen Debugger to the problematic Connect Field Set (CFS). As in the case in the previous blog, the simplest way is to run with ‘config gen -collect = ALL' (to keep all the generation information), and issue ‘show gen -instance' with the problem generated field as a parameter. Here we should issue ‘show gen -instance me.checksum' after breaking on the error.
2. When opening the Gen Debugger, choose the CFS in the process tree and trace the problematic constraint in its constraint list.
3. After choosing the constraint, examine its Linter tab. If it displays linter warnings, these could indicate the source of the problem!
Note that this is not the only case in which the Gen Debugger interacts with IntelliGen's linter. When debugging ICFSs, you can use the "inconsistency view" which includes the output of the inconsistency linter.
One final point: Starting with version 12.1, another Linter tab has been added -- this one appears in the displayed CFS information, and includes the CFS performance recommendations. (This is in addition to the constraint's Linter tab seen in this post.)
The last post in this series will demonstrate a different case of unenforced constraint -- when the constraint is a soft constraint.
Reuven Naveh
Intelligen R&D