This article presents the logic behind the design and implementation of a clock frequency or period measurement block. The article walks you through the principles used in designing multiple clock blocks, listing the potential pitfalls and offers a clear and practical solution anyone can implement.
Having several clock domains on an SOC is very common, resulting in many forms of clock domain crossing (CDC) and interaction between the domains. The ability to measure the frequency or period of a clock on the chip enables integration of multiple independent clock sources on the same device and a sort of “plug-and-play”. The chip control logic can test an external clock, determine its frequency and act accordingly, saving software intervention and potential issues. Other benefits of clock period measurement are in system testing and integration, chip validation and failure debugging.
The requirements of the frequency measurement block are:
- Simple interface to control registers that enable configuration of the block and readout of the frequency measurement results.
- Clean clock domain crossing, robust for any frequency.
- Configurable frequency range, so it can fit different applications.
- Simplified synthesis and physical design.
Naturally we would also like to be able to reset and disable the block.
As the frequency measurement block is synchronous, we require a reference clock, with a known frequency, so that the external clock can be measured against. Typically, this would be the chip main control clock, but it can be any free running clock in the device which has a known frequency.
Having a reference clock enables us to measure absolute time on the chip. For example, a 250Mhz clock has a period of 4ns, so if we count 250,000 clocks the resulting time period would equal 1 second. This well-defined time period, enables us to measure the frequency of any event, just by counting the number of events within this time period. Continuing with the same example, if there is a signal that toggles 0-to-1 40,000 times during the 1 second period, its frequency is 40 MHz. This principle can be used for measuring any event, including an external clock rise and it the basis for a clock frequency measurement block.
The other aspect we need to take care of is proper synchronization between the clock domains and proper storage of the results for readout.
So the implementation is actually two counters, one measuring the time, using a known clock and the other, counting the positive edges of the measured clock. When the time counter expires, it will cause the value of the frequency counter to be sampled and the frequency counter to be reset.
The accuracy of the measurement is dependent on the number of clocks counted by the time counter. If the period of time measured is high, the averaging effect results in a more accurate measured clock frequency.
Using two different frequencies for the time and frequency counters, requires us to handle the interaction between those domains with care. The problem is that the control clock used for time counter may be much faster than the measured clock. In this case, control signals may take long time to reach the frequency counter, so if we want to sample the frequency counter value in the control clock domain we may end up sampling the wrong data.
The solution for this potential problem lies in a structure of “two-way synchronizer”. Using a two-way synchronizer ensures that when the control clock domain sends out a control signal, it will have a positive indication that the signal has reached the other side and done its role. This way, sampling of the frequency counter value will be safe.
The last missing piece of the synchronization logic is the capability to transfer pulse into level and level into pulse. Any synchronizer is well equipped to transfer level signals from one domain to the other, so we need to translate pulse events into level signals, go through the synchronizer and then translate it back into pulse. The only question asked would be “how long should the pulse be?” the obvious answer is “until the two-way synchronizer says the signal has been captured on the other side”.
Putting it all together, the implementation of the clock frequency measurement would look like that:
The physical implementation of such frequency measurement block and other relatively small designs with high clocking complexity should be based on a separate physical flow closing it apart from the instantiating block. This approach enables the physical design to generate a block which is guaranteed by construction to function properly due to the short distances of placement.
The timing of the synchronization stage between the domains should be handled as other two sampling synchronizers, by limiting the maximal delay of the paths between the clocks.
By following strict principles of design, seemingly complex blocks, such as a clock frequency measurement can be broken into manageable pieces. In this case, separating the synchronization logic and employing correct-by-design synchronization technics such as the two-way synchronizer, ensures that the design is robust enough to function at any frequency.
The on-chip clock frequency measurement logic design, Verilog code and documentation can be found in the RTLery website library clocking and reset section, where you can find the design and Verilog source code for a variety of blocks targeted at the construction of a healthy clock and reset network in your device. Please see the RTLery website clock&reset section form more details.