Leçon 23 sur 23

Chapitre 23 — Développement d’un système numérique complet

Projet final — Finalité du chapitre

Mobiliser l’ensemble des acquis du cours pour spécifier, concevoir, vérifier, synthétiser, implanter et valider un système numérique hiérarchique sur FPGA.

Objectifs pédagogiques

À la fin de ce chapitre, l’étudiant devra être capable de :

  • transformer un besoin en cahier des charges vérifiable ;
  • décomposer un système en composants hiérarchiques ;
  • associer circuits combinatoires, registres, compteurs et machines à états ;
  • définir les interfaces et les contrats temporels entre blocs ;
  • développer des bancs de test unitaires et un testbench d’intégration ;
  • lire les rapports de synthèse, d’utilisation et de timing ;
  • créer les contraintes de broches et d’horloge ;
  • générer puis charger le bitstream ;
  • mettre en œuvre une validation matérielle reproductible ;
  • présenter une architecture, des résultats et des limites de manière professionnelle.

Notions mobilisées

Notion

Utilisation dans le projet

Conception hiérarchiqueDécomposition en blocs testables et réutilisables
CombinatoireDécodage, multiplexage, calculs et génération des sorties
SéquentielRegistres, mémorisation, synchronisation et pipeline
Machines à étatsSéquençage des modes et protocoles
Compteurs et registresTemporisation, mesure, stockage et décalage
TestbenchVérification automatique des blocs et du système
SynthèseTransformation en ressources matérielles
ContraintesBroches, horloges et exigences temporelles
Programmation FPGAGénération et chargement du bitstream
Validation matérielleEssais réels, instrumentation et diagnostic

 

Organisation du chapitre

Partie

Contenu

23.1Démarche complète de développement
23.2Architecture hiérarchique et intégration
23.3Stratégie de vérification
23.4Synthèse, contraintes et implantation
23.5Validation matérielle et documentation
Projets 1 à 7Sept sujets détaillés et extensibles
ÉvaluationLivrables, soutenance et barème

 

Critère de réussite — Projet démontrable

Un projet réussi ne se limite pas à un code qui compile. Il doit fournir des preuves : tests automatisés, rapports de synthèse, timing respecté, comportement observable sur carte et documentation.

 

23.1 Démarche complète de développement

23.1.1 Analyse du besoin

Le projet commence par une description fonctionnelle indépendante du code VHDL.

Question

Exemple

Que doit faire le système ?Mesurer un temps et l’afficher
Quelles sont les entrées ?Boutons, clavier, liaison série
Quelles sont les sorties ?LED, afficheurs, PWM, UART
Quelles performances ?Précision, fréquence, latence
Quels cas d’erreur ?Code faux, timeout, overflow
Comment valider ?Scénarios simulés et essais sur carte

 

23.1.2 Cahier des charges vérifiable

Exemple d’exigences  |  Spécification
REQ-01 : Le système utilise l'horloge de la carte.
REQ-02 : Une pression validée produit une seule action.
REQ-03 : Le reset ramène le système à l'état initial.
REQ-04 : La sortie est mise à jour dans la latence spécifiée.
REQ-05 : Aucun latch involontaire n'est synthétisé.
REQ-06 : Le timing respecte la fréquence de la carte.

 

23.1.3 Exigences fonctionnelles et non fonctionnelles

Type

Exemples

FonctionnellesModes, opérations, séquences, affichage, communication
TemporellesDurée, fréquence, timeout, latence
MatériellesBroches, tension, nombre d’afficheurs, mémoire
QualitéPortabilité, réutilisation, documentation, testabilité
SécuritéÉtat sûr au reset, limitation d’essais, arrêt moteur

 

23.1.4 Diagramme de contexte

Contexte générique  |  Architecture
                  +----------------------+
Entrées utilisateur --->|                      |---> Affichage
Capteurs -------------> |      SYSTÈME FPGA     |---> Communication
Horloge / reset -------> |                      |---> Actionneur
                  +----------------------+

 

23.1.5 Décomposition en fonctions

1. Acquisition et adaptation des entrées.

2. Traitement de contrôle par FSM.

3. Chemin de données : registres, compteurs, UAL ou mémoire.

4. Génération de temps et de ticks.

5. Formatage et pilotage des sorties.

6. Diagnostic et gestion des erreurs.

23.1.6 Définition des interfaces

Signal

Questions à préciser

dataLargeur, signe, format Q, ordre des bits
valid / readyQuand le transfert est-il effectif ?
start / busy / doneDurée des impulsions et latence
enableQuel registre est mis à jour ?
resetPolarité et stratégie synchrone/asynchrone
clkDomaine et fréquence

 

23.1.7 Planification

Jalon

Résultat attendu

J1 — SpécificationExigences, interface et architecture
J2 — Blocs élémentairesSimulation unitaire réussie
J3 — IntégrationTestbench système réussi
J4 — SynthèseRessources et RTL analysés
J5 — ImplantationTiming respecté, bitstream généré
J6 — ValidationScénarios matériels documentés
J7 — LivraisonRapport, code, démonstration et soutenance

 

23.1.8 Gestion des versions

  • conserver un dépôt par projet ;
  • séparer sources, tests, contraintes et documentation ;
  • effectuer des commits fonctionnels ;
  • étiqueter la version démontrée ;
  • ne pas modifier plusieurs sous-systèmes sans test intermédiaire.

23.1.9 Arborescence recommandée

Organisation du dépôt  |  Arborescence
projet_fpga/
├── rtl/
│   ├── packages/
│   ├── common/
│   ├── control/
│   ├── datapath/
│   └── top/
├── sim/
│   ├── unit/
│   └── integration/
├── constraints/
├── scripts/
├── reports/
├── doc/
└── README.md

 

23.1.10 Critères de passage entre étapes

Passage

Condition minimale

Codage → intégrationTests unitaires réussis
Intégration → synthèseTestbench système sans erreur
Synthèse → implantationAucun latch ou warning critique
Implantation → carteTiming respecté et broches vérifiées
Carte → livraisonScénarios matériels reproductibles

 

23.2 Architecture hiérarchique et intégration

23.2.1 Niveau supérieur

Le top-level associe les broches physiques aux blocs génériques et adapte les polarités.

Squelette du top-level  |  VHDL
architecture structurelle of systeme_top is
    signal bouton_sync   : std_logic;
    signal bouton_filtre : std_logic;
    signal impulsion     : std_logic;
    signal affichage     : std_logic_vector(15 downto 0);
begin
    U_ENTREES  : entity work.gestion_entrees(rtl) port map (...);
    U_CONTROLE : entity work.controleur(rtl)      port map (...);
    U_DONNEES  : entity work.chemin_donnees(rtl) port map (...);
    U_SORTIES  : entity work.gestion_sorties(rtl) port map (...);
end architecture structurelle;

 

23.2.2 Séparation contrôle / chemin de données

Contrôle

Chemin de données

FSM et prioritésRegistres et compteurs
start, enable, loadCalculs et comparaisons
gestion des modesMémoires et UAL
gestion des erreursDonnées affichées ou transmises

 

23.2.3 Contrat entre blocs

Handshake simple  |  VHDL
-- La source maintient data tant que ready = 0.
-- Le transfert a lieu lorsque valid = 1 et ready = 1.
transfert <= valid and ready;

 

23.2.4 Paramétrage

Génériques communs  |  VHDL
generic (
    F_CLK_HZ        : positive := 50_000_000;
    LARGEUR_DONNEES : positive := 8;
    DUREE_MS        : positive := 1000
);

 

23.2.5 Paquetage du projet

projet_pkg.vhd — Déclarations  |  VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

package projet_pkg is
    subtype octet_t is std_logic_vector(7 downto 0);
    subtype compteur_t is unsigned(15 downto 0);

    type mode_t is (ARRET, ACTIF, ERREUR);

    function clog2(n : positive) return natural;
end package projet_pkg;

 

projet_pkg.vhd — Fonction clog2  |  VHDL
package body projet_pkg is
    function clog2(n : positive) return natural is
        variable valeur : natural := n - 1;
        variable bits   : natural := 0;
    begin
        while valeur > 0 loop
            valeur := valeur / 2;
            bits := bits + 1;
        end loop;
        return bits;
    end function;
end package body projet_pkg;

 

23.2.6 Gestion des entrées

Chaîne recommandée  |  Architecture
entrée_physique
    -> adaptation_polarité
    -> synchroniseur_2_ff
    -> anti_rebond_si_nécessaire
    -> détection_de_front
    -> logique_du_projet

 

23.2.7 Base de temps partagée

Un générateur de ticks évite de créer plusieurs horloges logiques.

Tick d’une milliseconde  |  VHDL
constant DIVISEUR_1MS : positive := F_CLK_HZ / 1000;

process(clk)
begin
    if rising_edge(clk) then
        tick_1ms <= '0';
        if compteur_ms = DIVISEUR_1MS-1 then
            compteur_ms <= 0;
            tick_1ms <= '1';
        else
            compteur_ms <= compteur_ms + 1;
        end if;
    end if;
end process;

 

23.2.8 Intégration incrémentale

1. Intégrer d’abord l’horloge, le reset et une LED de vie.

2. Ajouter la chaîne d’entrée et vérifier les impulsions.

3. Ajouter le chemin de données.

4. Ajouter la FSM de contrôle.

5. Ajouter l’affichage ou la communication.

6. Ajouter les erreurs et le diagnostic.

23.2.9 Signaux de diagnostic

  • état courant de la FSM ;
  • ticks et compteurs terminaux ;
  • impulsions de boutons ;
  • flags overflow, timeout ou erreur ;
  • valid, busy et done des interfaces.

23.3 Stratégie de vérification

23.3.1 Plan de vérification

Exigence

Test

Preuve

ResetActiver pendant chaque modeÉtat initial observé
Fonction nominaleScénario principalAssertions réussies
LimitesMin/max, débordementFlags corrects
ErreurStimulus invalideÉtat sûr ou alarme
Timing fonctionnelCompter les cyclesLatence conforme
CarteRépéter le scénarioTableau de validation

 

23.3.2 Tests unitaires

  • générateur de tick ;
  • anti-rebond ;
  • compteur ou UAL ;
  • FSM ;
  • driver d’affichage ;
  • interface de communication.

23.3.3 Testbench d’intégration

Squelette  |   VHDL
entity tb_systeme is
end entity;

architecture simulation of tb_systeme is
    constant PERIODE : time := 20 ns;
    signal clk   : std_logic := '0';
    signal reset : std_logic := '0';
begin
    clk <= not clk after PERIODE/2;

    DUT : entity work.systeme_top(rtl)
        generic map (
            -- Valeurs réduites pour la simulation.
            F_CLK_HZ => 1000
        )
        port map (...);

    stimuli : process
    begin
        -- Reset, scénarios nominaux et erreurs.
        wait;
    end process;
end architecture;

 

23.3.4 Valeurs accélérées pour la simulation

Simulation — Conserver le comportement

Réduire un nombre de cycles est acceptable si le rapport entre événements reste cohérent. Les valeurs réelles sont restaurées pour la synthèse.

 

23.3.5 Procédures de stimulus

Appui de bouton réutilisable  |  VHDL
procedure appuyer(
    signal bouton : out std_logic;
    constant duree : time
) is
begin
    bouton <= '1';
    wait for duree;
    bouton <= '0';
end procedure;

 

23.3.6 Assertions

Validation d’un état  |   VHDL
assert etat_observe = ETAT_ATTENDU
    report "État incorrect après le scénario"
    severity error;

 

Timeout global  |   VHDL
timeout : process
begin
    wait for 10 ms;
    assert false
        report "Timeout du projet final"
        severity failure;
end process;

 

23.3.7 Couverture des scénarios

Catégorie

Exemples

NominalUtilisation prévue du début à la fin
LimiteValeur maximale, passage 59→00, duty 0/100 %
ErreurCode faux, trame invalide, overflow
ResetReset dans chaque état
ConcurrenceDeux boutons simultanés ou demandes proches
EnduranceNombreuses répétitions

 

23.3.8 Régression

Chaque bug découvert pendant l’intégration ou sur carte devient un cas de test permanent.

23.4 Synthèse, contraintes et implantation

23.4.1 Vérifications avant synthèse

  • aucune erreur du testbench ;
  • aucun latch involontaire ;
  • toutes les tailles et conversions vérifiées ;
  • entité supérieure correcte ;
  • valeurs réelles des génériques restaurées ;
  • sources de simulation exclues du top synthétisable.

23.4.2 Ressources à analyser

Ressource

Question

LUTLa logique combinatoire est-elle raisonnable ?
BasculesLes registres correspondent-ils à l’architecture ?
BRAMLes mémoires sont-elles inférées ?
DSPLes multiplications utilisent-elles les blocs dédiés ?
ClockingLes horloges utilisent-elles les ressources prévues ?
I/OLe nombre de broches est-il compatible ?

 

23.4.3 Contraintes d’horloge

Exemple XDC  |   Contraintes
create_clock -period 20.000 \
  -name clk_carte \
  [get_ports clk_carte]

 

23.4.4 Contraintes de broches

Exemple conceptuel  |  Contraintes
set_property PACKAGE_PIN <PIN_CLK> [get_ports clk_carte]
set_property IOSTANDARD LVCMOS33 [get_ports clk_carte]

set_property PACKAGE_PIN <PIN_LED0> [get_ports {leds[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[0]}]

 

23.4.5 Analyse temporelle

Indicateur

Condition

WNSDoit être positif ou nul pour le setup
TNSDoit être nul en absence de violation
HoldAucune violation de maintien
Unconstrained pathsAucun chemin important non contraint
FmaxCompatible avec la fréquence réelle

 

23.4.6 Signaux optimisés

Un bloc ou un signal qui n’influence aucune sortie peut disparaître. Vérifier les warnings et le schéma RTL.

23.4.7 Génération du bitstream

1. Synthèse complète.

2. Placement et routage.

3. Analyse des rapports.

4. Correction des violations.

5. Génération du fichier de programmation.

6. Archivage du bitstream avec la version du code.

23.5 Validation matérielle et documentation

23.5.1 Plan de validation

Test

Action

Résultat attendu

Mise sous tensionProgrammer puis relâcher resetÉtat initial
EntréesActiver chaque bouton/interrupteurUne seule action
SortiesParcourir les modesAffichage cohérent
LimitesAtteindre les valeurs maximalesTransition correcte
ErreurProvoquer un cas invalideAlarme ou état sûr
EnduranceRépéter le scénarioAucune dérive

 

23.5.2 Instrumentation

  • LED de vie ;
  • LED ou code d’état ;
  • compteur d’erreurs ;
  • UART de diagnostic ;
  • analyseur logique embarqué ;
  • analyseur logique externe ou oscilloscope.

23.5.3 Comparaison simulation / carte

Simulation

Carte

Entrées idéalesRebond, bruit et asynchronisme
Horloge exacteFréquence physique et jitter
Tous signaux visiblesInstrumentation nécessaire
Pas de brochageBroches, tension et polarité
Délais RTL idéauxRoutage et timing réel

 

23.5.4 Rapport final

1. Introduction et objectifs.

2. Cahier des charges.

3. Architecture hiérarchique.

4. Description des blocs.

5. Plan de vérification et résultats.

6. Synthèse, ressources et timing.

7. Contraintes et implantation.

8. Validation matérielle.

9. Difficultés, corrections et limites.

10. Conclusion et perspectives.

23.5.5 Démonstration

  • préparer une procédure courte et reproductible ;
  • montrer le reset et le scénario nominal ;
  • montrer un cas limite ou une erreur ;
  • expliquer un chronogramme et un rapport ;
  • prévoir une solution de secours : vidéo ou captures.

Projet 1 — Chronomètre numérique

1. Objectif

Réaliser un chronomètre minutes-secondes commandé par boutons et affiché sur quatre afficheurs sept segments.

2. Cahier des charges minimal

  • affichage MM:SS de 00:00 à 59:59 ;
  • boutons démarrage, arrêt et remise à zéro ;
  • une seule action par appui ;
  • mise à jour toutes les secondes ;
  • multiplexage de quatre afficheurs sept segments ;
  • reset prioritaire et état sûr.

3. Architecture

Décomposition  |   Architecture
boutons
  -> synchronisation / anti-rebond / fronts
  -> FSM MARCHE-ARRET
  -> base de temps 1 ms et 1 s
  -> compteurs secondes / minutes
  -> conversion BCD
  -> multiplexeur d'afficheurs
  -> décodeur sept segments

 

4. Blocs

Bloc

Fonction

gestion_boutonsProduire start_pulse, stop_pulse et reset_pulse
base_tempsProduire tick_1ms et tick_1s
controle_chronoMémoriser MARCHE ou ARRET
compteurs_tempsCompter secondes et minutes
affichage_4digitsMultiplexer et décoder les chiffres

 

5. FSM de contrôle

États  |   VHDL
type etat_t is (ARRET, MARCHE);
signal etat : etat_t := ARRET;

process(clk)
begin
    if rising_edge(clk) then
        if reset = '1' then
            etat <= ARRET;
        else
            case etat is
                when ARRET =>
                    if start_pulse = '1' then
                        etat <= MARCHE;
                    end if;
                when MARCHE =>
                    if stop_pulse = '1' then
                        etat <= ARRET;
                    end if;
            end case;
        end if;
    end if;
end process;

 

6. Compteurs minutes-secondes

Comptage BCD  |   VHDL
if rising_edge(clk) then
    if reset_chrono = '1' then
        sec_unites <= 0;
        sec_dizaines <= 0;
        min_unites <= 0;
        min_dizaines <= 0;
    elsif etat = MARCHE and tick_1s = '1' then
        if sec_unites < 9 then
            sec_unites <= sec_unites + 1;
        else
            sec_unites <= 0;
            if sec_dizaines < 5 then
                sec_dizaines <= sec_dizaines + 1;
            else
                sec_dizaines <= 0;
                -- Propagation vers les minutes.
            end if;
        end if;
    end if;
end if;

 

7. Décodeur sept segments

Extrait  |   VHDL
with chiffre select
    segments <=
        "1000000" when "0000", -- 0
        "1111001" when "0001", -- 1
        "0100100" when "0010", -- 2
        "0110000" when "0011", -- 3
        "0011001" when "0100", -- 4
        "0010010" when "0101", -- 5
        "0000010" when "0110", -- 6
        "1111000" when "0111", -- 7
        "0000000" when "1000", -- 8
        "0010000" when "1001", -- 9
        "1111111" when others;

 

8. Multiplexage

Sélection des quatre chiffres  |  VHDL
if rising_edge(clk) then
    if tick_1ms = '1' then
        index_afficheur <= index_afficheur + 1;
    end if;
end if;

case index_afficheur is
    when "00" => chiffre <= sec_unites_bcd;
    when "01" => chiffre <= sec_dizaines_bcd;
    when "10" => chiffre <= min_unites_bcd;
    when others => chiffre <= min_dizaines_bcd;
end case;

 

9. Plan de test

Scénario

Résultat

Reset00:00 et état ARRET
StartLe temps avance
StopLe temps reste stable
RepriseLe comptage reprend
59 sPassage à 01:00
59:59Retour à 00:00 ou saturation selon spécification
Rebond simuléUne seule transition de mode

 

10. Testbench accéléré

Scénario de référence  |  VHDL
-- En simulation, tick_1s est remplacé par un tick rapide.
reset <= '1';
wait for 3 * PERIODE;
reset <= '0';

start_pulse <= '1';
wait until rising_edge(clk);
start_pulse <= '0';

for i in 1 to 60 loop
    tick_1s <= '1';
    wait until rising_edge(clk);
    tick_1s <= '0';
    wait until rising_edge(clk);
end loop;

assert min_unites = 1 and sec_unites = 0
    report "Transition 00:59 vers 01:00 incorrecte"
    severity error;

 

11. Extensions

  • centièmes de seconde ;
  • fonction tour/lap ;
  • compte à rebours ;
  • buzzer de fin ;
  • transmission UART du temps.

Projet 2 — Feu de circulation intelligent

1. Objectif

Contrôler deux voies et un passage piéton avec temporisation, priorité contrôlée et mode clignotant.

2. Cahier des charges minimal

  • une seule voie au vert ;
  • phase orange avant le rouge ;
  • temps de sécurité avec toutes les voies au rouge ;
  • demande piéton mémorisée ;
  • mode nocturne clignotant ;
  • état visible sur LED.

3. États proposés

État

Voie A

Voie B

Piéton

A_VERTVertRougeRouge
A_ORANGEOrangeRougeRouge
TOUT_ROUGE_1RougeRougeRouge
B_VERTRougeVertRouge
B_ORANGERougeOrangeRouge
PIETON_VERTRougeRougeVert
CLIGNOTANTOrange clignotantOrange clignotantRouge

 

4. Type d’état

FSM  |   VHDL
type etat_t is (
    A_VERT,
    A_ORANGE,
    TOUT_ROUGE_1,
    B_VERT,
    B_ORANGE,
    TOUT_ROUGE_2,
    PIETON_VERT,
    CLIGNOTANT
);

 

5. Temporisation

Compteur de durée  |  VHDL
if rising_edge(clk) then
    if reset_temps = '1' then
        compteur_ms <= 0;
    elsif tick_1ms = '1' then
        if compteur_ms < duree_etat_ms then
            compteur_ms <= compteur_ms + 1;
        end if;
    end if;
end if;

fin_temps <= '1' when compteur_ms = duree_etat_ms else '0';

 

6. Transition principale

Extrait de logique suivante  |  VHDL
case etat is
    when A_VERT =>
        if mode_clignotant = '1' then
            etat_suivant <= CLIGNOTANT;
        elsif fin_temps = '1' then
            etat_suivant <= A_ORANGE;
        end if;

    when A_ORANGE =>
        if fin_temps = '1' then
            etat_suivant <= TOUT_ROUGE_1;
        end if;

    when TOUT_ROUGE_1 =>
        if fin_temps = '1' then
            if demande_pieton = '1' then
                etat_suivant <= PIETON_VERT;
            else
                etat_suivant <= B_VERT;
            end if;
        end if;
    when others =>
        -- Transitions complémentaires.
        null;
end case;

 

7. Mémorisation de la demande piéton

Drapeau de demande  |  VHDL
if rising_edge(clk) then
    if reset = '1' then
        demande_pieton <= '0';
    elsif impulsion_pieton = '1' then
        demande_pieton <= '1';
    elsif etat = PIETON_VERT then
        demande_pieton <= '0';
    end if;
end if;

 

8. Invariants de sécurité

Assertions  |   VHDL
assert not (a_vert = '1' and b_vert = '1')
    report "Deux voies vertes simultanément"
    severity failure;

assert not (pieton_vert = '1' and (a_vert = '1' or b_vert = '1'))
    report "Conflit véhicule-piéton"
    severity failure;

 

9. Tests

  • cycle normal complet ;
  • demande piéton dans chaque état ;
  • maintien de la demande jusqu’au traitement ;
  • entrée et sortie du mode clignotant ;
  • reset dans chaque état ;
  • assertions de sécurité sur plusieurs cycles.

10. Extensions

  • capteurs de présence et durée adaptative ;
  • compte à rebours piéton ;
  • priorité véhicule d’urgence ;
  • journal d’événements ;
  • configuration UART.

Projet 3 — Serrure électronique

1. Objectif

Réaliser une serrure contrôlée par clavier, avec vérification d’un code, limitation des tentatives et alarme.

2. Fonctions

  • saisie de chiffres ;
  • enregistrement du code saisi ;
  • validation et comparaison ;
  • ouverture temporaire en cas de succès ;
  • incrémentation des échecs ;
  • alarme après le nombre maximal de tentatives ;
  • effacement et reconfiguration optionnelle.

3. Architecture

Blocs  |   Architecture
clavier_matriciel
  -> scanner_lignes_colonnes
  -> anti_rebond / impulsion_touche
  -> encodeur_touche
  -> registre_code_saisi
  -> comparateur_code
  -> FSM_serrure
  -> temporisation_ouverture / alarme
  -> LED, afficheur ou buzzer

 

4. États proposés

Type d’état  |   VHDL
type etat_t is (
    ATTENTE,
    SAISIE,
    VERIFICATION,
    OUVERT,
    REFUSE,
    BLOQUE,
    ALARME
);

 

5. Registre de code

Décalage des chiffres  |  VHDL
if rising_edge(clk) then
    if effacer_code = '1' then
        code_saisi <= (others => '0');
        nb_chiffres <= 0;
    elsif chiffre_valide = '1' and nb_chiffres < 4 then
        code_saisi <= code_saisi(11 downto 0) & chiffre;
        nb_chiffres <= nb_chiffres + 1;
    end if;
end if;

 

6. Comparaison

Code mémorisé  |   VHDL
constant CODE_SECRET : std_logic_vector(15 downto 0)
    := x"1234";

code_correct <= '1'
    when code_saisi = CODE_SECRET
    else '0';

 

7. Tentatives

Limitation  |   VHDL
if rising_edge(clk) then
    if reset = '1' or code_correct = '1' then
        tentatives <= 0;
    elsif verification_fausse = '1' then
        if tentatives < MAX_TENTATIVES then
            tentatives <= tentatives + 1;
        end if;
    end if;
end if;

alarme <= '1' when tentatives >= MAX_TENTATIVES else '0';

 

8. Sécurité fonctionnelle

  • ne pas afficher le code secret ;
  • effacer le registre après validation ;
  • bloquer temporairement après plusieurs erreurs ;
  • définir l’état après coupure de courant ;
  • réserver une procédure de maintenance.

9. Plan de test

Scénario

Résultat

Code correctOuverture puis retour ATTENTE
Code fauxRefus et compteur +1
Trois codes fauxBLOQUE ou ALARME
EffacementRegistre de saisie remis à zéro
Touche maintenueUn seul chiffre
Reset pendant ouvertureRetour à l’état sûr

 

10. Extensions

  • code programmable stocké en mémoire ;
  • temporisation croissante après erreur ;
  • journal UART des tentatives ;
  • double authentification ;
  • affichage masqué par tirets.

Projet 4 — Mini-calculatrice numérique

1. Objectif

Saisir deux opérandes, sélectionner une opération, utiliser une UAL et afficher le résultat avec gestion des erreurs.

2. Fonctions minimales

  • saisie ou sélection de deux valeurs 8 bits ;
  • addition et soustraction ;
  • validation par bouton ;
  • affichage du résultat ;
  • indicateurs zéro, signe, retenue et overflow ;
  • message ou LED d’erreur.

3. Architecture

Décomposition  |   Architecture
entrées / clavier / interrupteurs
  -> registre A
  -> registre B
  -> sélection opération
  -> UAL 8 bits
  -> registre résultat
  -> conversion affichage
  -> flags et gestion erreur

 

4. FSM de saisie

États  |   VHDL
type etat_t is (
    SAISIE_A,
    SAISIE_OP,
    SAISIE_B,
    CALCUL,
    AFFICHAGE,
    ERREUR
);

 

5. Registres des opérandes

Chargement  |   VHDL
if rising_edge(clk) then
    if reset = '1' then
        operande_a <= (others => '0');
        operande_b <= (others => '0');
    else
        if load_a = '1' then
            operande_a <= unsigned(entree_valeur);
        end if;
        if load_b = '1' then
            operande_b <= unsigned(entree_valeur);
        end if;
    end if;
end if;

 

6. UAL simplifiée

Addition / soustraction  |  VHDL
process(all)
    variable ext : unsigned(8 downto 0);
begin
    resultat_comb <= (others => '0');
    carry_comb <= '0';

    case operation is
        when '0' =>
            ext := ('0' & operande_a) + ('0' & operande_b);
            resultat_comb <= ext(7 downto 0);
            carry_comb <= ext(8);
        when others =>
            resultat_comb <= operande_a - operande_b;
            if operande_a < operande_b then
                carry_comb <= '1'; -- convention emprunt
            end if;
    end case;
end process;

 

7. Overflow signé

Indicateur V  |   VHDL
overflow_add <=
    (not (a(7) xor b(7)))
    and (resultat(7) xor a(7));

overflow_sub <=
    (a(7) xor b(7))
    and (resultat(7) xor a(7));

 

8. Affichage

Le résultat peut être affiché en hexadécimal ou converti en décimal par double dabble ou division séquentielle.

Affichage hexadécimal  |  VHDL
digit_haut <= std_logic_vector(resultat(7 downto 4));
digit_bas  <= std_logic_vector(resultat(3 downto 0));

 

9. Tests

Opération

A

B

Attendu

ADD102030, flags nuls
ADD25510, C=1, Z=1
ADD signé1271-128, V=1
SUB1037
SUB01255, emprunt=1
SUB signé-1281127, V=1

 

10. Extensions

  • multiplication ;
  • division séquentielle ;
  • virgule fixe ;
  • mémoire des résultats ;
  • interface UART de calcul.

Projet 5 — Générateur de signal PWM

1. Objectif

Créer une PWM dont la fréquence et le rapport cyclique sont réglables par boutons, avec affichage et sortie vers LED ou étage de puissance.

2. Spécification minimale

  • résolution de rapport cyclique définie ;
  • fréquence choisie parmi plusieurs valeurs ;
  • boutons + et - pour la consigne ;
  • mise à jour sans glitch ;
  • affichage de la valeur ;
  • état sûr au reset.

3. Architecture

Décomposition  |   Architecture
boutons
  -> anti-rebond / fronts
  -> registre duty demandé
  -> sélection fréquence
  -> prescaler
  -> compteur de phase
  -> registre duty actif
  -> comparateur PWM
  -> LED / driver de puissance

 

4. Réglage du duty

Incrément / décrément saturant  |  VHDL
if rising_edge(clk) then
    if reset = '1' then
        duty_demande <= to_unsigned(128, 8);
    elsif plus_pulse = '1' then
        if duty_demande < 255 then
            duty_demande <= duty_demande + 1;
        end if;
    elsif moins_pulse = '1' then
        if duty_demande > 0 then
            duty_demande <= duty_demande - 1;
        end if;
    end if;
end if;

 

5. Choix de fréquence

Prescaler sélectionné  |  VHDL
case select_freq is
    when "00" => diviseur <= DIV_1KHZ;
    when "01" => diviseur <= DIV_5KHZ;
    when "10" => diviseur <= DIV_10KHZ;
    when others => diviseur <= DIV_20KHZ;
end case;

 

6. Mise à jour au début de période

Duty sans glitch  |  VHDL
if rising_edge(clk) then
    if tick_phase = '1' then
        phase <= phase + 1;
        if phase = 0 then
            duty_actif <= duty_demande;
        end if;
    end if;
end if;

pwm_o <= '1' when phase < duty_actif else '0';

 

7. Fréquence et résolution

Relations  |   Calcul
F_PWM = F_CLK / (DIVISEUR * 2^N)

Résolution duty = 1 / 2^N

Exemple N=8 : 256 niveaux.

 

8. Validation

  • mesurer la période à l’oscilloscope ;
  • compter les cycles hauts dans le testbench ;
  • tester duty 0, 1, 50 %, 254 et 255 ;
  • changer la consigne au milieu d’une période ;
  • vérifier la polarité de la LED ;
  • retester le timing à la fréquence la plus élevée.

9. Sécurité moteur

Sécurité matérielle — Étage de puissance obligatoire

La sortie FPGA commande un driver, un MOSFET ou un pont en H. Le moteur ne doit jamais être alimenté directement par une broche du FPGA.

 

10. Extensions

  • rampe progressive ;
  • PWM centrée ;
  • commande de servomoteur ;
  • plusieurs canaux ;
  • configuration UART.

Projet 6 — Communication UART

1. Objectif

Concevoir un émetteur, un récepteur, un générateur de baud et une boucle de retour entre la carte et un ordinateur.

2. Paramètres

Paramètre

Valeur de référence

Format8N1
Baud115 200 bit/s
OrdreLSB en premier
Repos TX/RX1
RécepteurSuréchantillonnage ×8 ou ×16

 

3. Architecture

Chaîne  |   Architecture
clk
  -> générateur baud TX
  -> UART TX

rx_async
  -> synchroniseur
  -> générateur tick x16
  -> UART RX
  -> FIFO / registre
  -> boucle de retour vers UART TX

 

4. Émetteur

Trame 8N1 dans un registre  |  VHDL
-- Bit 0 : START, bits 1..8 : data, bit 9 : STOP.
trame <= '1' & data_in & '0';

-- Envoi LSB en premier : tx <= trame(index_bit).

 

5. Récepteur : validation du START

Échantillonnage au centre  |  VHDL
if etat = IDLE and rx_sync = '0' then
    compteur_os <= 0;
    etat <= START;
elsif etat = START and tick_x16 = '1' then
    if compteur_os = 7 then
        if rx_sync = '0' then
            index_bit <= 0;
            etat <= DATA;
        else
            etat <= IDLE; -- faux START
        end if;
    else
        compteur_os <= compteur_os + 1;
    end if;
end if;

 

6. Capture des données

Octet reçu  |   VHDL
if tick_x16 = '1' then
    if compteur_os = 15 then
        compteur_os <= 0;
        registre_rx(index_bit) <= rx_sync;
        if index_bit = 7 then
            etat <= STOP;
        else
            index_bit <= index_bit + 1;
        end if;
    else
        compteur_os <= compteur_os + 1;
    end if;
end if;

 

7. Boucle de retour

Echo UART  |   VHDL
if rising_edge(clk) then
    tx_start <= '0';

    if rx_valid = '1' then
        octet_attente <= rx_data;
        octet_present <= '1';
    end if;

    if octet_present = '1' and tx_busy = '0' then
        tx_data <= octet_attente;
        tx_start <= '1';
        octet_present <= '0';
    end if;
end if;

 

8. Erreurs

Erreur

Détection

FramingSTOP reçu à 0
OverflowOctet reçu avant consommation
Faux STARTRX remonte avant le centre du START
Mauvais baudAccumulation de décalage

 

9. Testbench

Procédure d’envoi UART  |   VHDL
procedure envoyer_octet(
    signal rx : out std_logic;
    constant data : std_logic_vector(7 downto 0);
    constant temps_bit : time
) is
begin
    rx <= '0';
    wait for temps_bit;
    for i in 0 to 7 loop
        rx <= data(i);
        wait for temps_bit;
    end loop;
    rx <= '1';
    wait for temps_bit;
end procedure;

 

10. Validation PC

1. Utiliser un pont USB-UART compatible avec la tension logique.

2. Relier les masses.

3. Configurer le terminal en 8N1 au bon débit.

4. Envoyer des caractères.

5. Vérifier leur retour.

6. Tester des séquences longues et rapides.

11. Extensions

  • parité ;
  • FIFO RX/TX ;
  • commandes ASCII ;
  • protocole avec checksum ;
  • transmission de mesures périodiques.

Projet 7 — Jeu numérique sur FPGA

1. Objectif

Réaliser un jeu de réflexe ou de séquence avec génération pseudo-aléatoire, score, temporisation et sorties lumineuses ou sonores.

2. Exemple de jeu

Après un délai pseudo-aléatoire, une LED s’allume. Le joueur doit appuyer sur le bouton correspondant avant le timeout.

3. Architecture

Décomposition  |   Architecture
base_de_temps
  -> LFSR pseudo-aléatoire
  -> FSM du jeu
  -> sélection LED cible
  -> gestion boutons
  -> mesure temps de réaction
  -> score
  -> affichage
  -> buzzer / effets lumineux

 

4. États

FSM du jeu  |   VHDL
type etat_t is (
    ATTENTE_DEMARRAGE,
    DELAI_ALEATOIRE,
    SIGNAL_ACTIF,
    ATTENTE_REPONSE,
    SUCCES,
    ECHEC,
    FIN_PARTIE
);

 

5. Générateur pseudo-aléatoire LFSR

LFSR 8 bits  |   VHDL
process(clk)
begin
    if rising_edge(clk) then
        if reset = '1' then
            lfsr <= x"A5"; -- graine non nulle
        elsif avance_lfsr = '1' then
            lfsr <= lfsr(6 downto 0)
                    & (lfsr(7) xor lfsr(5)
                       xor lfsr(4) xor lfsr(3));
        end if;
    end if;
end process;

 

6. Sélection d’une cible

Index LED  |   VHDL
index_cible <= to_integer(unsigned(lfsr(1 downto 0)));

leds_cible <= std_logic_vector(
    shift_left(to_unsigned(1, 4), index_cible)
);

 

7. Délai pseudo-aléatoire

Durée bornée  |   VHDL
duree_attente_ms <= 500
    + to_integer(unsigned(lfsr)) * 10;

-- Délai entre 500 ms et 3050 ms.

 

8. Mesure de réaction

Compteur  |   VHDL
if rising_edge(clk) then
    if reset_reaction = '1' then
        reaction_ms <= 0;
    elsif etat = ATTENTE_REPONSE and tick_1ms = '1' then
        reaction_ms <= reaction_ms + 1;
    end if;
end if;

 

9. Score

Mise à jour  |   VHDL
if rising_edge(clk) then
    if reset_score = '1' then
        score <= 0;
    elsif succes = '1' then
        if reaction_ms < SEUIL_RAPIDE then
            score <= score + 3;
        else
            score <= score + 1;
        end if;
    elsif erreur = '1' and score > 0 then
        score <= score - 1;
    end if;
end if;

 

10. Anti-triche et erreurs

  • appui avant le signal : pénalité ;
  • mauvais bouton : échec ;
  • absence de réponse : timeout ;
  • boutons synchronisés et filtrés ;
  • graine LFSR non nulle.

11. Plan de test

Scénario

Résultat

StartPassage en délai aléatoire
Appui anticipéÉchec ou pénalité
Bonne réponseScore augmenté
Mauvaise réponseScore réduit
TimeoutÉchec
Fin du nombre de manchesFIN_PARTIE
ResetScore et état initial

 

12. Effets sonores

Buzzer carré  |   VHDL
buzzer <= phase_audio
    when son_actif = '1'
    else '0';

-- phase_audio est basculée par un tick correspondant
-- à la fréquence sonore souhaitée.

 

13. Extensions

  • jeu Simon avec séquence mémorisée ;
  • niveau de difficulté progressif ;
  • meilleur score en RAM ;
  • affichage du temps de réaction ;
  • mode deux joueurs ;
  • transmission UART des résultats.

Comparaison des sujets proposés

Projet

Difficulté

Blocs dominants

Extension naturelle

ChronomètreIntermédiaireCompteurs, affichage, boutonsCompte à rebours
Feu intelligentIntermédiaireFSM, temporisationCapteurs adaptatifs
SerrureIntermédiaire+Clavier, FSM, registresCode programmable
CalculatriceIntermédiaire+UAL, saisie, affichageVirgule fixe
PWMIntermédiaireCompteurs, comparateurMulti-canaux
UARTAvancéFSM, suréchantillonnageProtocole de commandes
JeuAvancéFSM, LFSR, scoreDeux joueurs

 

Choisir le projet

Profil ou objectif

Projet conseillé

Débuter l’intégrationChronomètre ou PWM
Approfondir les FSMFeu ou serrure
Approfondir l’arithmétiqueCalculatrice
Approfondir les communicationsUART
Projet démonstratif et créatifJeu
Approfondir l’affichageChronomètre ou calculatrice

 

Livrables obligatoires

1. Cahier des charges et matrice des exigences.

2. Diagramme d’architecture hiérarchique.

3. Sources VHDL commentées.

4. Paquetages et composants réutilisables.

5. Bancs de test unitaires et d’intégration.

6. Fichier de contraintes.

7. Rapports de synthèse et de timing.

8. Tableau de validation matérielle.

9. Rapport final.

10. Démonstration ou vidéo de secours.

Barème proposé sur 100 points

Critère

Points

Cahier des charges et exigences8
Architecture hiérarchique12
Qualité du VHDL et bonnes pratiques12
Fonctionnement des blocs12
Testbenches et assertions15
Synthèse et analyse des ressources8
Contraintes et timing8
Validation matérielle12
Rapport et traçabilité7
Démonstration et soutenance6
Total100

 

Niveaux d’évaluation

Niveau

Description

InsuffisantFonction non démontrée, tests absents ou architecture monolithique
AcceptableFonction principale opérationnelle et validation minimale
BonArchitecture claire, tests automatiques et timing respecté
Très bonCas limites, diagnostic, réutilisation et documentation complète
ExcellentExtensions maîtrisées, preuves quantitatives et démonstration robuste

 

Checklist de livraison

  • Le dépôt se reconstruit à partir d’une copie propre.
  • Le top-level correspond à la carte utilisée.
  • Les contraintes ne contiennent aucun placeholder.
  • Le testbench se termine automatiquement.
  • Les assertions ne signalent aucune erreur.
  • Le rapport ne contient aucun latch involontaire.
  • Le timing est respecté.
  • Le bon bitstream est archivé.
  • La procédure de démonstration est documentée.
  • Les limites et améliorations sont honnêtement décrites.

Synthèse du chapitre

Étape

Résultat attendu

SpécificationExigences mesurables
ArchitectureBlocs et interfaces définis
CodageComposants lisibles et synthétisables
VérificationTests unitaires et système réussis
SynthèseRessources conformes à l’intention
ContraintesBroches et horloges correctement décrites
ImplantationTiming respecté et bitstream généré
ValidationScénarios matériels réussis
DocumentationPreuves, limites et perspectives

 

Autoévaluation

1. Quel est le premier livrable ?

Réponse : Un cahier des charges vérifiable.

2. Pourquoi décomposer le système ?

Réponse : Pour tester, réutiliser et intégrer progressivement.

3. Que doit préciser une interface ?

Réponse : Types, largeur, polarité, timing et protocole.

4. Quand synthétiser ?

Réponse : Après réussite du testbench d’intégration.

5. Que vérifier dans le rapport ?

Réponse : Ressources, latches, warnings et timing.

6. Pourquoi accélérer la simulation ?

Réponse : Réduire les durées sans changer la logique.

7. Que prouve le bitstream ?

Réponse : Seulement que l’implémentation a été générée.

8. Pourquoi valider sur carte ?

Réponse : Les entrées, broches et délais physiques diffèrent.

9. Que devient un bug corrigé ?

Réponse : Un test de régression.

10. Quand le projet est-il terminé ?

Réponse : Quand fonction, timing, validation et documentation sont démontrés.

Modèle de fiche de projet

Rubrique

Contenu à renseigner

TitreNom clair du système
ObjectifFonction principale et utilisateur
EntréesBroches, protocoles, polarités
SortiesAfficheurs, LED, communication, actionneur
Horloge/resetFréquence et stratégie
ArchitectureBlocs, interfaces et hiérarchie
ExigencesListe numérotée et mesurable
TestsScénarios nominaux, limites et erreurs
ContraintesBroches, I/O et timing
ValidationProcédure sur carte
ExtensionsFonctions supplémentaires

 

Conclusion — Aboutissement du cours

Le projet final doit démontrer une démarche d’ingénierie complète : comprendre le besoin, concevoir une architecture, vérifier le comportement, maîtriser l’implantation et apporter des preuves de fonctionnement.