Digital Signal Processing Logic

Phase Accumulators

Wagner Lipnharski says:

I got interested to analyze the performance of Phase Accumulators. Paul was very gentle explaining it, kind enough to type about it after midnight and all.

I put both versions (auto-reload and phase accumulator) side by side, with their pros and cons. I also made a PC program to calculate the jitter of the Phase Accumulator technique, you will see the download link at the end.

In both versions, it is necessary a timed routine, very steady in time, driven by a timer interrupt or by a non interruptible software time loop. Any error or slack in this routine would be transferred to the output signal and accumulated along the time.

AUTO-RELOAD

The first and old way, using Auto-Reload decrement (or increment) counters, is based in load a counter with a certain value, and decrement it each time the timer routine loops. When the counter goes zero, the routine flips an output port pin, and reloads the counter with that certain value again. As each loop of the timer routine has a specific and steady period of time, you can say this old way generates an output signal at the port pin, that is directly related to the timer routine period x the specific reload value.

Lets say that the timer routine loops once every millisecond, then the output can be programmed to flip each 1ms, 2ms, 3ms, 4ms... and so on, and you would have only "integers" as result. It is basically a multiplier of the timer routine period. As it deals with periods, the frequency in Hertz is difficult to produce constantly as integers results.

This routine generates a very steady signal all along, and its counter can be used to generate a perfect tooth saw generator via an DAC. The use of a even/odd zero flag can be used to read the counter value, invert it and generate a nice triangular wave form.

This routine only outputs something based on the carry or zero counter, and no counter bit(s) can be used to identify a half counting or something like that.

The processing at each loop is faster, since requires only an instruction to decrement the counter and check for carry, even that it is necessary to reload the counter at each carry.

As you can see, this routine can generate a pulse as short as the timer routine period, and long as many bits allocated to the decrementing counter.

PHASE-ACCUMULATOR

The Phase Accumulator way, use a full bits counter to produce a carry, or rollover situation. This system requires a timer routine that generates pulses in a quantity enough to fit into the counter in the period of one second. As Paul said as example; a 16 bits counter has 65536 combinations, so it requires a timer routine that generates 65536 pulses per second, or a period = 15.29µs. Now, there is this "adder" value, that represents how many steps the counter will advance at each loop of the timer routine.

If the adder is set to "1", the counter will advance one by one, it will take 65536 pulses to generate a carry, so, it will take a whole one second, 1 carry per second.

If the adder is set to "2", the counter will need 32768 pulses to generate the carry, and it will take 0.5 second, 2 carries per second.

The rollover

If the adders is set to "10", the counter will advance in 10 steps, so needing 6553.6 steps..oops, it will carry only at the 6554th loop, and will rollover the value (6554-6553.6)*10 = 4, so now the counter is not starting from zero, then it is 4 counts shorter, or 65532.

Now, the next carry will require 6553.2 steps, ooops again, it will carry only at the 6554th loop, and will rollover the value (6554-6553.2)*10 = 8, so the counter is again shorter, or 65528.

The next carry will require 6552.8, oops again, the carry will happens only at the 6553th loop and will rollover (6553-6552.8)*10 = 2, but wait, this carry happened one loop count before the first two above. This is the jitter generated by this system. Some pulses are larger, some are shorter, and in average they generate the expected pulses per period of time.

This system is based in a division factor of a carry "1" by a fixed period of time, that generates frequency, so one can say you set the "adder" with the frequency, in Hertz, and it generates that number in pulses per second. Of course your adder should be set to the double of the expected frequency if your routine flips the PORT pin each time a carry happens, or set your timer routine with the double frequency of the counter bits combination.

As this routine generates frequency in integers relative to the counter bits and timer frequency, the period of those output pulses are not integers.

This routine can also be used to generate wave forms based on its counter bits. The advantage is that for example the counter high order bit can be considered the polarity, or even representing the signal output when the timer routine frequency is equal to the counter bits combinations.

This routine needs extra processing each loop, since there is an addition involved.

If 2^n (n:counter bits) = 1 ÷ (timer routine period), then this routine can generate a pulse short as the granularity of the timer period, and largest as 1 second. To expand this time, or increase the counter bits or increase the timer routine period.

Results

It sounds that whenever you need a fixed period of time (as a time delay), as any integer multiple of the timer routine period, you should use the *auto-reload* technique, and when you need fixed (jitter) *frequency* you should use the Phase Accumulator technique.

With the *auto-reload* is impossible to generate 1200 Hz from a 8MHz crystal, because the division does *not* result in an integer value, but you can generate 3ms, 50ms, 60ms, or 139ms based on a timer routine loop of 1ms.

By the other side, the Phase Accumulator system can not generate frequencies whose periods are 60ms and then 50ms, just by changing the "adder" value, because the division of both frequencies does not generate an integer result. (20 ÷ 16.666666666666666... is not integer)

To understand better the jitter generated, and its timings, I produced a PC software, named PHAS_CAL.EXE, it is available at my website http://www.ustr.net/files/phas_cal.exe it was produced by me, so I know that there is not any nasty virus inside. Running this software you will need to entry how many bits will be used at the counter and what is the output frequency required (adder). It will show you all the loops, frequencies, averages and rollovers, and at the reset point (if any) it will show you the average jitter timings. If he loop count takes too long, press any key to interrupt and see the results. If you want to write the screens text in a file, use the "redirect DOS function", command PHAS_CAL.EXE > X.TXT and when a blank screen appears, type the number equivalent of the counter bits, press enter, enter the "adder" frequency value, press enter, press enter again and wait. When it finishes, the file X.TXT will contains all the story.

The Phase Accumulator has a maximum jitter equivalent to the granularity of the timer routine period. If using the 16 bits counter and the timer routine looping 65536 times per second, the jitter will have a max value of 15.2µs. The jitter in Hertz turns to be problematic when the relation between the timer routine period and the signal generated period is small. Example, using a 16 bits counter, 15.2µs (65536 counts/second) and wanting to generate 4800 Hz (value at the adder), it will create a jitter of 9.96µs, that represents an unstable delta frequency of 241Hz, or an instantaneous frequency error of 5.02 percent. This error is bigger than the clock jitter when generating baud rate for async communications. See http://www.ustr.net/8051pc/starting.htm as an explanation about it (Clock Speed, almost 3/4 down the page). In time, the average of 4800 cycles/second is achieved.