Cours FPGA Complet — Circuits Logiques Programmables
De l'architecture interne d'un FPGA jusqu'au flot de conception Vivado / Quartus : LUT, BRAM, DSP, contraintes XDC, simulation, debug ILA et exemples VHDL prêts à flasher sur Basys 3, Nexys A7 ou DE10-Nano.
Sommaire
1. Introduction aux FPGA
Objectifs du chapitre
- Définir un FPGA et comprendre son rôle dans le numérique moderne
- Connaître l'historique et l'évolution des FPGA
- Comparer un FPGA aux ASIC et aux microcontrôleurs
- Identifier les domaines d'application des FPGA
Historique :
- 1984 — Premier FPGA par Xilinx (XC2064)
- 1992 — Introduction des LUT 4 entrées
- 2000 — Intégration de blocs DSP et mémoire
- 2010 — SoC FPGA (ARM + FPGA sur la même puce)
- 2020+ — FPGA haute performance (Versal, Agilex)
Le FPGA se situe entre le microcontrôleur (flexibilité logicielle, performance modeste) et l'ASIC (performance maximale, coût unitaire très bas mais NRE énorme). Voici une synthèse :
| Critère | FPGA | ASIC | Microcontrôleur |
|---|---|---|---|
| Coût NRE | Faible | Très élevé | Nul |
| Coût unitaire | Moyen à élevé | Très faible (en volume) | Faible |
| Performance | Élevée | Maximale | Modérée |
| Consommation | Moyenne | Optimisée | Faible |
| Flexibilité | Totale (matérielle) | Nulle | Logicielle uniquement |
| Time-to-market | Court | Long (12-18 mois) | Très court |
| Parallélisme | Massif (matériel) | Massif | Limité (CPU séquentiel) |
Les FPGA excellent dans les domaines où le parallélisme matériel et la performance déterministe priment :
Télécom
5G, stations de base, radio logicielle (SDR)
Aérospatial
Satellites, avionique, FPGA durcis aux radiations
Médical
Imagerie, échographie, traitement temps réel
Automobile
ADAS, conduite autonome, fusion de capteurs
IA / ML
Accélération d'inférence, réseaux de neurones
Finance
Trading haute fréquence, cryptographie
2. Architecture des FPGA
Objectifs du chapitre
- Comprendre l'organisation interne d'un FPGA
- Identifier le rôle d'un CLB, d'une LUT, d'une bascule
- Connaître les ressources dédiées (BRAM, DSP, PLL, GTx)
- Savoir distinguer slice logique et slice mémoire
Un FPGA moderne est constitué d'une matrice régulière de ressources hétérogènes reliées par un réseau d'interconnexion programmable. L'organisation typique :
┌─────────────────────────────────────────────────────────────┐ │ FPGA │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ I/O Blocks │ │ │ └─────────────────────────────────────────────────────┘ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ CLB │ │ CLB │ │ CLB │ │BRAM │ │ CLB │ │ CLB │ │ │ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ │ │ │ │ │ │ │ │ Routing │ │ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ │ │ │ CLB │ │ DSP │ │ CLB │ │ CLB │ │ DSP │ │ CLB │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ PLL │ │ Clock │ │ PLL │ │ │ │ (CMT) │ │ Tree │ │ (CMT) │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ CLB = Configurable Logic Block BRAM = Block RAM DSP = Digital Signal Processing PLL = Phase-Locked Loop CMT = Clock Management Tile
Le CLB (Configurable Logic Block) est l'élément logique de base. Il contient des LUT (Look-Up Tables), des bascules (flip-flops) et de la logique de retenue (carry chain) pour les opérations arithmétiques.
Structure d'une LUT. Une LUT 4 entrées est en fait une mémoire SRAM de 16 bits qui implémente n'importe quelle fonction booléenne à 4 variables :
LUT 4 entrées (16 bits de configuration)
A ──┐
B ──┼──► ┌────────────┐
C ──┼──► │ SRAM │ ──► Sortie
D ──┘ │ 16 bits │
└────────────┘
Peut implémenter N'IMPORTE quelle fonction de 4 variables :
- AND, OR, XOR, NAND, NOR, XNOR
- Multiplexeur 2:1
- Comparateur
- Addition (avec chaîne de retenue)
Slices Xilinx 7-series :
- SLICEL (L = Logic) : 4 LUT6, 8 flip-flops, chaîne de retenue — pour la logique pure
- SLICEM (M = Memory) : SLICEL + RAM distribuée (64 bits/slice) + registres à décalage (32 bits/slice)
Outre les CLB génériques, un FPGA embarque des blocs durs (hard IP) dédiés à des tâches spécifiques :
| Ressource | Fonction | Capacité typique |
|---|---|---|
| Block RAM (BRAM) | Mémoire embarquée double-port | 18 Kb ou 36 Kb par bloc |
| DSP48 | Multiplieur-accumulateur 25×18 + 48 bits acc. | Pipeline interne, pré-additionneur |
| IOB | Interface d'entrée/sortie | LVDS, LVCMOS, DDR, SSTL |
| PLL / MMCM | Génération d'horloge | Multiplication, division, déphasage |
| GTx / GTH | Transceiver série haute vitesse | Jusqu'à 28 Gbps |
| PCIe | Interface bus rapide | Gen3 / Gen4 hard IP |
| Hard processor (SoC) | Cœur ARM Cortex-A embarqué | Zynq, Cyclone V SoC |
3. Technologies de configuration
Objectifs du chapitre
- Connaître les trois grandes technologies de programmation
- Comprendre la notion de volatilité et de reprogrammabilité
- Choisir la bonne technologie selon le contexte industriel
La « configuration » d'un FPGA est l'ensemble des bits qui définissent la fonction de chaque LUT, l'état de chaque switch d'interconnexion et le mode de chaque bloc IP. Trois technologies coexistent :
| Technologie | Volatile | Reprogrammable | Fabricants |
|---|---|---|---|
| SRAM | Oui | ∞ (illimité) | Xilinx, Intel |
| Flash | Non | ~1 000 cycles | Microchip, Lattice |
| Antifuse | Non | Non (OTP) | Microchip (Axcelerator) |
FPGA basés SRAM. C'est la technologie dominante (Xilinx, Intel/Altera). Caractéristiques :
- Configuration perdue à chaque mise hors tension
- Nécessite une mémoire externe (Flash SPI, EEPROM, microSD)
- Temps de configuration : quelques ms à quelques secondes
- Avantage : dernière technologie de process, densités les plus élevées
- Inconvénient : sensible aux radiations (SEU), bitstream parfois chiffrable
FPGA Flash (Microchip PolarFire, Lattice iCE40) : la configuration est stockée dans des cellules Flash non volatiles, intégrées sur la puce. Démarrage instantané, immunité aux radiations, faible consommation. Limité en densité par rapport au SRAM.
FPGA Antifuse : chaque cellule est un fusible microscopique qu'on grille une fois pour créer une connexion. One-Time Programmable (OTP), mais extrêmement robuste face aux radiations — utilisé dans le spatial et le militaire.
4. Flot de conception
Objectifs du chapitre
- Connaître les étapes du flot HDL → bitstream
- Comprendre le rôle de la synthèse, du placement et du routage
- Savoir lire les rapports Vivado / Quartus
Le passage du code HDL au bitstream qui programme le FPGA suit un flot bien défini :
┌─────────────────┐
│ Spécification │
│ (Cahier des │
│ charges) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Description │ ◄── VHDL / Verilog / Schématique
│ HDL │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Simulation │ ◄── Testbench, vérification fonctionnelle
│ Fonctionnelle │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Synthèse │ ◄── Traduction en primitives (LUT, FF)
│ │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Implémentation │ ◄── Placement + Routage
│ (Place & Route)│
└────────┬────────┘
│
▼
┌─────────────────┐
│ Simulation │ ◄── Timing, vérification post-implémentation
│ Temporelle │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Génération │ ◄── Fichier de configuration (.bit / .sof)
│ Bitstream │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Programmation │ ◄── Chargement dans le FPGA via JTAG
│ FPGA │
└─────────────────┘
La synthèse transforme le code HDL en un netlist de primitives FPGA (LUT, flip-flops, BRAM, DSP). L'outil applique des optimisations logiques :
- Area : minimise les ressources utilisées (LUT, FF, BRAM)
- Speed : maximise la fréquence d'horloge (registres, pipeline)
- Power : réduit la consommation (clock gating, désactivation)
if sans else dans un process combinatoire synthétise un latch, presque toujours un bug.L'implémentation se décompose en deux grandes phases :
- Placement : attribution de chaque primitive logique à un emplacement physique (CLB précis, BRAM précis) sur le die.
- Routage : utilisation des ressources d'interconnexion programmables pour relier les primitives entre elles.
Rapports importants à consulter :
- Utilization Report : ressources utilisées (LUT, FF, BRAM, DSP, IO)
- Timing Report : respect des contraintes temporelles (slack, WNS, TNS)
- Power Report : estimation de consommation statique et dynamique
- Clock Report : hiérarchie d'horloges et fréquences générées
5. Outils de développement
Objectifs du chapitre
- Connaître les principaux IDE par fabricant
- Identifier les simulateurs HDL gratuits et payants
- Choisir l'outil adapté à son projet
Chaque grand fabricant de FPGA fournit un IDE complet, gratuit dans sa version « Web » ou « Lite » :
| Fabricant | Outil | Familles FPGA | Licence |
|---|---|---|---|
| AMD / Xilinx | Vivado Design Suite | 7-series, UltraScale, Versal | Gratuit (WebPack) |
| AMD / Xilinx | ISE (legacy) | Spartan-6, Virtex-6 | Plus maintenu |
| Intel / Altera | Quartus Prime | Cyclone, Arria, Stratix, Agilex | Gratuit (Lite) |
| Lattice | Diamond / Radiant | iCE40, ECP5, Nexus | Gratuit |
| Microchip | Libero SoC | PolarFire, SmartFusion, IGLOO | Gratuit (Silver) |
| Yosys + nextpnr | Flot open source | iCE40, ECP5, Gowin | 100 % libre |
La simulation se fait avant la synthèse pour valider la fonctionnalité et après l'implémentation pour valider le timing :
- ModelSim / QuestaSim : référence industrielle (Mentor / Siemens) — VHDL et Verilog, version « Starter » gratuite limitée
- Vivado Simulator (xsim) : intégré à Vivado, gratuit, suffisant pour la plupart des cas
- ModelSim-Altera Starter : fourni avec Quartus Prime Lite
- GHDL : simulateur VHDL open source, très correct, parfait pour CI/CD
- Icarus Verilog : simulateur Verilog open source léger
- Verilator : compilateur Verilog → C++, simulation extrêmement rapide (utilisé pour le co-simulation)
Le flot open source Yosys + nextpnr est entièrement utilisable pour :
- Lattice iCE40 : cartes iCEBreaker, iCEStick, ULX3S, OrangeCrab
- Lattice ECP5 : cartes ULX3S, Colorlight 5A-75B, OrangeCrab
- Gowin GW1N : cartes Tang Nano (très bon marché)
6. Contraintes & timing
Objectifs du chapitre
- Écrire un fichier de contraintes XDC correct
- Comprendre les notions de setup, hold et slack
- Interpréter un rapport de timing Vivado / Quartus
Le fichier de contraintes indique à l'outil : quelle broche physique correspond à quel port HDL, quelle est la fréquence d'horloge cible, et quelles sont les exceptions de timing. Au format XDC (Xilinx Design Constraints) ou SDC (Synopsys, utilisé par Quartus) :
# Contraintes d'horloge create_clock -period 10.000 -name sys_clk [get_ports clk] # Contraintes de pins (FPGA Basys3) set_property PACKAGE_PIN W5 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports clk] # LEDs set_property PACKAGE_PIN U16 [get_ports {led[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}] # Boutons set_property PACKAGE_PIN T18 [get_ports reset] set_property IOSTANDARD LVCMOS33 [get_ports reset] # Switches set_property PACKAGE_PIN V17 [get_ports {sw[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
PACKAGE_PIN) dépend de la carte. Voir le schematic de la Basys 3 pour la liste complète.L'analyse temporelle (static timing analysis) vérifie que tous les chemins logiques respectent les contraintes définies dans le fichier XDC/SDC.
Concepts clés :
- Setup Time (Tsu) : temps avant le front d'horloge pendant lequel la donnée doit être stable
- Hold Time (Th) : temps après le front pendant lequel la donnée doit rester stable
- Slack : marge temporelle — positif = OK, négatif = violation
- WNS (Worst Negative Slack) : pire slack sur l'ensemble du design (en setup)
- TNS (Total Negative Slack) : somme des slacks négatifs sur tous les chemins en violation
- Fmax : fréquence maximale atteignable = 1 / (Tperiod − WNS)
Quelques attributs Vivado utiles pour guider l'outil :
# Garder une hiérarchie lors du routage set_property DONT_TOUCH true [get_cells u_eth_mac/*] # Forcer un bloc dans une région (Pblock) — pour le floorplanning create_pblock pblock_eth add_cells_to_pblock [get_pblocks pblock_eth] [get_cells u_eth_mac] resize_pblock [get_pblocks pblock_eth] -add {SLICE_X10Y50:SLICE_X30Y80} # Contrainte de période spécifique sur un sous-module create_clock -period 5.000 -name clk_fast [get_pins u_dsp/clk]
7. Debug & vérification
Objectifs du chapitre
- Connaître les outils de debug intégrés au FPGA
- Savoir insérer un ILA / VIO dans un design Vivado
- Utiliser la simulation pour valider un design avant synthèse
Les FPGA modernes embarquent des blocs de debug qui permettent d'observer et de contrôler le design en cours d'exécution, sans instrumenter physiquement le circuit :
- ILA (Integrated Logic Analyzer) : capture de signaux internes en temps réel, équivalent d'un analyseur logique mais à l'intérieur du FPGA
- VIO (Virtual I/O) : contrôle et observation de signaux via JTAG — comme si vous aviez des boutons / LEDs virtuels
- JTAG-to-AXI : accès direct aux bus mémoire AXI depuis Vivado, idéal pour lire / écrire la DDR
- SDK / MicroBlaze : pour les FPGA avec cœur soft, exécution de code C sur un mini-processeur embarqué
Une bonne stratégie mélange simulation, testbench et debug in-situ :
- Testbench VHDL/Verilog : simule les stimuli et vérifie les sorties (assert)
- Simulation fonctionnelle : avant synthèse, vérifie la logique pure
- Simulation post-implémentation : tient compte du timing réel
- Debug sur carte : capture de signaux internes via ILA / VIO
- Test unitaire par bloc : valider chaque sous-module indépendamment
- Couverture de code : identifier les branches HDL non testées
8. Applications pratiques
Objectifs du chapitre
- Connaître les cartes de développement les plus utilisées
- Savoir choisir une carte selon son budget et son besoin
- Implémenter un premier design complet VHDL + XDC
Le choix de la carte conditionne l'apprentissage et les projets possibles :
| Carte | FPGA | Prix | Usage |
|---|---|---|---|
| Basys 3 | Artix-7 35T | ~150 € | Éducation (référence Digilent) |
| Nexys A7 | Artix-7 100T | ~300 € | Éducation avancée, plus d'IO |
| Arty A7 | Artix-7 35T / 100T | ~130 € | Maker, prototypage, Pmod |
| DE10-Nano | Cyclone V SoC | ~180 € | SoC ARM + FPGA, retrogaming |
| iCEBreaker | iCE40UP5K | ~70 € | Open source, Yosys / nextpnr |
| Tang Nano | Gowin GW1N-1 | ~15 € | Ultra-budget, open source |
Premier design complet : un compteur 27 bits incrémenté à 100 MHz, dont le bit de poids fort fait clignoter une LED à environ 0,75 Hz.
Code VHDL :
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity blink is port ( clk : in std_logic; -- 100 MHz led : out std_logic ); end entity; architecture behavioral of blink is signal counter : unsigned(26 downto 0) := (others => '0'); begin process(clk) begin if rising_edge(clk) then counter <= counter + 1; end if; end process; led <= counter(26); -- ~0,75 Hz end architecture;
counter(26) change tous les 2²⁶ ≈ 67 millions de coups d'horloge. À 100 MHz, ça donne une période de 0,67 s — donc une LED qui clignote à environ 0,75 Hz.Contraintes XDC (Basys 3) :
## Horloge 100 MHz sur la broche W5 set_property PACKAGE_PIN W5 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports clk] create_clock -period 10.000 -name sys_clk [get_ports clk] ## LED[0] sur la broche U16 set_property PACKAGE_PIN U16 [get_ports led] set_property IOSTANDARD LVCMOS33 [get_ports led]
Étapes sous Vivado :
- Create Project → cible
xc7a35tcpg236-1(Basys 3 par défaut) - Ajouter
blink.vhdcomme Design Source - Ajouter
basys3_blink.xdccomme Constraints - Run Synthesis → vérifier le rapport (1 LUT, 27 FF)
- Run Implementation → vérifier le timing (slack largement positif à 100 MHz)
- Generate Bitstream → produit
blink.bit - Open Hardware Manager → connecter la Basys 3 en USB → Program Device
- La LED clignote. Premier FPGA programmé. ✨
Quelques idées de projets progressifs après la LED clignotante :
- Compteur 7 segments : afficher un compteur hexadécimal sur l'afficheur de la Basys 3
- Chenillard : séquence de LEDs commandée par un bouton ou un switch
- UART loopback : transmettre en boucle ce qu'on reçoit sur le port USB-UART
- Multiplieur pipeline : multiplier deux nombres 16 bits en 1 cycle grâce aux blocs DSP
- FIR filter : filtre numérique RIF sur un flux d'échantillons ADC
- CPU soft (RISC-V) : instanciation d'un cœur RISC-V (PicoRV32, Ibex) et exécution de code C