Projekt dotyczy zaprojektowania i implementacji autorskiego procesora w układzie FPGA, wykorzystując język opisu sprzętu Verilog. Celem projektu było stworzenie prostego procesora, zdolnego do wykonywania podstawowych instrukcji, takich jak MOV, JMP, ADD i inne operacje arytmetyczne oraz logiczne, z możliwością obsługi skoków warunkowych. Procesor został zaimplementowany w sposób modułowy, obejmujący rejestry, jednostkę sterującą, ALU, pamięć programu i danych, a także licznik rozkazów (PC). Dzięki tej implementacji możliwe jest zrozumienie i testowanie podstaw architektury CPU, przy jednoczesnej elastyczności w modyfikowaniu i rozszerzaniu funkcjonujących rozkazów oraz opracowywaniu nowych rozwiązań, takich jak przerwania czy potokowanie.
Projekt polega na zaprojektowaniu i zaimplementowaniu w układzie FPGA (z wykorzystaniem języka Verilog) własnej, uproszczonej architektury procesora z podstawowym zestawem instrukcji (m.in. MOV, ADD, JMP) oraz zewnętrznymi pamięciami programu i danych, co pozwala na uruchamianie niewielkich sekwencji rozkazów i obserwację działania typowych elementów CPU, takich jak liczniki rozkazów (PC), rejestry ogólnego przeznaczenia czy jednostka arytmetyczno-logiczna (ALU).

Poniższy schemat ilustruje podstawową architekturę autorskiego procesora zaimplementowanego w układzie FPGA z wykorzystaniem języka opisu sprzętu (np. Verilog). Procesor korzysta z 32‑bitowych słów rozkazów oraz 8‑bitowej szerokości danych, a główne komponenty układu to:
1. Pamięci programu i danych
- Pamięć rozkazów ma organizację 256×32 bit, co oznacza, że może pomieścić maksymalnie 256 instrukcji, z których każda zajmuje 32 bity. Sygnał adresu tej pamięci (
pc_addr
) pochodzi z licznika rozkazów (rejestrupc
), a wyjście pamięci (instr
) jest następnie dekodowane. - Pamięć danych (256×8 bit) służy do przechowywania wartości tymczasowych, zmiennych i innych danych potrzebnych podczas wykonywania programu. Adres tej pamięci zwykle pochodzi z wyjścia ALU (
alu_res
), zaś dane mogą być do niej zapisywane lub odczytywane zależnie od typu instrukcji.
2. Rejestry i dekoder rozkazu
- Rejestry ogólnego przeznaczenia: r0–r5, które mogą przechowywać dane i wyniki operacji.
- Rejestr r6 jest w tym projekcie ustawiony na wartość 0 (co ułatwia np. porównywanie z zerem czy inicjalizację danych).
- Rejestr r7 pełni funkcję licznika rozkazów (ang. Program Counter – PC). Z jego wyjścia korzysta pamięć rozkazów do pobierania kolejnej instrukcji.
- Dekoder rozbija 32‑bitowe słowo instrukcji na poszczególne pola (m.in.
pc_op
,alu_op
,rx_op
,ry_op
,rd_op
,imm_op
i ewentualne 8‑bitowe pole natychmiastoweimm[7:0]
). Dzięki tym sygnałom poszczególne bloki CPU (ALU, multipleksery, rejestry) „wiedzą”, jak zareagować na konkretną instrukcję.
3. ALU (Jednostka Arytmetyczno-Logiczna)
ALU (Arithmetic Logic Unit) pobiera dwa operandy:
- Operand X – wybierany przez multiplekser
rx_mux
(np. zawartość jednego z rejestrów r0–r5 lub wartość 0 z r6). - Operand Y – wybierany przez
ry_mux
(np. drugi rejestr albo wartość natychmiastowąimm
).
W zależności od rozkazu (alu_op
), ALU może:
- Wykonywać dodawanie (
+
), - Wykonywać operacje logiczne (np. AND),
- Sprawdzać równość z zerem (==0) – co ułatwia implementację instrukcji porównania i skoków warunkowych.
Wynik z ALU (alu_res
) może zostać zapisany do rejestru docelowego (np. przez rd_op
), użyty jako adres do pamięci danych lub jako nowy adres PC w przypadku skoku.
4. Sterowanie skokami i aktualizacja PC
- PC (r7) jest zwiększany o 1 po każdej wykonanej instrukcji, co oznacza sekwencyjne wykonywanie rozkazów.
- Jeśli instrukcja przewiduje skok (warunek skoku ustawiony np. w wyniku operacji
CMP
), do rejestru PC może zostać załadowana inna wartość – np. wyjście ALU lub część natychmiastowa instrukcji. - Blok „warunek skoku” (
cmp_res
) decyduje, czy PC zostanie nadpisany nowym adresem, czy kontynuuje liczenie sekwencyjne.
5. Przykładowy przepływ wykonania instrukcji
- Pobranie instrukcji: PC (r7) wskazuje adres w pamięci rozkazów (256×32). Słowo 32‑bitowe trafia do dekodera.
- Dekodowanie: dekoder wyodrębnia pola określające typ rozkazu, docelowe rejestry, ewentualne pole natychmiastowe.
- Przygotowanie operandów: multipleksery
rx_mux
iry_mux
wybierają właściwe źródła danych (np. rejestry r0–r5, r6=0 lub wartośćimm
). - Operacja w ALU: w zależności od
alu_op
wykonuje się dodawanie, AND czy porównanie. - Zapis wyniku: wynik ALU może trafić do rejestru docelowego, pamięci danych lub zostać wykorzystany jako adres skoku.
- Aktualizacja PC: jeśli rozkaz to skok, a warunek jest spełniony, PC przyjmuje wartość z ALU; w przeciwnym razie PC jest inkrementowany (PC+1).
6. Zastosowania i rozwój
Tak zaprojektowany procesor może realizować podstawowe instrukcje, np. MOV
, ADD
, AND
, CMP
, JMP
, JE
, HLT
itp. Nadaje się do nauki architektury CPU i implementacji w FPGA. Możliwe dalsze rozbudowy to m.in. dodanie kolejnych instrukcji, implementacja przerwań czy pipeline (potokowanie), a także rozbudowa pamięci i warstw cache.
Dzięki prostej, modułowej budowie oraz czytelnym rozdzieleniu pamięci rozkazów i danych, projekt jest łatwy w modyfikacji i może stanowić punkt wyjścia do zaawansowanych eksperymentów z własnymi mikroarchitekturami w układach programowalnych.