Main Content

Decoding PWM Using an FPGA

Using a standard RC transmitter (HobbyKing HK-T6A) you will learn how to create and test Verilog to decode 6 channels of PWM.

The transmitter outputs 6 PWM channels at 50Hz with each channel ranging from 1000us to 2000us. There are many waveform examples that can be found on the web. Here is a trace of all 6 channels from the transmitter

Decoding PWM
A 1.0MHz clock will count the number of ticks present in “on” and “off” pulse and report the value in microseconds. If the “on” time is bigger than 2600us an error is reported, this maybe due to bad wiring or PWM line is locked high. Also, the same logic will be used to detect if the line is locked low, for example, if the transmitter is turned off, the PWM value is updated with 0 and error condition.

Here is an example of using this code to drive BetaFlight.

First Steps
I use vscode for editing verilog code, there are several extensions available to support syntax highlighting. For a simulation environment, will use Icarus Verilog. I use Linux, here is a guide to compile and install. So, why use Icarus Verilog, (iverilog)?

Can use $display, i.e. printf statements in verilog to help debug
setup test environment to simulate errors, test basic operation
There are two files: pwm_decode.v which is the module that decodes one channel of PWM. pwm_decoder_tb.v is the testbench that drives pwm_decode.v. This follows the same general methodology as unit testing software.

Also, should have gtkwave installed. The test bench generates a gtkwave file, now it is possible to see the top level timing diagrams and low level (UUT) timing.”

Link to article