Swapping bits improves performance of FPGA-PWM counter
When you need some analog outputs and you have an FPGA in your system, you probably choose to use a PWM module and a simple lowpass filter such as those in Figure 1. The output of the FPGA is typically a waveform with a fixed-frequency, variable-duty cycle, which a counter and a digital comparator generate (Listing 1).
Figure 1 A simple lowpass filter changes the PWM digital output from an FPGA to an analog voltage level. The maximum ripple occurs at a 50% duty cycle.
Suppose that Enable is high, the counter counts up every clock cycle, and the frequency of the PWM output is the clock frequency divided by 2 count bits. You can use Enable to lower the output frequency by connecting it to a prescaler. Because the output frequency is fixed, the filter is easy to calculate, because you know that the worst-case ripple happens at a duty cycle of 50%. The combination of the desired maximum ripple and settling time determines the filter type and RC (resistance/capacitance) values.
With a small change to the code in Listing 1, you can improve the performance of the PWM circuit. Whereas in the original system, the maximum ripple currents occur at a duty cycle of 50% and the minimum ripple currents occur at the minimum duty cycle, the improved version shows a maximum ripple equal to the minimum of the standard version. The trick is to generate the highest frequency possible but keep the average duty cycle constant. The higher the frequency of the pulses on the output, the better the filter does its job.
The modification to Listing 1 consists of rewiring the binary comparator with all the bits swapped from left to right. The MSB (most significant bit) becomes the LSB (least significant bit), the LSB becomes the MSB, and so on (Listing 2). You do only a rewiring requiring no extra registers or logic.
Listing 3 shows the pulse trains that a 4-bit PWM emits. In Listing 3, you see that at 50% duty cycle (Value=8, second column), the frequency is maximum and equal to the clock frequency divided by two. At the first point at which some ripple shows up (Value=1, second column), there is exactly the same ripple as in the conventional PWM system—that is, the pulse train is the same.