Sitemap

PWM Signal Generation with VHDL to Control Servo Motor

4 min readDec 28, 2025

--

In this article, I aim to explain how a PWM signal can be generated using VHDL to control a Servo Motor in an FPGA. In other words, I will show how to design a servo motor controller in an FPGA.

RTL block diagram of the PWM controller
Press enter or click to view image in full size
Generic paramaters of PWM controller.

What is PWM Signal?

Pulse Width Modulation (PWM) is a modulation technique used to encode information or control the average power delivered to a load by varying the duty cycle of a fixed-frequency square wave. In this application, a PWM signal will be used to encode position information for servo motor control.

Press enter or click to view image in full size
PWM signal examples with different duty cycle values.

SG90 Servo Motor

I have aimed to control the SG90 Servo Motor in this application. In the datasheet of this SG90 Servo Motor, it says that it can rotate approximately 180 degrees.

SG90 Servo Motor

According to the datasheet, the PWM period should be 20 ms. Moreover, the duty cycle should be between 1ms and 2ms. For example, if the duty cycle is 1ms, it means the motor is in the “0 degree” position. If the duty cycle is 1.5 ms, it means the motor is in the “ 90 degree” position. Finally, if the duty cycle is 2 ms, it means the motor is in the “180 degree” position. In some other applications, it is recommended that the duty cycle be between 0.5 ms and 2.5 ms. However, I would like to obey the datasheet. You can change the values if you like.

Example pwm signal for SG90 Servo Motor

Thus, the input PWM signal that will control the servo motor should have a 20 ms period and a 1 ms duty cycle for the 0 degree position or a 2 ms duty cycle for the 180 degree position.

Get Alperen Özçelik’s stories in your inbox

Join Medium for free to get updates from this writer.

After analyzing the datasheet of the SG90 servo motor, it is understood what kind pwm signal we need. So it can be designed now in an FPGA.

PWM Signal Controller Design in VHDL

I have designed a generic PWM signal controller using VHDL hardware description language. The state diagram of this RTL code is shared below.

Press enter or click to view image in full size
FSM of PWM signal controller

We have 3 states, which are IDLE, UP_COUNT, and DOWN_COUNT. In idle state duty cycle absolutly 1 ms, which is 0 degrees. In the up_count state, the duty cycle time is incrementing in each clock by 1 clock time, up to the duty cycle reaches 2 ms, which is 180 degrees. In the down_count state duty cycle is decremented by 1 clock time in each clock bye 1 clock time, up to the duty cycle reaches 1 ms, which is 0 degrees. Finally, it can be said that the duty cycle will be oscillating between 1ms and 2ms. Thus, 0 degrees and 180 degrees.

Used libraries, generic parameters, and ports of this module are shared below. It has 2 inputs, which are clk and reset, but only 1 output, just a PWM signal.

Press enter or click to view image in full size
Ports and generic paramaters.

Used constants and signals are shared below. Constants are derived according to the clock numbers. For example, the PERID_CLKS constant means how many clocks are required to reach 20 ms period.

Press enter or click to view image in full size
Used constants and signals.

The whole FSM part of the code is shared below. The calculated new PWM signal value is latched when the period begins. Thus, it latches every 20 ms. Moreover, FSM updates only for the new period.

Press enter or click to view image in full size
Whole process code block which covers also FSM.

I have also written a testbench code for this controller design and analyzed it. Complete testbench code is shared below.

The output waveform of the testbench can be seen below in two figures. The controller functions as it is designed. It can be seen from the figures pwm period is as long as 20 ms. Moreover, in the UP_COUNT state duty cycle gradually increments in every PWM period. Also, in the DOWN_COUNT state duty cycle gradually decrements in every PWM period. If you run these codes and analyze it you can also realize these on your own.

Press enter or click to view image in full size
Waveform output when the controller in UP_COUNT state.
Press enter or click to view image in full size
Waveform output when the controller in DOWN_COUNT state.

Finally, it can be said that the design is working as it is planned.

The complete code can be found on my GitHub page. Also, you can visit my LinkedIn page.

--

--