Many microprocessor applications require a precise time base. For example, consider a microprocessor-based system that drives a time-of-day display, like a watch or microwave oven controller. To know when to update the display, the processor must have an accurate way to measure time. One way to measure time is to calculate the execution time of a sequence of instructions, and then carefully control the software so that the same sequence is executed during each time interval. Using this method, a simple loop might update a counter that is keeping track of time, and then update the display based on that counter. An N-instruction loop will execute for (N x P x M) ns, where P is the clock period and M is the number of clocks per instruction. To establish an exact time increment (for example, within 100ns of a specified target time), some number of “padding” instructions would need to be added to the processing/loop time.
Achieving accurate times following this method is difficult, because all instructions times must be counted. Any processes that are not in the main timing loop (like dealing with occasional pushbutton inputs) would need to be factored in, and any modifications to the code would require recalculating loop times. And further, simply “burning” time by executing dummy loop instructions is inefficient.
As a second example, consider an analog-to-digital converter used to digitize an audio track. A typical sampling rate might be 100K samples/sec, which means a new sample is recorded every 10us. The processor could try to execute a timing loop to burn exactly 10us between each reading of the ADC (around 1000 instructions if the CPU clock was 100MHz), but it would be difficult to execute the exact number of instructions needed to precisely span 10us. And again, if the processor needed handle other occasional or sporadic tasks, it would be difficult to get back into the same timing cadence. Also, when dealing with waveform sampling in particular, a very accurate time base is needed because any sample-to-sample time variations create distortion. Consider the figure below – a sample that is too early or too late will result in the waveform being sampled at higher or lower voltage than it should have been, and the difference distorts the digitized waveform. The larger the timing error, the larger the distortion.
The same problem exists in when recreating an analog signal from a digital source – any timing discrepancies in sending digital samples to a digital-to-analog converter will result in distortion in the reconstituted analog waveform.
As a third example, many applications produce periodic waveforms to control sensors, motors, or other external devices that need an accurate timing signal to function properly. Often, these waveforms use a time-based modulation encoding (like pulse-width modulation) that requires an output signal to be regularly updated at a moderately high speed. Such a signal could be created from software loops, but all the same issues discussed above are again relevant. Accurate time bases are also needed for lower frequency applications (e.g., under 100Hz), like checking ambient lighting conditions or system voltages or temperatures. Hundreds of millions of instructions would be executed between samples, and keeping track of time by counting instruction execution times would be extraordinarily difficult.
In virtually any situation where a processor must record, produce, or process information on a precise time schedule, it simply is not practical generate a suitable time base by tracking instruction execution times. Instead, and independent counter that runs continuously without any involvement or interference from the processor can be used. Virtually all CPUs (and certainly those used in embedded applications) include such a timer/counter as one of their major features.
A typical timer circuit uses the same clock input as the CPU, so that it can run as fast as possible while remaining independent from the CPU. Timer circuits typically include several programmable comparators as well to indicate when the counter value is equal to any given number (corresponding to a given time interval). With such a timer circuit, the CPU has several options – it can read the timer directly, it can poll the output of a comparator, or interrupts can be generated from comparator outputs.
Two major timing circuit architectures are prevalent. In the simplest architecture, the counter free-runs forever, and always indicates the elapsed time since the last reset. These counters are typically large (e.g., 48-64 bits) since they run forever, and they typically use the fastest available clock. If comparators used to detect time intervals, they need to be updated at the end of each interval, before a new interval can be detected. For example, to measure 10us from a 100MHz clock, a comparator would first be programmed to detect 100,000. But to measure the next 10us, the comparator value would need to be set to 200,000, and so on.
In the second major architecture, the counter doesn’t run continuously forever, but is instead reset back to 0 at the end of an interval. This allows the use of smaller counters (e.g., 16-24 bits), and comparators used to measure intervals don’t need to be reprogrammed at each interval because the counter resets back at 0. This type of timing circuit is often used for creating periodic waveforms.
The ZYNQ chip provides both types of timing circuits. One, called the “global counter”, uses a 64-bit counter clocked at 333MHz. It starts automatically when power is applied, and starts counting from 0 to 2^64, updating once every 3ns. If allowed to run (i.e., if power is not removed), it will count 3ns intervals continuously for 1750 years (2^64 is a big number!). Applications can use the global timer to generate highly accurate periodic interrupts, allowing processing steps to be completed on a precise and accurate schedule.
The second timing circuit, called the “triple timer counter” (TTC), uses resettable counters to produce periodic waveforms that can control sensors, motors, or other external devices that need an accurate time base. This same timing circuit can also be used to measure input signals that might arise from sensors or other apparatus. ZYNQ’s TTC circuits use 16-bit counters and a programmable clock to create (or measure) periodic waveforms. The period and duty cycle of waveforms can be accurately and easily controlled by writing a few values to configuration registers.
The outputs from both ZYNQ timer circuits can be polled, they can generate interrupts, and they can be sent to the FPGA or off-chip to control IP blocks or external devices.