Pulse Width Modulation
A pulse-width modulator (PWM) circuit is often used as a simple digital to analog converter to produce analog waveforms that require only relatively low frequencies, typically less than 100KHz. Many digital devices like microprocessors and FPGAs use pulse-width modulation to create low-bandwidth analog signals because they require few resources – just a single output pin and a simple passive RC filter. The digital part of a PWM circuit functions by generating a chain of pulses at some fixed frequency, with each pulse potentially having a different width. This digital signal is passed through a simple low-pass filter that integrates the digital waveform to produce an analog voltage proportional to the average pulse width over some interval (the interval is determined by the RC time constant and the pulse frequency). For example, if the pulses are high for an average of 10% of the available pulse period, then an integrator will produce an analog value that is 10% of the Vdd voltage.
The PWM signal must be integrated to define an analog voltage. The integrator 3dB frequency should be an order of magnitude lower than the PWM frequency, so that signal energy at the PWM frequency is filtered from the signal. For example, if an audio signal must contain up to 5KHz of frequency information, then the PWM frequency should be at least 50KHz (and preferably even higher). In general, in terms of analog signal fidelity, the higher the PWM frequency, the better.
The figure below shows a representation of a PWM integrator producing an output voltage by integrating the pulse train. Note the steady-state filter output signal amplitude ratio to Vdd is the same as the pulse width duty cycle (duty cycle is defined as pulse-high time divided by pulse-window time).
The PWM “window” frequency defines the regular, recurring starting point of a pulse. For anything other than a 0V output, there will be a pulse rising edge at the start of every new pulse window. Then the length of the ensuing pulse will determine the resulting analog voltage. Before you design a PWM circuit, you must know (at least) the maximum frequency content and dynamic range of the analog signal you intend to produce, as well as minimum clocking frequency you can use to produce the PWM waveform.
As an example, let’s look at a PWM signal used to produce a single-channel audio output to drive a speaker at a fast food drive-through window. The design specifications will require that the audio signal have something like up to 10KHz of signal bandwidth, and perhaps a 48dB dynamic range (dynamic range, or DNR, is the ratio between the smallest and largest reproducible output signal). A 48dB DNR requires an 8-bit digital value (an 8 bit number can have 256 values, and 20 x log10(256) = 48dB). So, each pulse window must support a pulse that can have up to 256 different widths.
If we want to preserve 10KHz of bandwidth in the resulting analog signal, we must use a window frequency of at least 10x the analog bandwidth, or 100KHz in this example. Each window must support 256 pulse width end points, so we need to have time slices that are (1/(256 x 100KHz)), or 40ns long. That is certainly possible with an FPGA-based custom circuit based on counters, but that is too short a time slice to be manageable through software running on a processor.
As a second example, let’s say we want to control the brightness of an LED. In this case, we need to define two things: the maximum frequency at which we want to vary the LED between maximum brightness (totally on) and minimum brightness (totally off); and the number of brightness levels. If we want to ramp the LED between “all off” and “all on” in one second (seems reasonable!), and if we want 16 different brightness levels (also seems reasonable), then we need a period of 1/(16 x .5Hz), or 125ms. That period is easily manageable by software running on a processor.
Pulse Density Modulation
A Pulse Density Modulator (PDM) circuit is a variation on the PWM that works in a similar fashion. Like a PWM circuit, a PDM circuit drives a digital pulse train on a single digital pin, and a low-pass filter integrates the digital signal to produce an analog signal. But in a PDM circuit, the pulse widths are constant, but the period between the pulses change.
A PDM has the advantage of switching more frequently than a PWM circuit, and so the resulting waveform can have higher bandwidth or better characteristics. Consider a PWM with an 8-bit sample (and so 256 different pulse widths). To achieve an analog voltage that is 50% of Vdd, the PWM would have one pulse that terminates at 128 clock cycles, but the PDM would alternate between high and low on every clock. In trade-off, the PDM signal requires more overhead to produce.
Both PWM and PDM circuits are frequently used in many different digital systems. We will use both in upcoming projects.
The Blackboard PWM IP Block
The PWM IP block included in the Blackboard_standard_config file is a general PWM solution that allows for maximum configurability. It contains eight independent PWM circuits, and each PWM accepts two 32-bit parameters: a divider value to divide the 100MHz input clock to a pulse window period, and a pulse-width value to determine how long each pulse should be within the pulse window. Both parameters specify a number of 100MHz clock cycles (10ns each).
For example, if 100,000 decimal (or 0x185A0) is programmed into the period register, a 1KHz frequency (or 1ms period) will result. There are 100,000 10ns clock periods in each 1ms period, so setting the width register to 50000 will result in a 50% duty-cycle PWM output.
The PWM IP block registers are shown below.
PWM_EN (0x43C000XX (XX-00/10/20/30/40/50)): Enable individual PWM generators (write only). Bit0 turns on/off corresponding PWM.
EN: Enable PWM (1 to enable).
PWM_PERIOD (0x43C000XX (XX-04/14/24/34/44/54)): PWM Period definition (write only). 32-bit divisor to establish PWM frequency.
PERIOD: Divisor value applied to system clock (100MHz) used to establish PWM period/window frequency.
PWM_WIDTH (0x43C000XX (XX-08/18/28/38/48/58)): PWM pulse width (write only). 32-bit value determines pulse length from start of PWM period.
WIDTH: Length of PWM pulse in system clocks (100MHz).