00 FPGA-SoC nedir? — PS ve PL kavramları
Modern FPGA-SoC (System on Chip) cihazları, sabit bir işlemci alt sistemi (Processing System — PS) ile programlanabilir bir lojik dokusunu (Programmable Logic — PL) tek bir silikon üzerinde birleştirir. Bu yaklaşım, ARM işlemcisinin yazılım ekosistemini FPGA'nın esnekliğiyle harmanlar.
Diskret FPGA vs FPGA-SoC farkı
Klasik diskret FPGA tasarımında (Xilinx 7 serisi, Intel Cyclone 10 LP) tüm işlemler PL üzerinde gerçekleşir; Soft-core işlemci (MicroBlaze, Nios II) bile programlanabilir kaynaklardan tüketilir ve harici bir işlemciyle paralel çalıştırılır. FPGA-SoC yaklaşımında ise ARM Cortex-A serisi işlemci silikon üzerinde donanım olarak sabittir; PL yalnızca hızlandırıcı, periferel veya veri yolu olarak kullanılır.
| Özellik | Diskret FPGA | FPGA-SoC |
|---|---|---|
| İşlemci | Soft-core (LUT tabanlı) | Hard ARM Cortex-A (silikon) |
| İşlemci performansı | Düşük (50–200 MHz) | Yüksek (650 MHz – 1.5 GHz) |
| Linux desteği | Sınırlı (ucLinux) | Tam Linux (MMU, çok çekirdek) |
| PS-PL bant genişliği | Yok (ayrı çip) | Yüksek (AXI HP portları) |
| Güç tüketimi | Sadece PL | PS + PL (ancak entegre) |
| Tipik kullanım | Dijital tasarım, protokol | Gömülü Linux + HW hızlandırıcı |
PS alt sistemi bileşenleri
PL ile entegrasyon senaryoları
PL, PS'e birkaç farklı biçimde bağlanır: (1) Periferel modu — PL'de özel AXI-Lite register'lı bir blok; PS yazılımı bunu bellek eşlemeli G/Ç gibi erişir. (2) Veri akış motoru — PL'de AXI-Stream arayüzlü bir işleme hattı; AXI-DMA ile DDR'dan ham veri alır ve işlenmiş veriyi geri koyar. (3) Bağımsız işlemci — PL'de MicroBlaze veya Zynq'in R5 çekirdeği bağımsız çalışır, AXI Mailbox ile haberleşir.
Bu bölümde
- FPGA-SoC: sabit ARM (PS) + programlanabilir lojik (PL) — tek silikon
- PS: hard ARM Cortex-A, DDR kontrolcüsü, GIC, sabit periferaller
- PL: hızlandırıcı, özel periferel veya veri akış motoru
- PS-PL bağlantısı: AXI Interconnect portları (GP, HP, HPC, ACP)
01 AXI bus hiyerarşisi — AXI4, AXI-Lite, AXI-Stream
AMBA AXI (Advanced eXtensible Interface) protokolü, ARM'ın AMBA 3 ve AMBA 4 standardının parçasıdır. Zynq/Cyclone SoC tasarımlarında PS-PL iletişiminin omurgasını oluşturur; üç temel varyantı vardır.
AXI4 — yüksek bant genişlikli bellek erişimi
AXI4 tam özellikli protokoldür: beş kanal (AW, W, B, AR, R), burst transferler (256 beat'e kadar), multiple outstanding transaction, dar/geniş veri yolu desteği (32–1024 bit). DDR bellekle büyük veri bloklarını taşırken kullanılır.
AXI4 Kanalları: ┌──────────────────────────────────────────────────────────┐ │ Master → Slave: AW (Write Address) · W (Write Data) │ │ Slave → Master: B (Write Response) │ │ Master → Slave: AR (Read Address) │ │ Slave → Master: R (Read Data) │ └──────────────────────────────────────────────────────────┘ Handshake: VALID + READY — her kanalda bağımsız akış kontrolü
AXI4-Lite — register haritası erişimi
AXI4-Lite, burst ve narrow transfer desteği olmayan sadeleştirilmiş AXI4'tür. Tek bir 32-bit veya 64-bit transfer; custom IP register'larına erişmek için idealdir. Sentez alanı küçük, protokol basit. Her özel periferalin kontrol-durum register'ları (CSR) AXI-Lite ile erişilir.
AXI4-Stream — veri akışı
AXI4-Stream adres kanalı olmayan, yalnızca TDATA/TVALID/TREADY/TLAST sinyallerinden oluşan tek yönlü bir veri akış protokolüdür. Video pikselleri, ADC örnekleri, network paketleri gibi sürekli veri akışlarında kullanılır. Sideband sinyalleri: TKEEP (byte lane), TSTRB, TID, TDEST, TUSER.
// AXI4-Stream slave (alıcı) arayüzü
module axis_sink #(
parameter DATA_WIDTH = 32
) (
input wire aclk,
input wire aresetn,
// AXI4-Stream Slave
input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire s_axis_tvalid,
output wire s_axis_tready,
input wire s_axis_tlast
);
// Alıcı her zaman hazır
assign s_axis_tready = 1'b1;
always @(posedge aclk) begin
if (s_axis_tvalid && s_axis_tready) begin
// Veriyi işle: s_axis_tdata geçerli
if (s_axis_tlast)
// Paket/frame sonu
end
end
endmodule
| Protokol | Kanallar | Burst | Tipik kullanım |
|---|---|---|---|
| AXI4 | AW, W, B, AR, R | Evet (256) | DDR, DMA, HP portları |
| AXI4-Lite | AW, W, B, AR, R | Hayır | CSR register haritası |
| AXI4-Stream | Tek yönlü akış | Sürekli | Video, ADC, DMA veri yolu |
Bu bölümde
- AXI4: 5 kanal, burst 256, outstanding — DDR ve DMA için
- AXI4-Lite: sadeleştirilmiş, tek transfer — CSR register erişimi
- AXI4-Stream: adressiz veri akışı — video, ADC, paket işleme
- Handshake: VALID + READY — her kanalda bağımsız akış kontrolü
02 Zynq-7000 blok diyagramı
Xilinx Zynq-7000 (XC7Z010/020/030/045/100), çift çekirdekli ARM Cortex-A9 tabanlı PS ile Artix-7 veya Kintex-7 tabanlı PL dokusunu birleştiren ilk yaygın FPGA-SoC platformdur.
PS bileşenleri
Zynq-7000 PS Blok Diyagramı: ┌─────────────────────────────────────────────────────────────┐ │ APU (Application Processing Unit) │ │ ┌────────────────┐ ┌──────────┐ ┌────────────────────┐ │ │ │ Cortex-A9 #0 │ │ SCU │ │ Cortex-A9 #1 │ │ │ │ NEON/FPU │ │ Snoop │ │ NEON/FPU │ │ │ │ L1 I+D$ 32KB │ │ Filter │ │ L1 I+D$ 32KB │ │ │ └────────────────┘ └──────────┘ └────────────────────┘ │ │ ↕ AXI L2$ 512 KB │ ├─────────────────────────────────────────────────────────────┤ │ Central Interconnect │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ DDR CTRL │ │ OCM 256K │ │ GIC │ │ DMA (8ch) │ │ │ │ (PS DDR) │ │ │ │ (IRQ) │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ I/O Periferals (MIO çıkışlı) │ │ UART0/1 · SPI0/1 · I2C0/1 · CAN0/1 · USB0/1 · GigE0/1 │ │ SD/MMC0/1 · GPIO · QSPI │ ├─────────────────────────────────────────────────────────────┤ │ PS-PL AXI Portları │ │ GP0/GP1 (32-bit, master) → PL periferallerine erişim │ │ HP0–HP3 (64-bit, slave) ← PL DMA → PS DDR │ │ ACP (64-bit, L2 cache coherent) ← PL → PS cache │ │ IRQ (16 PL kesmesi → GIC) │ └─────────────────────────────────────────────────────────────┘ PL: Artix-7 / Kintex-7 lojik dokusu (LUT, FF, BRAM, DSP, PLL)
AXI port türleri ve kullanım senaryoları
Zynq-7000 hedef kullanım alanları
Endüstriyel motor kontrolü (FSMC), tıbbi görüntüleme (ultrasound DSP), SDR (yazılım tanımlı radyo), makine görüsü, motor enkoder arayüzü ve aviyonik veri konsantratörü gibi uygulamalar için tercih edilir. ZedBoard, PYNQ-Z1/Z2, MiniZed ve Arty Z7 popüler geliştirme kartlarıdır.
Bu bölümde
- PS: çift Cortex-A9, 512 KB L2, DDR3 kontrolcü, GIC, 8-kanal DMA
- GP portları: PS→PL, 32-bit, register erişimi; HP portları: PL→DDR, 64-bit, yüksek bant
- ACP: önbellek tutarlı PL erişimi — küçük veri kümesi için avantajlı
- PL: Artix-7 / Kintex-7 dokusu — Vivado ile sentezlenir
03 Zynq UltraScale+ MPSoC mimarisi
Zynq UltraScale+ MPSoC (ZU2–ZU19), Zynq-7000'in halefisidir: dört çekirdek Cortex-A53 + çift çekirdek Cortex-R5F + Mali-400 GPU + UltraScale+ PL dokusu.
Çok işlemcili yapı
| İşlemci Grubu | Çekirdek | Tipik kullanım |
|---|---|---|
| APU (Application) | 4× Cortex-A53 @ 1.5 GHz | Linux, uygulama katmanı |
| RPU (Real-time) | 2× Cortex-R5F @ 600 MHz | FreeRTOS, gerçek zamanlı kontrol |
| PMU (Platform Mgmt) | MicroBlaze PMU | Güç yönetimi, boot sıralaması |
| CSU (Config Security) | MicroBlaze CSU | Güvenli önyükleme, şifreleme |
| GPU | Mali-400 MP2 | HMI, grafik arayüzü |
PS-PL AXI portları (UltraScale+)
UltraScale+'ın RPU'su (Cortex-R5F) bağımsız çalışabilir (lockstep veya split modu) ya da APU ile OpenAMP/RPMsg üzerinden haberleşebilir. Bu, gömülü bir gerçek zamanlı kontrolörü Linux ile birleştiren güçlü bir tasarım desenidir.
Bu bölümde
- APU: 4× A53 (Linux); RPU: 2× R5F (FreeRTOS); PMU + CSU: platform yönetimi
- HPC portları: önbellek tutarlı PL→PS DMA — büyük veri transferleri
- RPU + OpenAMP/RPMsg: Linux ve RTOS eş zamanlı çalışma deseni
04 Cyclone V SoC HPS — Intel tarafı
Intel (Altera) Cyclone V SoC, çift çekirdek ARM Cortex-A9 tabanlı HPS (Hard Processor System) ile Cyclone V FPGA dokusunu birleştiren endüstriyel hedefli bir platformdur. DE1-SoC ve Arrow SoCKit popüler geliştirme kartlarıdır.
HPS-FPGA köprüleri
| Köprü | Yön | Genişlik | Kullanım |
|---|---|---|---|
| HPS-to-FPGA (H2F) | HPS master → FPGA slave | 32/64/128-bit | HPS'den FPGA periferallerine yazma/okuma |
| FPGA-to-HPS (F2H) | FPGA master → HPS slave | 32/64/128-bit | FPGA DMA → HPS DDR veya periferaller |
| Lightweight H2F | HPS master → FPGA | 32-bit | Düşük bant genişlikli CSR register erişimi |
| F2H SDRAM | FPGA → DDR | 128/256-bit | FPGA DMA doğrudan DDR erişimi |
Quartus + Linux geliştirme akışı
Intel tarafında araç akışı: Quartus Prime (sentez ve P&R) + Platform Designer (Qsys, köprü yapılandırması) + SoC EDS (Embedded Development Suite) + Yocto/buildroot. HPS periferallerinin pinout yapılandırması Quartus'taki HPS Component üzerinden yapılır; boot ROM, MMC/QSPI veya NAND'dan yüklenir.
// Cyclone V SoC — H2F Lightweight Bridge
// Temel adres: 0xFF200000
#include <sys/mman.h>
#include <fcntl.h>
#define H2F_LW_BASE 0xFF200000UL
#define H2F_LW_SPAN 0x00200000UL /* 2 MB */
int fd = open("/dev/mem", O_RDWR | O_SYNC);
void *h2f_lw = mmap(NULL, H2F_LW_SPAN,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, H2F_LW_BASE);
/* FPGA üzerindeki periferalin offset'i: 0x0000 */
volatile uint32_t *led_reg =
(volatile uint32_t *)((uintptr_t)h2f_lw + 0x0000);
*led_reg = 0xAA; /* LED'leri yak */
printf("LED register: 0x%08X\n", *led_reg);
Bu bölümde
- HPS: çift Cortex-A9, DDR3, GigE, USB, UART, SPI, I2C, SD/MMC
- H2F / F2H / Lightweight H2F köprüleri — farklı bant genişliği ve gecikme
- F2H SDRAM: FPGA DMA doğrudan DDR erişimi
- Geliştirme: Quartus + Platform Designer + SoC EDS + Yocto
05 HW/SW co-design metodolojisi
Donanım/yazılım eş tasarımı (HW/SW co-design), bir uygulamanın hangi kısımlarının FPGA PL'de, hangi kısımlarının PS'de çalışacağını sistematik olarak belirleme ve birlikte geliştirme sürecidir.
Bölümleme kriterleri
Tipik geliştirme döngüsü
1. Algoritma analizi → darboğaz belirleme (profiling) 2. Bölümleme kararı → hangi bloklar PL'e? 3. HLS veya HDL ile PL bloklarını tasarla 4. Vivado/Quartus: Block Design → sentez → P&R → bitstream 5. Device Tree güncellemesi (PL periferaller için nodes) 6. Linux sürücüsü: platform_driver veya UIO 7. Kullanıcı alanı uygulaması: test + benchmark 8. Optimizasyon → 3'e geri dön
İlk prototipte HLS kullanın: C++ algoritmayı doğrudan RTL'e çevirin, latency/throughput raporlarını alın. Yeterliyse canlıya geçin; yetersizse elle yazılmış VHDL/Verilog ile kritik modülleri optimize edin.
Bu bölümde
- PL'e: tekrarlı döngüler, kesin zamanlama, paralel işlem
- PS'te: protokol, UI, yapılandırma, aperiodik görevler
- Arayüz seçimi: AXI-Lite (CSR) / AXI-Stream (veri) / AXI4 DMA (büyük bloklar)
- Döngü: profil → bölümle → HLS/HDL → sentez → DT → sürücü → benchmark
06 Bellek haritası ve adres uzayı
Zynq-7000'de PS ve PL bileşenleri 32-bit adres uzayını paylaşır. PL'de oluşturulan AXI periferalleri bu haritaya belirlenmiş bölgelere yerleştirilir.
Zynq-7000 bellek haritası özeti
| Adres Aralığı | Alan | Açıklama |
|---|---|---|
| 0x0000_0000 – 0x3FFF_FFFF | DDR (1 GB) | PS DDR — Linux belleği |
| 0x4000_0000 – 0x7FFF_FFFF | PL via GP0 | GP0 portuna bağlı PL periferalleri (1 GB) |
| 0x8000_0000 – 0xBFFF_FFFF | PL via GP1 | GP1 portuna bağlı PL periferalleri (1 GB) |
| 0xE000_0000 – 0xE02F_FFFF | PS I/O Periferalleri | UART, SPI, I2C, CAN, USB, GigE, SD |
| 0xF000_0000 – 0xF8FF_FFFF | PS Sistem Kaydedicileri | SLCR, GIC, Timers, SWDT |
| 0xFFFC_0000 – 0xFFFF_FFFF | OCM (256 KB) | On-chip SRAM — FSBL ve kritik kod |
PL periferali adres atama (Vivado)
Vivado Address Editor'da her AXI slave'e 0x4000_0000–0x7FFF_FFFF aralığından bir offset ve boyut atanır. Örneğin özel bir AXI-Lite LED denetleyicisi 0x4000_0000'e, AXI-DMA motoru 0x4040_0000'e yerleştirilir. Bu adresler Device Tree'de reg property olarak tanımlanır.
/* arch/arm/boot/dts/zynq-zed.dts veya overlay */
&amba_pl {
led_ctrl_0: led-ctrl@40000000 {
compatible = "xlnx,led-ctrl-1.0";
reg = <0x40000000 0x10000>; /* base, 64 KB */
clocks = <&clkc 15>;
clock-names = "s00_axi_aclk";
};
axi_dma_0: dma@40400000 {
compatible = "xlnx,axi-dma-1.00.a";
reg = <0x40400000 0x10000>;
dma-channel@40400000 {
compatible = "xlnx,axi-dma-mm2s-channel";
interrupts = <0 29 4>;
xlnx,datawidth = <32>;
};
};
};
Bu bölümde
- 0x4000_0000–0x7FFF_FFFF: GP0 PL periferalleri; 0x8000_0000–0xBFFF_FFFF: GP1
- Vivado Address Editor: her AXI slave'e adres ve boyut atanır
- Device Tree: reg property ile adres bilgisi kernel sürücüsüne aktarılır
07 Interrupt yönlendirme PS→PL
Zynq-7000'de PL, GIC (Generic Interrupt Controller) üzerinden PS'e 16 adet kesme sinyali gönderebilir. Bu sinyaller Device Tree'de tanımlanır ve Linux IRQ subsystem aracılığıyla sürücülere iletilir.
PL→PS kesme yolları
Device Tree — kesme tanımı
my_periph@40000000 {
compatible = "myco,my-periph-1.0";
reg = <0x40000000 0x10000>;
/* GIC: <tip IRQ tetik>
tip 0: SPI (paylaşımlı), 1: PPI
IRQ 29 → GIC SPI 61 (IRQ_F2P[0])
tetik: 1=yükselen kenar, 4=yüksek seviye */
interrupts = <0 29 1>;
interrupt-parent = <&gic>;
};
Sürücüde kesme kaydetme
static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
struct my_priv *priv = dev_id;
/* PL'den gelen kesmeyi işle */
priv->irq_count++;
wake_up_interruptible(&priv->wait_q);
return IRQ_HANDLED;
}
static int my_probe(struct platform_device *pdev)
{
int irq = platform_get_irq(pdev, 0);
devm_request_irq(&pdev->dev, irq, my_irq_handler,
0, "my-periph", priv);
return 0;
}
Bu bölümde
- IRQ_F2P[15:0]: 16 PL→PS kesme sinyali; GIC SPI 61–76 olarak eşlenir
- DTS: interrupts = <0 IRQ-offset tetik>; interrupt-parent = <&gic>
- platform_get_irq() + devm_request_irq() — Linux sürücü kayıt deseni
08 Boot akışı ve pratik: Zynq-7000 AXI-Lite LED denetleyici
Zynq-7000 önyükleme akışı FSBL → U-Boot → Linux'tan oluşur. Pratik bölümde sıfırdan bir AXI-Lite LED denetleyicisi tasarlanacak, Vivado Block Design'a entegre edilecek ve Linux'tan kontrol edilecektir.
Boot akışı
ROM (BootROM) → QSPI/SD'den BOOT.BIN oku
↓
FSBL (First Stage Boot Loader)
- OCM'de çalışır (0xFFFC_0000)
- PS başlatma (DDR, PLL, CLK)
- PL bitstream yükleme (isteğe bağlı)
- U-Boot'u DDR'a kopyala
↓
U-Boot (Second Stage Boot Loader)
- DDR testleri
- Ortam değişkenleri
- Kernel + DTB + initrd yükleme
- bootm / bootz komutu
↓
Linux Kernel
- of_* API ile DT parse
- Platform sürücüler probe
- Rootfs mount, init/systemd
Pratik: AXI-Lite LED denetleyici — VHDL tasarımı
-- Register haritası:
-- 0x00: LED_DATA (RW) — 8 bit LED çıkışı
-- 0x04: LED_DIR (RW) — yön (1=çıkış)
-- 0x08: STATUS (RO) — 0x1 = hazır
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axi_lite_led is
generic (
C_S_AXI_DATA_WIDTH : integer := 32;
C_S_AXI_ADDR_WIDTH : integer := 4
);
port (
-- AXI4-Lite Slave
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_AWREADY : out std_logic;
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_WSTRB : in std_logic_vector(3 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_WREADY : out std_logic;
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_BREADY : in std_logic;
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_RREADY : in std_logic;
-- Uygulama çıkışı
LED_OUT : out std_logic_vector(7 downto 0)
);
end axi_lite_led;
Linux sürücüsü — /dev/mem veya platform driver
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#define LED_BASE 0x40000000UL
#define MAP_SIZE 0x10000UL
#define REG_LED 0x00 /* LED_DATA */
#define REG_DIR 0x04 /* LED_DIR */
#define REG_STATUS 0x08 /* STATUS */
int main(void)
{
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) { perror("open"); return 1; }
volatile uint32_t *regs = mmap(NULL, MAP_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, LED_BASE);
/* Yön: tüm pinler çıkış */
regs[REG_DIR / 4] = 0xFF;
/* LED deseni: alternatif */
for (int i = 0; i < 10; i++) {
regs[REG_LED / 4] = (i % 2) ? 0xAA : 0x55;
usleep(500000);
}
munmap((void *)regs, MAP_SIZE);
close(fd);
return 0;
}
/dev/mem erişimi üretim sistemlerinde güvenlik açığı oluşturur. Gerçek ürünlerde kernel platform_driver veya UIO sürücüsü tercih edilmelidir. Bu örnekteki kullanım yalnızca hızlı prototipleme içindir.
Bu bölümde
- Boot: BootROM → FSBL (OCM) → U-Boot (DDR) → Linux Kernel
- FSBL: DDR/PLL başlatma + isteğe bağlı PL bitstream + U-Boot yükleme
- AXI-Lite LED: 3 register (LED_DATA, LED_DIR, STATUS), VHDL AXI-Lite slave
- /dev/mem + mmap: hızlı prototipleme; üretimde platform_driver/UIO tercih edilmeli