1. Variable declarations
First, registers used to represent special information should adhere to predefined legal patterns (i.e., number of bits on/off, gray_code, odd_parity, even_parity, one-hot, one-cold). For instance, the register declarations below require that the bus_state is one_hot encoded, individual bits in int_mask are mutually exclusive and hdl_cmd will only have the legal values. In addition, there may be legal patterns that happen very rarely. Capture them to ensure they are covered by functional verification.
Next, when registers are used as counters, they should behave accordingly (i.e., consistent with all parameters for minimum, maximum, range, value, decrement, increment, delta, underflow, overflow and so on). For instance, in the register declarations below, we want to ensure hdr_adr is within the range of 1 to 26. And for the bus_cnt, it should not underflow and overflow. For counters, it may be interesting to find out whether they have hit the high-water marks. The verification team can perform more coverage analysis but will need to know the locations of these counters, pointers to which can often be found in coverage properties.
In addition, important control registers (status, address and state) should be reset correctly and should not have X or Z bits (i.e., signals should be known and driven). For instance, the hdr_status register should be known when it is valid.