CURSUL 09

Sisteme Reconfigurabile și Accelerare Hardware pentru Aplicații Embedded

Durată: 120 min de predare Nivel: licență, anul III - recomandat după Cursul 08 Disciplină: Sisteme Încorporate Laborator asociat: Laboratorul 05 PDF: descarcă suportul EN English version

Până acum, tot ce am discutat rula pe un procesor care execută instrucțiuni una câte una. Acest curs deschide o direcție diferită: ce se întâmplă când mutăm o parte din calcul direct în hardware, folosind un FPGA. Pornim de la motivația acestei decizii (profilare, nu presupunere), trecem prin arhitectura internă a unui FPGA - LUT-uri, blocuri DSP, memorie de configurare -, prin fluxul de proiectare hardware, până la întrebarea centrală practică: cum se împarte o aplicație între procesor și logica reconfigurabilă, și de ce accelerarea unei singure funcții rareori accelerează aplicația în aceeași măsură.

1Obiectul și structura cursului6 min

Un procesor rapid ajunge, inevitabil, la o limită: creșterea frecvenței de ceas crește puterea consumată, iar reducerea tensiunii e limitată de funcționarea corectă a tranzistorilor. Consumul dinamic al unui circuit digital poate fi aproximat prin P_dinamic = αC_LV²f, unde α e factorul de activitate, C_L capacitatea comutată, V tensiunea, iar f frecvența - dublarea frecvenței dublează, aproximativ, puterea consumată. Din acest motiv, arhitecturile moderne nu mai urmăresc doar „mai rapid", ci „structuri de calcul specializate pentru sarcina la îndemână".

Recapitulare din Cursurile 04-06
  • Puterea dinamică depinde de V², motiv pentru care DVFS reduce energia agresiv
  • Accelerarea hardware a unei operații reduce direct timpul petrecut la frecvență/tensiune ridicată pentru acea operație
Astăzi mutăm accentul de la „cum rulează mai eficient codul pe CPU" la „ce câștigăm dacă nu mai rulează deloc pe CPU".

Rezultate ale învățării

  • Să explicați poziția FPGA-ului între procesorul general și circuitul ASIC dedicat
  • Să identificați o funcție candidată pentru accelerare pe baza profilării, nu a intuiției
  • Să descrieți rolul LUT-urilor, blocurilor DSP și memoriei de configurare într-un FPGA
  • Să urmăriți fluxul de proiectare FPGA și să interpretați un slack temporal negativ
  • Să calculați pragul de eficiență al unui accelerator, incluzând costul transferului
  • Să aplicați legea lui Amdahl pentru accelerarea parțială a unei aplicații

2Calculul reconfigurabil și paralelismul spațial8 min

Calculul reconfigurabil ocupă o poziție intermediară între execuția software pe un procesor general și implementarea unei funcții într-un circuit dedicat: funcționalitatea hardware poate fi modificată după fabricarea dispozitivului, prin încărcarea unei noi configurații. Platforma principală pentru acest tip de calcul e FPGA-ul (Field-Programmable Gate Array) - blocuri logice, registre, memorii și conexiuni programabile, configurate pentru a forma un circuit specific aplicației.

PlatformăFlexibilitateEficiență hardware
Procesor generalfoarte ridicată (schimbi programul)limitată de arhitectura generală
FPGAridicată (schimbi bitstream-ul)ridicată, paralelism personalizat
ASICfixă (stabilită la fabricație)foarte ridicată
Diferența esențială față de programare Un program descrie o succesiune de instrucțiuni executate de aceleași unități de calcul, reutilizate pe rând. O descriere hardware definește structura unui circuit - unde y = a·b + c·d poate folosi, simultan, două multiplicatoare paralele urmate de un sumator, în loc de două înmulțiri succesive pe aceeași unitate aritmetică.

Avantajul central e paralelismul spațial: pentru N canale independente, fiecare cu timp de procesare T_C, o implementare secvențială are T_secvențial ≈ N·T_C, în timp ce N unități hardware simultane pot atinge T_paralel ≈ T_C, plus latențele de sincronizare și colectare a rezultatelor.

Exemplu - opt canale independente

Opt canale, fiecare necesitând 10 µs: secvențial, 8 × 10 µs = 80 µs. Cu opt unități paralele, timpul rămâne apropiat de 10 µs - dar reducerea nu e automată: necesită replicarea resurselor, porturi de memorie suficiente, lățime de bandă adecvată și absența dependențelor între date.

A doua formă de paralelism, la fel de importantă, e pipeline-ul: algoritmul e împărțit în etape, fiecare procesând simultan un element diferit. După umplerea pipeline-ului, un rezultat poate fi produs la fiecare interval de inițiere (II - numărul de cicluri dintre două intrări succesive), chiar dacă latența totală rămâne de mai multe cicluri - distincția latență/throughput revine detaliat mai târziu în acest curs.

3Motivația accelerării hardware: profilare, nu presupunere8 min

Accelerarea hardware nu trebuie aplicată întregii aplicații. Aproape întotdeauna, doar o parte redusă a codului consumă o proporție semnificativă din timpul total - aceste porțiuni sunt numite zone critice, hotspot-uri sau funcții dominante. Procesul corect începe prin profilarea aplicației, nu prin alegerea anticipată a unui accelerator.

Contribuția unei funcții la timpul total
pᵢ = Tᵢ / T_total
Exercițiu rezolvat

O aplicație necesită 100 ms; filtrarea imaginilor consumă 70 ms. Ce proporție reprezintă filtrarea, și merită accelerată?

Vezi rezolvarea

p_filtru = 70/100 = 0,7

70% din timpul total e un candidat excelent - accelerarea filtrului poate îmbunătăți semnificativ aplicația. În schimb, accelerarea unei funcții care consumă doar 2% din timp va avea un efect redus, indiferent cât de performant e acceleratorul construit pentru ea.

O funcție e candidat bun pentru hardware dacă are contribuție mare la timpul total, e executată frecvent, operează asupra unor date regulate, poate fi paralelizată, iar transferul datelor nu anulează câștigul. Acest ultim punct e ușor de subestimat: timpul efectiv al unui accelerator e T_accelerat = T_trimitere + T_configurare + T_execuție + T_primire - pentru operații foarte scurte, costul comunicării CPU-FPGA poate depăși timpul economisit prin execuția hardware, temă la care revenim în detaliu în secțiunea de partiționare.

Timpul total al aplicației are mai multe componente

T_aplicație = T_control + T_calcul + T_memorie + T_I/O. Accelerarea componentei T_calcul poate avea un efect redus dacă aplicația e dominată de transferurile de memorie sau de intrare-ieșire - trebuie analizat întregul traseu al datelor, nu doar funcția matematică izolat.

4Procesor, FPGA și ASIC: comparație și prag de cost10 min

Aceeasi functie, patru platforme: energie pe operatie

Trei categorii principale de platforme de calcul: procesorul general, FPGA-ul și circuitul ASIC (Application-Specific Integrated Circuit). Nu se exclud reciproc - un produs poate folosi simultan un procesor, un FPGA și mai multe blocuri ASIC integrate.

CaracteristicăProcesorFPGAASIC
Flexibilitatefoarte ridicatăridicatăfoarte redusă
Paralelism personalizatlimitat de arhitecturăridicatfoarte ridicat
Eficiență energeticămoderatăridicată pentru sarcini adecvatefoarte ridicată
Cost inițialredusredus sau moderatfoarte ridicat
Cost unitar (volum mare)depinde de platformărelativ ridicatredus
Actualizareprin softwareprin software și bitstreamîn general imposibilă

ASIC-ul oferă performanță maximă și consum minim pentru funcția exactă pentru care a fost proiectat, dar cu cost nerecurent (NRE) foarte mare și fără posibilitatea modificării după fabricație. FPGA-ul folosește resurse programabile suplimentare (LUT-uri, rutare, memorie de configurare) pentru a rămâne flexibil, ceea ce conduce, în general, la o eficiență mai redusă de suprafață, viteză și putere față de un ASIC echivalent.

Costul total și pragul de echilibru
C_total = C_NRE + N·C_unitar. Pragul de volum la care ASIC și FPGA au același cost total: N* = (C_NRE,ASIC - C_NRE,FPGA) / (C_FPGA - C_ASIC)
Sub N*, FPGA-ul câștigă; peste N*, ASIC-ul câștigă ASIC-ul are NRE mare și cost unitar mic; FPGA-ul are NRE mic și cost unitar mai mare. Sub pragul N*, costul total al FPGA-ului rămâne mai mic (NRE-ul redus domină); peste N*, costul unitar mai mic al ASIC-ului compensează investiția inițială mare. O strategie frecventă în industrie: prototip pe FPGA → validare → ASIC la volum ridicat - dar migrarea nu e automată, descrierea hardware, memoriile și blocurile DSP specifice FPGA-ului trebuie adaptate tehnologiei ASIC.
Alegeți platforma potrivită pentru fiecare scenariu

5Arhitectura internă a unui FPGA10 min

Un FPGA modern e o matrice de resurse hardware configurabile, conectate printr-o rețea programabilă. Configurația stabilește atât funcțiile implementate în blocurile logice, cât și traseele semnalelor dintre ele. Categoriile principale de resurse: blocuri logice configurabile (CLB), registre, interconectări programabile, blocuri de intrare-ieșire, memorii interne (Block RAM), blocuri aritmetice specializate (DSP) și resurse pentru distribuția ceasului.

Blocul logic configurabil e unitatea de bază - include, de regulă, unul sau mai multe LUT-uri, registre de tip flip-flop, multiplexoare, logică rapidă de transport (carry chain) pentru sumatoare eficiente, și conexiuni către rețeaua de rutare.

Întârzierea rutării poate domina întârzierea logicii T_cale = T_logic + T_rutare, iar frecvența maximă e limitată de cea mai lentă cale sincronă: f_max ≤ 1/(T_clk→q + T_logic + T_rutare + T_setup). În multe implementări, întârzierea rutării e comparabilă sau chiar mai mare decât cea a logicii - două descrieri funcțional echivalente pot conduce la frecvențe maxime diferite după plasare și rutare, un rezultat adesea surprinzător pentru cineva venit din lumea software, unde codul „echivalent" e, de regulă, la fel de rapid.

Memoria de configurare și bitstream-ul

Configurația FPGA-ului e descrisă printr-un fișier binar numit bitstream, care stabilește conținutul LUT-urilor, starea comutatoarelor de rutare, configurația blocurilor I/O și modurile resurselor DSP/memorie. În dispozitivele bazate pe SRAM, configurația e volatilă - bitstream-ul trebuie reîncărcat la fiecare pornire, dintr-o memorie externă sau printr-un procesor.

Timpul de încărcare a configurației
T_config ≈ N_bitstream / R_config
Exercițiu rezolvat

Un bitstream de 32 Mbit e încărcat cu o rată de 100 Mbit/s. Cât durează configurarea?

Vezi rezolvarea

T_config ≈ 32/100 = 0,32 s

În practică se adaugă timpii de inițializare, verificare și pornire a resurselor interne - timpul real e mai mare decât acest calcul simplificat. Unele FPGA-uri permit reconfigurare parțială: o regiune a dispozitivului poate fi modificată fără oprirea completă a logicii din celelalte regiuni, util pentru înlocuirea dinamică a unui accelerator sau actualizarea unei funcții fără oprirea întregului sistem - cu prețul unei complexități de proiectare și verificare mai mari.

6LUT-uri și logica secvențială8 min

Unitatea logică fundamentală a unui FPGA e LUT-ul (Look-Up Table) - conceptual, o mică memorie în care intrările formează adresa, iar ieșirea e valoarea memorată la acea adresă.

Principiul LUT
F(x₃,x₂,x₁,x₀) = LUT[x₃x₂x₁x₀] - orice funcție booleană cu cel mult k intrări poate fi implementată direct într-un LUT cu k intrări.
Exemplu - funcția XOR pe două intrări

Tabelul de adevăr al F = A ⊕ B: (0,0)→0, (0,1)→1, (1,0)→1, (1,1)→0. Aceste patru valori, memorate la adresele 00, 01, 10, 11 dintr-un LUT cu 2 intrări, implementează funcția complet - fără nicio poartă logică „reală", doar o citire de memorie.

Dacă funcția are mai multe intrări decât dimensiunea unui LUT, instrumentul de sinteză o descompune în mai multe LUT-uri conectate - descompunerea poate crește numărul de niveluri logice, întârzierea și consumul, motiv pentru care numărul de intrări al LUT-ului influențează atât flexibilitatea cât și eficiența arhitecturii.

Logică combinațională vs. secvențială

O descriere combinațională produce o ieșire dependentă doar de intrările curente: y(t) = F(x₀(t), x₁(t), ...). O descriere secvențială include starea anterioară: q[n+1] = F(q[n], x[n]) - registrele asociate LUT-urilor permit implementarea mașinilor de stare, contoarelor și registrelor pipeline.

-- registru sincron cu reset si enable, in VHDL
process(clk)
begin
  if rising_edge(clk) then
    if reset = '1' then
      q <= (others => '0');
    elsif enable = '1' then
      q <= d;
    end if;
  end if;
end process;
Pipeline-ul reduce lungimea căilor combinaționale Fără registre pipeline, trei operații cu întârzierile T₁, T₂, T₃ se înlănțuie: T_comb = T₁ + T₂ + T₃. Cu registre între etape, perioada de ceas e limitată de cea mai lentă etapă individuală: T_clk ≥ max(T₁,T₂,T₃) + T_registre - latența exprimată în cicluri crește, dar throughput-ul poate crește semnificativ, exact compromisul studiat detaliat mai jos, la secțiunea de performanță.

7Resurse hardware specializate: BRAM, DSP, ceasuri8 min

Implementarea tuturor funcțiilor exclusiv prin LUT-uri și registre ar consuma resurse excesive. FPGA-urile moderne includ blocuri dedicate, mai eficiente pentru operații întâlnite frecvent.

Block RAM și memorie distribuită

Memoria distribuită folosește LUT-urile ca elemente de stocare - potrivită pentru tabele mici și registre de deplasare. Block RAM (BRAM) e o memorie fizică dedicată, configurabilă ca single-port sau dual-port, cu adâncime și lățime de cuvânt variabile.

Capacitatea unei memorii
M = N_cuvinte · W_cuvânt. Pentru 1024 cuvinte de 16 biți: M = 1024 × 16 = 16 384 biți.

Un BRAM dual-port permite două accesări în același ciclu - dar nu un număr nelimitat de utilizatori simultani; pentru mai multe citiri paralele sunt necesare replicarea memoriei, împărțirea în bănci sau arbitrarea accesului.

Blocuri DSP - Multiply-Accumulate

Operația centrală a unui bloc DSP
P = A·B + C (Multiply-Accumulate) - apare în filtre FIR, transformate, convoluții și rețele neuronale.

Un filtru FIR cu N coeficienți: y[n] = Σ h[k]x[n-k], k=0..N-1. O implementare complet paralelă poate folosi N multiplicatoare simultan; o implementare serializată reutilizează un număr mai mic de blocuri DSP, dar necesită mai multe cicluri - un compromis exprimat conceptual prin resurse · timp ≈ volum de calcul. Precizia numerică influențează direct utilizarea resurselor: un multiplicator pe 8 biți consumă mult mai puține resurse decât unul pe 32 de biți.

Ceasuri și traversarea domeniilor de ceas

Blocurile de management al ceasului (PLL/MMCM) pot multiplica frecvența, o pot diviza, deplasa faza sau genera mai multe domenii de ceas independente. Semnalele transferate între domenii de ceas diferite necesită mecanisme de Clock Domain Crossing (CDC) - un sincronizator cu două registre pentru un singur bit de control, FIFO asincron sau cod Gray pentru magistrale de date.

Conectarea directă între domenii de ceas asincrone e periculoasă

Fără mecanism CDC, o magistrală conectată direct între două domenii de ceas independente poate produce metastabilitate și date incoerente - un risc ușor de ignorat pentru cineva obișnuit doar cu programare software, unde acest concept nu are echivalent direct.

8Fluxul de proiectare FPGA8 min

Dezvoltarea unei aplicații FPGA diferă fundamental de dezvoltarea software: compilarea unui program produce instrucțiuni pentru un procesor existent, în timp ce implementarea unei descrieri hardware produce configurația unui circuit digital nou.

  1. Descrierea arhitecturii - în VHDL/Verilog (nivel RTL) sau prin HLS (High-Level Synthesis, pornind de la o funcție C/C++).
  2. Simulare funcțională - modulul e stimulat printr-un testbench, iar ieșirile sunt comparate cu rezultatele așteptate: y_HDL(x) = y_referință(x), pentru un set de scenarii ce trebuie să includă valori limită, reset și situații de overflow, nu doar cazul nominal.
  3. Sinteză logică - descrierea e transformată într-o rețea de LUT-uri, registre, DSP-uri și conexiuni.
  4. Plasare și rutare - fiecare element logic primește o poziție fizică, iar rutarea selectează traseele dintre resurse.
  5. Analiză temporală - verifică dacă circuitul respectă frecvența dorită.
  6. Generarea bitstream-ului și validarea pe hardware.
HLS nu garantează automat paralelism O funcție C++ simplă (de exemplu o buclă care adună două vectoare element cu element) descrisă pentru HLS nu devine automat hardware paralel - instrumentul decide dacă bucla e executată secvențial, desfășurată parțial, desfășurată complet sau transformată într-un pipeline, pe baza directivelor de sinteză. Codul trebuie tratat ca o descriere a unei arhitecturi posibile, nu doar ca un program obișnuit.
Marja temporală (slack)
T_arrival = T_clk→q + T_logic + T_rutare; T_required = T_clk - T_setup - T_incertitudine; Slack = T_required - T_arrival. Cerința e satisfăcută dacă Slack ≥ 0.
Slack negativ - corect în simulare, greșit pe hardware

Un slack negativ indică o încălcare temporală: circuitul poate produce rezultate corecte în simularea funcțională (care nu ține cont de întârzieri fizice), dar poate eșua pe hardware la frecvența solicitată. Corectarea implică introducerea de registre pipeline suplimentare, reducerea nivelurilor de logică între registre, sau reducerea frecvenței - dar constrângerile temporale incorecte sunt periculoase în sens opus: dacă o cale reală nu e analizată deloc, instrumentul poate raporta eronat că implementarea satisface cerințele.

Gradul de utilizare a unei resurse e U_R = N_R,utilizat / N_R,disponibil - o utilizare apropiată de 100% poate conduce la dificultăți de rutare și la reducerea frecvenței maxime; simpla încadrare în capacitatea dispozitivului nu e întotdeauna suficientă pentru o implementare eficientă.

Fluxul de proiectare pentru FPGA: puneti etapele in ordine

9Sisteme heterogene CPU-FPGA8 min

O arhitectură heterogenă combină un procesor general cu logică reconfigurabilă: procesorul execută software-ul de control, iar FPGA-ul implementează acceleratoare și interfețe cu cerințe temporale stricte. Comunicarea se împarte în cale de control (configurarea acceleratorului, scrierea parametrilor, citirea stării) și cale de date (volumele mari procesate).

// controlul conceptual al unui accelerator mapat in memorie
accelerator->source_address = input_buffer_physical_address;
accelerator->destination_address = output_buffer_physical_address;
accelerator->data_length = number_of_elements;
accelerator->control = start_command;

while ((accelerator->status & completed_flag) == 0U) {
    wait_for_interrupt_or_poll();
}

DMA - evitarea copierii element cu element

Transferul fiecărui element prin instrucțiuni CPU poate consuma mai mult timp decât procesarea propriu-zisă. Pentru volume mari se folosește DMA (Direct Memory Access): procesorul configurează transferul, dar nu copiază fiecare cuvânt.

Timpul unui transfer DMA
T_transfer = T_inițializare + D/B_efectiv, unde B_efectiv e mai mic decât lățimea de bandă teoretică, din cauza arbitrajului și latenței memoriei.
Double buffering suprapune transferul cu procesarea Cu două buffere (unul în procesare, altul în transfer, cu roluri inversate la fiecare iterație), durata unei iterații tinde spre T_iterație ≈ max(T_transfer, T_accelerator), în loc de suma celor două - un câștig relevant mai ales când transferul și calculul au durate comparabile.

Memorie partajată și coerența cache-ului

Dacă procesorul folosește cache, o valoare modificată poate să nu fie scrisă imediat în memoria vizibilă acceleratorului. Înaintea unui transfer CPU→FPGA poate fi necesar flush(cache); după ce acceleratorul scrie rezultatul, poate fi necesar invalidate(cache) înainte ca CPU-ul să citească. Sincronizarea poate folosi polling (simplu, dar consumă timp de procesor) sau întreruperi (permite CPU-ului să execute alte activități până la finalizare).

10Partiționarea hardware-software și legea lui Amdahl12 min

Partiționarea stabilește ce funcții rămân în software și ce funcții sunt implementate în FPGA. O alegere greșită poate produce un accelerator foarte rapid, dar un sistem mai lent, din cauza transferurilor și controlului suplimentar.

Mai potrivit pentru CPUMai potrivit pentru FPGA
control complex, ramificații numeroaseparalelism între date
structuri dinamiceacces regulat la memorie
actualizări frecventethroughput ridicat, funcție stabilă
Intensitatea calculului
IC = N_operații / N_bytes_transferați - o funcție cu IC mare beneficiază mai mult de accelerare; o funcție cu IC redusă poate fi limitată de memoria externă, indiferent de câte unități aritmetice implementează acceleratorul.
Exercițiu rezolvat - pragul de eficiență al unui accelerator

O operație rulează pe CPU în 2 ms. Un accelerator FPGA calculează rezultatul (nucleul de calcul propriu-zis) în doar 0,2 ms - de zece ori mai rapid - dar transferurile de date necesită 1,5 ms. Care e accelerația reală, end-to-end?

Vezi rezolvarea

T_FPGA,total = T_setup + T_calcul = 0,2 + 1,5 = 1,7 ms

S = T_CPU / T_FPGA,total = 2 / 1,7 ≈ 1,18

Deși nucleul hardware e de zece ori mai rapid decât CPU-ul, accelerația reală e doar ~18%, pentru că transferurile domină timpul total. Reducerea acestui cost necesită procesarea mai multor date per apel, păstrarea datelor în FPGA între operații succesive, sau utilizarea DMA cu double buffering.

Legea lui Amdahl pentru accelerare parțială
Dacă proporția p din aplicație e accelerată cu factorul S_A: S_total = 1 / ((1-p) + p/S_A)
Exercițiu rezolvat

60% din timpul unei aplicații poate fi accelerat de zece ori (p=0,6, S_A=10). Care e accelerația globală a aplicației complete?

Vezi rezolvarea

S_total = 1 / (0,4 + 0,6/10) = 1 / (0,4 + 0,06) = 1/0,46 ≈ 2,17

Deși funcția accelerată e de zece ori mai rapidă, aplicația completă e accelerată de doar ~2,17 ori - exact ca legea lui Amdahl studiată pentru paralelism în Cursul 05, dar aplicată aici accelerării hardware. Chiar cu un accelerator infinit de rapid (S_A → ∞), limita e S_max = 1/(1-p) = 1/0,4 = 2,5. Optimizarea trebuie să urmărească întregul flux al aplicației, nu doar funcția izolată.

Merita accelerarea hardware? Amdahl plus costul transferurilor

11Performanță, latență și utilizarea resurselor8 min

Evaluarea unui accelerator FPGA trebuie să distingă între latență, throughput, interval de inițiere, frecvență, utilizarea resurselor și lățimea de bandă - o singură valoare de „accelerație" nu descrie complet comportamentul sistemului.

Latență și throughput într-un pipeline
Pentru N_P etape la frecvența f: L_pipeline = N_P/f. Dacă intervalul de inițiere e II: Θ_pipeline = f/II.
Exercițiu rezolvat

Un pipeline cu zece etape rulează la 200 MHz, cu II=1. Care e latența primului rezultat, și cât de des apare câte un rezultat nou?

Vezi rezolvarea

L_pipeline = 10 / (200×10⁶) = 50 ns - primul rezultat apare după 50 ns.

Cu II=1, un nou rezultat poate fi acceptat la fiecare ciclu, adică la fiecare 1/(200×10⁶) = 5 ns - deci după umplerea pipeline-ului, deși fiecare element individual „durează" 50 ns (latență), sistemul produce un rezultat nou la fiecare 5 ns (throughput). Cele două valori descriu lucruri diferite și nu trebuie confundate.

Throughput-ul e limitat de lățimea de bandă disponibilă B_necesar = Θ·D, unde D e numărul de bytes per rezultat. Dacă un accelerator produce 100 de milioane de rezultate pe secundă, fiecare de 8 bytes: B_necesar = 100×10⁶ × 8 = 800 MB/s. O memorie care oferă efectiv doar 500 MB/s nu poate alimenta acceleratorul la rata proiectată, indiferent de câte unități paralele conține circuitul - soluțiile includ reutilizarea locală a datelor, Block RAM, transferuri în rafală și reducerea preciziei numerice.

O comparație corectă CPU vs. FPGA trebuie să folosească aceleași date de intrare, aceeași precizie numerică, toate transferurile (nu doar nucleul de calcul) și aceeași definiție a timpului măsurat: S = T_CPU / T_FPGA,total. Energia pentru sarcina completă, nu doar puterea instantanee, e indicatorul relevant: E ≈ P_medie · T - un FPGA poate avea o putere instantanee comparabilă cu un procesor mic, dar poate finaliza operația mult mai rapid, rezultând în energie totală mai mică.

12Configurarea și securitatea sistemelor reconfigurabile8 min

Posibilitatea reconfigurării e un avantaj important, dar introduce riscuri specifice: un atacator care poate înlocui sau modifica bitstream-ul poate schimba chiar structura hardware a sistemului, nu doar comportamentul software-ului care rulează pe el.

Autenticitate prin semnătură digitală
σ = Sign(K_privat, H(B)), unde B e bitstream-ul. Dispozitivul verifică: Verify(K_public, H(B), σ) = valid înainte de a activa logica.
Autenticitate și confidențialitate sunt obiective diferite Semnătura demonstrează că o configurație provine de la o sursă autorizată și nu a fost modificată. Criptarea (B_criptat = Enc(K_dispozitiv, B)) protejează proprietatea intelectuală, împiedicând interpretarea directă a configurației - dar criptarea, singură, nu demonstrează autenticitatea. Un sistem sigur folosește ambele mecanisme.

Secure Boot stabilește un lanț de încredere: ROM de pornire → bootloader → bitstream → software, fiecare etapă verificând-o pe următoarea. O actualizare sigură parcurge descărcarea pachetului, verificarea semnăturii și versiunii, stocarea temporară, activarea controlată și confirmarea funcționării - iar numărul versiunii trebuie să respecte V_nou > V_minim_acceptat, o protecție directă împotriva atacurilor de tip rollback (reinstalarea unei versiuni vechi, semnate corect, dar cunoscută ca vulnerabilă).

Recuperarea automată la eșec de pornire

Un sistem robust păstrează o imagine de recuperare protejată separat de imaginea principală. Dacă noua configurație nu finalizează pornirea într-un timp stabilit, sistemul revine automat la imaginea de recuperare, evitând o „cărămidă" (dispozitiv complet nefuncțional) în urma unei actualizări eșuate.

Securitatea configurației nu elimină atacurile fizice: un adversar cu acces la dispozitiv poate analiza consumul energetic, emisiile electromagnetice sau durata operațiilor (atacuri prin canal lateral), sau poate încerca fault injection - producerea de erori controlate prin variații de tensiune, ceas sau temperatură, urmărind ca o eroare produsă exact în timpul verificării să determine acceptarea unei configurații invalide. Interfețele de depanare (precum JTAG), utile în dezvoltare, trebuie dezactivate, autentificate sau restricționate în produsul final - protejarea exclusivă a bitstream-ului nu ajută dacă bootloader-ul sau interfața de depanare rămân deschise.

13Erori frecvente5 min

  • „Accelerarea de zece ori a celei mai lente funcții înseamnă aplicație de zece ori mai rapidă." Fals - legea lui Amdahl arată că accelerația globală e limitată de proporția din aplicație care a fost efectiv accelerată, nu doar de factorul de accelerare al acelei părți. Calculați S_total = 1/((1-p) + p/S_A) înainte de a promite o accelerație globală.
  • „Un nucleu hardware de zece ori mai rapid garantează un accelerator de zece ori mai rapid, end-to-end." Nu - timpul de transfer CPU↔FPGA poate domina complet timpul de calcul propriu-zis, mai ales pentru operații scurte sau volume mici de date. Includeți întotdeauna T_setup, T_input și T_output în calculul accelerării reale.
  • „Un slack pozitiv în raportul de sinteză garantează funcționarea corectă pe hardware." Doar dacă toate căile relevante au fost analizate corect - constrângeri temporale incomplete sau greșite pot ascunde o cale reală care nu respectă frecvența. Verificați că toate căile critice sunt acoperite de constrângerile temporale, nu doar că raportul arată slack pozitiv.

14Rezumat și glosar5 min

FPGA-ul ocupă o poziție intermediară între flexibilitatea unui procesor general și eficiența unui ASIC dedicat, oferind paralelism spațial și pipeline configurabile după fabricație. Blocurile LUT implementează logică arbitrară prin memorie mică, iar resursele specializate (Block RAM, DSP, PLL-uri) evită consumul excesiv de LUT-uri pentru operații frecvente. Fluxul de proiectare hardware - simulare, sinteză, plasare/rutare, analiză temporală - diferă fundamental de compilarea software, iar un slack negativ semnalează o eroare pe care simularea funcțională nu o detectează. Partiționarea corectă a unei aplicații între CPU și FPGA trebuie să pornească de la profilare, să includă costul complet al transferurilor, și să țină cont de legea lui Amdahl: accelerarea unei funcții, oricât de spectaculoasă, e limitată de proporția pe care acea funcție o reprezintă din aplicația completă. Securitatea unei configurații reconfigurabile cere atât autenticitate (semnătură) cât și confidențialitate (criptare), plus protecție împotriva atacurilor fizice.

FPGA
Field-Programmable Gate Array - circuit reconfigurabil după fabricație.
LUT
Look-Up Table - memorie mică ce implementează o funcție logică arbitrară.
Bitstream
fișierul de configurare care stabilește funcția și rutarea unui FPGA.
HLS
High-Level Synthesis - generarea automată de hardware dintr-o descriere de nivel înalt (C/C++).
Slack
marja temporală a unei căi sincrone; negativ = încălcare a frecvenței cerute.
Interval de inițiere (II)
numărul de cicluri dintre două intrări succesive acceptate de un pipeline.
Intensitate a calculului
numărul de operații efectuate per byte transferat.

15Întrebări de verificare6 min

  1. Ce diferență fundamentală există între a programa un procesor și a configura un FPGA?
  2. De ce trebuie profilarea să preceadă alegerea unei funcții pentru accelerare hardware?
  3. Cum se calculează pragul de volum N* la care ASIC-ul devine mai avantajos decât FPGA-ul?
  4. Explicați principiul unui LUT folosind exemplul funcției XOR.
  5. Ce reprezintă slack-ul temporal, și de ce un slack negativ nu apare în simularea funcțională?
  6. De ce accelerarea unui nucleu de calcul de zece ori nu produce automat o accelerație globală de zece ori?
  7. Care e diferența dintre autenticitatea și confidențialitatea unui bitstream?

16Direcții de aprofundare2 min

Cursul următor schimbă din nou direcția: energy harvesting - cum poate un sistem embedded să-și extragă singur energia din mediu (solar, vibrații, termic, RF), și ce înseamnă proiectarea unui sistem care nu poate presupune niciodată o sursă de energie constantă.

Conceptele din acest curs - paralelism spațial, pipeline, partiționare hardware/software - se regăsesc, aplicate practic, în orice proiect care combină un procesor cu logică programabilă; platforme precum Xilinx Zynq sau Intel/Altera Cyclone SoC integrează exact arhitectura CPU+FPGA discutată aici pe un singur circuit.