In the first two episodes of this blog series, we saw how we put in place an efficient formal testbench for a cache, how we found a genuine bug, reproduced a deadlock bug and found a design fix. At this point we were confident that no other deadlock bug exists. This episode shows how we verified powerful assertions, and how we prepared the formal testbench to verify end-to-end properties (an end-to-end property checks the DUT outputs against what has been seen on its inputs), along with new best practices.
An essential property
Actually, let’s start with a property that is not end-to-end but that is essential for a cache. This property is the only one we will have to check internal details. It verifies that, upon a hit request in the cache, the hit is in only one way. If that is not respected, there is a strong ambiguity about which data to read or write.
hit_onehot: assert property(i_ucache.i_hit_stage.is_hit |-> $onehot(i_ucache.i_hit_stage.hit_way);
When a lookup is performed in the cache, the address is split into a tag (123 in the following figure), an index (1), and an offset. The index is used to address tagram ways. If the content of this index is valid and the tag is the same in two ways (0 and 2 below), this is a “multiple hit”, and a serious problem. Many potential design bugs can be seen as a violation of this property.
Click here to read more ...