In this tip, you will learn how to verify a simple counter used to capture real-time performance metrics. Inside the DUT, a controller provides an indication of the received and transmitted packets via the PERFORMANCE_DATA_OUT[n:0] output, as illustrated in the diagram below:
Each bit on this output is a 1 clock-wide pulse, asserted when the corresponding event occurs (e.g. mem. wr/rd req, cfg. wr/rd req, I/O wr/rd req,…). The enable and clear inputs are controlled by performance measurement logic, as defined by the user firmware.
The test procedure involves forcing the controller’s output to a random value from the testbench and then reading and comparing the counters’ values from the registers. The steps are as follows:
1. Enable the counters.2. Force the controller output to random data and compare the counters’ values.3. Clear the counters and verify they are cleared.4. Disable the counters, force output, and check if counters remain unchanged.5. Re-enable the counters and unclear them; verify that the counters do not roll over.6. Clear the counters, force the output, and check if counters remain unchanged.
First, ensure that the local counters, which will be used for later comparison, are properly initialized. In this case, PERFORMANCE_DATA_OUT is an 18 wide variable (representing 18 counters), with each counter being a 16 bit variable.
Next, enable the counters by proper writing to the corresponding address. In this example, read and write operations (WR and RD) for the registers are performed via APB:
Next, the output can be forced with the previously randomized value, and the local counters will be updated accordingly. This process is repeated in a for-loop, 100 times. At the end of each iteration, a comparison is performed.
The next step is to clear the counters and verify that they are actually cleared, along with updating the local counters.
Similarly to clearing, disabling must also be verified. Next, force the output and check if counters remain unchanged.
To verify a critical aspect—whether the counter rolls over—we set it to a value just below its maximum, then force the output several times until the counter reaches its maximum and remains steady, regardless of the number of forces applied. It is assumed that the counters are enabled and uncleared at the start, as done in the previous steps.
Lastly, we clear all counters again (step 3) and check if they remain unchanged after a few forces of output.