Implementing Sobel Edge Detection Filter Using VHDL

Muhammed Kocaoğlu
5 min readDec 26, 2021

--

In this post, we will see the implementation of Sobel Filter using software and firmware.

I first implemented the algorithm using a software language. Then I implemented it using VHDL and compared the results with a self-checking test bench. After verifying my design, I created and packaged it as IP with an AXI-Lite interface in order to use it with a Microblaze processor.

I created a block design and added Microblaze, UART IP, DDR3 SDRAM IP, and lastly my Sobel Filter IP to the system. After validating the result, I generated bitstream and exported the hardware for further use in Vitis. You can see how the system looks like in the figure below.

Sobel Filter Algorithm

In this title, I will explain the algorithm. The algorithm is very straightforward in software. Different from Gaussian Filter there are coefficients in the x and y-directions. The yellow part is first convolved with coeff_x and obtained a value. Then it is convolved with coeff_y and obtained a value. Lastly, the final value of the blue pixel is calculated.

The blue pixel is calculated with the formula below. The advantage of using VHDL is parallelization. Since the multiplication is an independent operation, we can multiply all the yellow pixels with coefficients in a single clock cycle.

VHDL Implementation

Let me now show you how I wrote RTL of the Sobel filter algorithm and how I added AXI Lite IP to my design.

In the figure below, you can see the input and output ports of the design.

In the entity, the filter start triggers the system to start filtering. Filter busy is 0x55 as long as the filtering is in progress. Otherwise, it is 0x44. Filter_data_o_x is the value of the filtered pixel in the x-direction and Filter_data_o_y is the filtered pixel in the y-direction. Even though I don’t need them in the final stage, I added them because I checked them in the verification step. Filtered_data_o is the filtered pixel value.

filter_data_i is the input image.

filteredPixelReady signal tells you that the filtering has been completed.

Let’s analyze the code in detail.

When it is in the IDLE stage, wait for filter_start input to be 0xab. Once it becomes 0xab, it shifts in the incoming data and starts filtering. Filtering starts by multiplying the coefficients with the 3x3 array.

the coefficients in the x and y direction are given below. they have 1 byte signed values.

The multiplication is performed in a single cycle parallelly for the x-direction and y-direction.

After the multiplication step, the addition step comes. We add each element of the matrix and obtain the filtered value in the x and y-direction.

Lastly, we calculate the filtered pixel value using the calculation below. In VHDL, the square root operation is difficult. That’s why I prefer to do it in Microblaze.

Adding AXI-Lite Interface to the design

AXI-Lite interface lets us connect it to a processor. Since we use MicroBlaze, we need to add the AXI-Lite interface. From tools menu, we can create and package IP.

In the figure below, you can see how I connected my inputs to the registers. In the least significant byte of slv_reg0, I store the trigger signal. In the least significant 3 bytes of slv_reg1, I store input image. In the filter_data_o_Reg, I store the output obtained using my RTL implementation.

After connecting the ports to AXI peripheral, we can package the IP and add it to the Microblaze processor.

Lastly, I created an HDL wrapper, generated bitstream, and exported the hardware for further use in Vitis.

Creating a project in Vitis and writing C code

In the processor part, I stored the image in DDR3 SDRAM and performed the convolution part in the PL part. I actually accelerated the algorithm using FPGA.

A gray image with size 640x480 is stored in DDR. The filtered pixels are transmitted to the host PC through the UART protocol.

In C language, we need to send the image to FPGA in order to filter. You can see how we can send it to FPGA. ipSobelAddr is the base address that stores the trigger signal.

We can now get the filtered value and transmit it to PC through UART. In the figure below, I show how we can do that.

When we program the FPGA from Vitis and connect a serial terminal to the FPGA, the filtered data will be transmitted to the PC. In this link, you can see how the filtered data is transmitted to PC.

Reconstructing and Visualizing the Image

We can do reconstruction and visualizing of the image in Matlab or Octave. The data transmitted to the PC is 32*640*478 bits and in 1D format. We need to convert it to a 2D format to see a meaningful image. When I do that, I obtain the image below.

Let me now do it for another image and see the result.

Github: https://github.com/muhammedkocaoglu/Sobel-Edge-Detection-Using-VHDL-and-FPGA

LinkedIn : https://www.linkedin.com/in/muhammed-kocao%C4%9Flu-2b661b178/

Youtube : https://www.youtube.com/watch?v=uIkAXSV5x3g

--

--