DEV Community

Hedy
Hedy

Posted on

Generating a PWM Square Wave Using an FPGA

Generating a PWM (Pulse Width Modulation) signal with an FPGA involves configuring a counter-comparator logic block to control the duty cycle and frequency. Below is a step-by-step guide using Verilog/VHDL for implementation on Xilinx (Artix-7/Kintex-7) or Intel (Cyclone/MAX 10) FPGAs.

Image description

1. PWM Basics

  • PWM = A square wave with adjustable duty cycle (pulse width) and frequency.
  • Duty Cycle = (ON time) / (Total Period) × 100%
  • Frequency = 1 / (Total Period)

2. Hardware Requirements

  • FPGA Board (e.g., Xilinx Artix-7, Intel Cyclone IV).
  • Clock Source (e.g., 50 MHz onboard oscillator).
  • Output Pin (connected to LED, motor driver, or oscilloscope).

3. PWM Implementation in Verilog
A. Simple PWM Generator

verilog
module pwm_generator (
    input clk,          // FPGA clock (e.g., 50 MHz)
    input reset,        // Active-high reset
    input [7:0] duty,   // 8-bit duty cycle (0-255 = 0%-100%)
    output reg pwm_out  // PWM output signal
);

reg [7:0] counter;      // 8-bit counter (0-255)

always @(posedge clk or posedge reset) begin
    if (reset) begin
        counter <= 0;
        pwm_out <= 0;
    end
    else begin
        counter <= counter + 1;
        pwm_out <= (counter < duty) ? 1 : 0;  // Compare & set PWM
    end
end

endmodule
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • duty controls the ON time (e.g., duty = 128 → 50% duty cycle).
  • Frequency = clk_freq / (2^counter_bits) (e.g., 50 MHz / 256 ≈ 195.3 kHz for 8-bit counter).

B. Adjustable Frequency PWM
To control both frequency and duty cycle, add a period register:

verilog
module pwm_advanced (
    input clk,
    input reset,
    input [15:0] period,  // Total clock cycles per PWM period
    input [15:0] duty,    // ON time (must be ≤ period)
    output reg pwm_out
);

reg [15:0] counter;

always @(posedge clk or posedge reset) begin
    if (reset) begin
        counter <= 0;
        pwm_out <= 0;
    end
    else begin
        if (counter >= period - 1)
            counter <= 0;
        else
            counter <= counter + 1;

        pwm_out <= (counter < duty) ? 1 : 0;
    end
end

endmodule
Enter fullscreen mode Exit fullscreen mode

Example Settings:
For 1 kHz PWM with 50 MHz clock:
period = 50,000,000 / 1,000 = 50,000
duty = 25,000 → 50% duty cycle.

4. PWM Implementation in VHDL

vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity pwm_generator is
    Port (
        clk   : in  STD_LOGIC;
        reset : in  STD_LOGIC;
        duty  : in  STD_LOGIC_VECTOR (7 downto 0);
        pwm   : out STD_LOGIC
    );
end pwm_generator;

architecture Behavioral of pwm_generator is
    signal counter : unsigned(7 downto 0) := (others => '0');
begin
    process(clk, reset)
    begin
        if reset = '1' then
            counter <= (others => '0');
            pwm <= '0';
        elsif rising_edge(clk) then
            counter <= counter + 1;
            if counter < unsigned(duty) then
                pwm <= '1';
            else
                pwm <= '0';
            end if;
        end if;
    end process;
end Behavioral;
Enter fullscreen mode Exit fullscreen mode

5. Testing PWM on Hardware
A. Pin Assignment
Connect pwm_out to an FPGA GPIO pin (check your board’s constraints file).

Example (Xilinx Artix-7):

tcl
set_property PACKAGE_PIN "R10" [get_ports pwm_out]
set_property IOSTANDARD LVCMOS33 [get_ports pwm_out]
Enter fullscreen mode Exit fullscreen mode

B. Verification

  1. Oscilloscope: Check PWM waveform.
  2. LED: Vary duty to see brightness change.
  3. Logic Analyzer: Capture duty cycle transitions.

6. Advanced PWM Techniques
A. Dead-Time Insertion (For H-Bridge Motors)

  • Adds a small delay between PWM transitions to prevent shoot-through.
  • Requires two complementary PWM signals with adjustable delay.

B. Center-Aligned PWM

  • Used in motor control for symmetric waveforms.
  • Implemented with up/down counters:
verilog
if (direction == UP) 
    counter <= counter + 1;
else 
    counter <= counter - 1;
Enter fullscreen mode Exit fullscreen mode

C. Using FPGA IP Cores
Xilinx "AXI Timer" or Intel "PWM IP Core" for hardware-optimized PWM.

7. Example Applications

  1. Motor Speed Control (H-Bridge driver).
  2. LED Dimming (adjust brightness).
  3. Servo Control (1-2 ms pulses @ 50 Hz).
  4. Audio Generation (class-D amplifiers).

Conclusion

  • Basic PWM = Counter + Comparator.
  • Frequency depends on clock speed and counter resolution.
  • Duty cycle is set by comparing counter to a threshold.
  • FPGAs excel at PWM due to parallel hardware control.

Top comments (0)