Skip to Content

Starting FPGA

eng.abderhman waled

I decided to jump headfirst into something completely new: a 24-hour hands-on FPGA course spread over just 6 days. Here’s the twist — I had never studied logic design or computer architecture before. My only prior experience was building a simple 4-bit adder as a hardware project. So, enrolling in an FPGA course wasn’t just a step forward… it was a leap. The course focused on using Xilinx Vivado and VHDL to design digital systems and testing on a Xilinx PYNQ-Z2 board. It was an intense mix of coding, simulation, and hardware testing — and I learned a lot more than I expected. In this blog, I’ll take you through that experience and what it was like diving into the deep end of FPGA development.

fpga board

Xilinx PYNQ-Z2 board


After hearing about my spontaneous dive into FPGA, people often have one of two reactions. One group questions my decision: "Why would you take this if you've never studied logic design or computer architecture?" The other jumps straight to curiosity: "What even is an FPGA?" This section aims to address both those questions

What is an FPGA?

In my terms, an FPGA is like a artist’s blank canvas. Instead of painting with colors, you 'paint' with logic gates. It’s a piece of hardware you can reconfigure to become almost any digital circuit you can imagine

also —>

A field-programmable gate array (FPGA) is a type of configurable integrated circuit that can be repeatedly programmed after manufacturing. FPGAs are a subset of logic devices referred to as programmable logic devices (PLDs). They consist of a grid-connected array of programmable logic blocks that can be configured 'in the field' to interconnect with other logic blocks to perform various digital functions.

— Wikipedia

Why Did I Take the Course?

Simple: I love a challenge. I love when people doubt me, and I get to prove them wrong. also, My only hardware experience before this was building a small 4-bit adder — and I enjoyed it so much that I wanted to see what would happen if I took that curiosity to the next level. FPGA felt like the perfect playground for that.

Hands-On FPGA

Over the 6 days, the course packed a lot of hands-on work into a short time. Almost every session was about building something in VHDL using Vivado, running simulations. Here’s a quick rundown of the main things I worked on:

4-Bit Adder

My first task was to code a simple 4-bit adder in VHDL, run it through Vivado, and verify it with simulation.

Decoder Design & Simulation

Next, I wrote a decoder in VHDL, again testing it with simulation to ensure it behaved as expected.

Mini ALU Development

We started building a small Arithmetic Logic Unit. (I’ll go into more detail about this later — it was one of my favorite parts.)

Flip-Flops

Learned about flip-flops and how to use them in designs.

Synchronous vs. Asynchronous Logic ,Sequential vs. Combinational

Understood the core differences between these design styles and when to use each.

Vivado Core Generator Exploration

Explored Vivado’s built-in core generator to create reusable, pre-optimized components.

FIR Filter Implementation

Wrote a Finite Impulse Response (FIR) filter in VHDL and simulated its behavior.

The mini ALU

As promised, here’s the breakdown of the mini ALU: We start with two 2-bit inputs. These first pass through flip-flops, then go into three different units — an adder, a multiplier, and a subtractor. Each of these produces its own output. All three outputs are then fed into a multiplexer. A 2-bit selection input chooses which one of these results becomes the final 4-bit output. You can see the whole flow in the diagram below

minialu digram

THE CODE

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

entity alu_2bit is
    Port (
        clk     : in  STD_LOGIC;                     
        a       : in  STD_LOGIC_VECTOR(1 downto 0);  
        b       : in  STD_LOGIC_VECTOR(1 downto 0);  
        sel     : in  STD_LOGIC_VECTOR(1 downto 0);  
        result  : out STD_LOGIC_VECTOR(3 downto 0)       
);
end alu_2bit;

architecture Behavioral of alu_2bit is
    
    signal a_reg   : STD_LOGIC_VECTOR(1 downto 0);
    signal b_reg   : STD_LOGIC_VECTOR(1 downto 0);
    signal sel_reg : STD_LOGIC_VECTOR(1 downto 0);
    signal result_reg : STD_LOGIC_VECTOR(3 downto 0);

    signal a_int   : unsigned(1 downto 0);
    signal b_int   : unsigned(1 downto 0);

    
begin

    
    a_int <= unsigned(a_reg);
    b_int <= unsigned(b_reg);
    process(clk)
    begin
        if rising_edge(clk) then
            a_reg   <= a;
            b_reg   <= b;
            sel_reg <= sel;
            case sel_reg is
                when "00" => result_reg <= std_logic_vector(resize(a_int, 4) + resize(b_int, 4));
                when "01" => result_reg <= std_logic_vector(resize(a_int, 4) * resize(b_int, 4));
                when "10" => result_reg <= std_logic_vector(resize(a_int, 4) - resize(b_int, 4));
                when others => result_reg <= "0000";
            end case;
        end if;
    end process;
    result <= result_reg;
end Behavioral;

Simulating the Mini ALU:

Here’s a screenshot of the waveform simulation. For this run, I used ModelSim instead of Vivado — that way, I’ve now tried both programs.

modlesim

Challenges I faced while writing this code:

ModelSim Error Identification

Unlike Vivado, ModelSim doesn’t directly point to where the error is, so I had to guess multiple times until I found the problem.

Clock and Flip-Flop Management

Making sure the clock signal and flip-flops were handled correctly took careful adjustment.

Arithmetic Library Selection

I needed the correct libraries to use the +, -, and * operators.

Bit Resizing for Operations

I had to resize signals so that arithmetic operations could work properly.

Output Synchronization via Flip-Flops (over flow error)

To prevent overflow issues, I used flip-flops to store intermediate results.