Fractional PWM in verilog

Objective of a fractional PWM

The derivation of the equation for fractional pulse width modulation (frac_pwm) is shown along with the verilog code implementation. This code has been tested to work on a Spartan 3AN and is available on Bitbucket. My related blog was written June 4, 2016 on a fractional divider (FD) circuit for use in a PLL VCO.

The purpose of frac_pwm is to achieve higher resolution in a digital PWM motor controller without increasing the clock frequency or the PWM period. The most common digital PWM has an output frequency of  fout = Fxtal / No and sets the output high for N counts. The PWM resolution in this simple case is 1 part in No.

Derivation of the fractional PWM

The basis of the fractional derivation comes from a TI Technical Brief SWRA029. The basic principal is to count N+1 counts for m cycles and N counts for M-m cycles. The total number of PWM counts is the sum  Latex formula for a total of M cycles. The PWM signal will be set high at the beginning of each M cycle and resets when the count reaches zero.

From this simple equation the average counts per cycle is Latex formula  , which is non-integer. The incremental change in Nbar from m to (m+1) is 1/M. The fractional change in duty-cycle is Latex formula. Thus the resolution in PWM has improved by a factor of M.

Implementation

In the verilog code M this is parameterized by the constant fsze. Using fsze= 3 (bits) we have M=8. In effect we are using the input divide as an integer with fractional bits, yyyy.xxx.

The verilog implementation has three counters. The period counter is dividing by the integer count No to give a fixed frequency PWM. Two other counters, mcnt and Mreg, control the PWM duty-cycle. The mcnt counter decrements when the period counter under flows, down counting from M-1 rolling to 0 giving M windows designated from [M-1:0]. The third counter, Mreg, reloads every time the period_counter reaches 0 and is loaded with N+1 if mcnt < m and otherwise is loaded with N. 

The code was simulated using Veritakwin and synthesized using Xilinx Project Navigator 14.7. A plot of the pertinent signals is shown below.

In this example the clock is divided by 4000 (16'h0fa0) to achieve a 25kHz period and the fractional pwm word is 1000 (16'h03e8) for the integer portion and 1 (1'h1) for the fractional portion. The value for M is 8 (2^3).

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top