Berkay YarderTCS student, University of Twente
mberkayyarder@gmail.com
Enschede, the Netherlands

~ / projects / fpga-sobel

FPGA Sobel accelerator and stack processor

Three hardware design assignments, from a traffic light controller in Verilog to an image processing accelerator written in Clash.

Year
2025/26
Context
EAT course, University of Twente
Languages
Clash (Haskell), Verilog
Interface
AXI4-Stream
pixels in line buffers 3×3 window Sobel // my part: shift-register window clk tvalid tready tdata p0 p1 p2 p3 p4 // tready low: p2 has to wait
Fig. 2 Top: pixels stream through line buffers into a 3×3 window. Bottom: AXI4-Stream backpressure. While tready is low, the data has to be held.

What I built

First a traffic light controller in Verilog: a finite state machine with a testbench, simulated in Icarus Verilog and checked in VCD waveforms. Then two designs in Clash, a min-max Mealy machine and a small stack-based processor.

The last assignment was a Sobel edge detection accelerator with an AXI4-Stream interface, so it can sit in a real SoC pipeline.

How the accelerator works

Pixels arrive one per clock as a stream. Line buffers built from shift registers keep the previous rows, so the design always has a 3×3 window of pixels ready for the Sobel kernel.

AXI4-Stream only moves data when tvalid and tready are both high. When the next stage pulls tready low, every pixel has to stay where it is until it goes high again. Getting that right is what makes the accelerator usable in a larger system.

My part

I designed the shift-register architecture that feeds the convolution window, fixed the s_axis_tready handshake and the 1D convolution transpose, checked the design against the RTL schematic and wrote parts of the report.

What I learned

Building a processor in Clash is where I properly understood how a functional description turns into gates.

Result

A working accelerator with correct AXI4-Stream backpressure, verified in simulation, with a report on the design decisions.

Try it

Sobel filter

Click or drag on the left grid to draw. The right grid shows the edge strength, |Gx| + |Gy|, the same thing the accelerator computes per pixel.

12 × 12 pixels, computed in your browser.