# VHDL Avancé 1 : Machines à états en VHDL

Clément Foucher

► To cite this version:

Clément Foucher. VHDL Avancé 1 : Machines à états en VHDL. Licence. VHDL Avancé, IUT Paul Sabatier, Toulouse, France. 2025. hal-04399300v2

HAL Id: hal-04399300

https://hal.science/hal-04399300v2

Submitted on 18 Feb 2025

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons Attribution - ShareAlike 4.0 International License
VHDL avancé

MACHINES À ÉTATS EN VHDL

© 2024-2025 Clément Foucher

Cours distribué sous licence libre

<figure><img src="image_2.png" /></figure>

BUT GEII Toulouse S6 ESE
# Rappels : Machines à états

UNE MACHINE À ÉTATS EN ÉLECTRONIQUE NUMÉRIQUE ?

REPRÉSENTATION D'UNE MAE EN VHDL

BLOC D'ÉVOLUTION DE L'ÉTAT

CALCUL DES ACTIONS

EXERCICE

ENCODAGE DE L'ÉTAT
# Principe de base d'une machine à états

* Problématique : comment représenter un système de manière simple ?

* Solution : représenter le système sur la base de ses états possibles

* Exemple : système d'ouverture d'une porte coulissante

* La porte peut être ouverte ou fermée (état)

* La porte peut changer d'état (transition)

<figure><img src="image_3.png" /></figure>
# Principe de base d'une machine à états

* **Problématique : comment représenter un système de manière simple ?**

* **Solution : représenter le système sur la base de ses états possibles**

* **Exemple : système d'ouverture d'une porte coulissante**

* La porte peut être ouverte ou fermée (état)

* La porte peut changer d'état (transition)

* **Un état n'est pas forcément « statique » :**

* La porte en train de s'ouvrir ou de se fermer peut être représentée par un état

<figure><img src="image_4.png" /></figure>
# Principe de base d'une machine à états

* Les changements d'état se font lorsqu'une **condition** est réalisée

* Il est possible de réaliser des **actions** tant qu'un état est actif, ou au moment du changement d'état

* Le principe des machines a états est particulièrement adapté aux systèmes de commande, pour lesquels des capteurs peuvent être utilisés pour les conditions, et des actionneurs pour les actions

<figure><img src="image_5.png" /></figure>
# Variables

Note :
Selon ces définitions, l'état courant de la MAE est une variable interne mémorisée

* Dans une MAE, un variable a une direction (3 possibles)

* Variable d'entrée

* Peut être lue, ne peut pas être modifiée

* Utilisable uniquement dans les conditions

* Variable interne

* Peut être lue et modifiée

* Peut-être utilisée dans les conditions et dans les actions

* Variable de sortie

* Peut être modifiée, ne peut pas être lue

* Peut uniquement être utilisée dans les actions

* Dans une MAE, une variable peut être mémorisée ou non mémorisée

* Ne s'applique qu'aux variables modifiables (interne ou de sortie)

* Une variable **mémorisée** conserve la valeur qui lui est affectée dans une action

* Il est nécessaire de lui donner une **valeur initiale**, qui sera utilisée tant que la valeur n'a pas encore été affectée.

* Une variable **non mémorisée** « perd » sa valeur lorsqu'aucune action ne s'applique à elle

* Ce type de variable a une **valeur par défaut**, qui est utilisée lorsqu'aucune action ne s'applique à elle

En théorie, mais dans les faits, on accepte la lecture de certaines variables de sorties pour simplifier.

Mais le VHDL ne le permet pas forcément...
# Représentation d'une machine à états

* Règles de construction d'une MAE :

* Un **état** est représenté par un cercle

* L'état initial par un double cercle

* Une **transition** est représentée par une flèche

* Une **condition** est représentée par du texte placé sur une barre placée sur une transition

* Une **action** est représentée par du texte placé dans un rectangle placé sur une transition ou un état

* Si l'action s'applique à une variable mémorisée, on l'indique avec un « M »

<figure><img src="image_6.png" /></figure>
# Règles d'une machine à états

## États

* À tout instant, un état et un seul est actif, tous les autres étant inactifs

* On peut donc dire par abus de langage qu'a tout moment, la MAE « est » dans un état (celui qui est actif)

* L'un des états doit être défini comme « initial », c'est-à dire que c'est lui qui sera activé au démarrage ou en cas de réinitialisation du système

## Transitions

* Une transition doit être dessinée entre 2 états : un état « source » et un état « cible »

* Il est possible d'avoir une transition dont l'état source et l'état cible sont confondus

* Toute transition doit être associée à une et une seule condition

## Conditions

* Une condition s'exprime sous la forme d'une opération booléenne dont le résultat est soit « vrai » soit « faux »

* Les conditions associées à plusieurs transitions ayant le même état source doivent être mutuellement exclusives

## Actions

* Une action se présente sous la forme d'une affectation de variable : « X ← Y »

* Une action peut être placée sur une transition : elle est alors ponctuelle (active brièvement, au moment du changement d'état)

* Une action peut être placée sur un état : elle est alors maintenue (active tant que l'état est actif, se désactive lorsque l'on sort de l'état)
RAPPELS : MACHINES À ÉTATS

# Une machine à états en électronique numérique ?

- REPRÉSENTATION D'UNE MAE EN VHDL

- BLOC D'ÉVOLUTION DE L'ÉTAT

- CALCUL DES ACTIONS

- EXERCICE

- ENCODAGE DE L'ÉTAT
# Comment réaliser une MAE avec des concepts numériques ?

* En électronique numérique, il faut réfléchir en termes de cycles d'horloges

* Une variable mémorisée se traduit par une valeur stockée dans un registre

* Sa valeur peut changer au front montant de l'horloge

* Il faut donc « préparer » en entrée du registre la valeur à stocker au prochain front

* Une variable non mémorisée est combinatoire

* Sa valeur peut changer de manière asynchrone (par exemple si elle dépend de la valeur d'une entrée, et que cette entrée change)

Combinatoire

Séquentiel

<figure><img src="image_7.png" /></figure>

<figure><img src="image_8.png" /></figure>
# Comment réaliser une MAE avec des concepts numériques ?

* Avec ces définitions, on sait donc réaliser des changement de valeurs pour les variables

* Toutes les variables disposent d'un circuit logique qui calcule la valeur de manière combinatoire

* Pour les variables mémorisées, on utilise un registre qui mémorise le résultat du calcul au front d'horloge

* Rappel : l'état d'une MAE est une variable interne mémorisée
# Changement d'état

* L'état est une variable interne mémorisée

* Si à un instant $t$ la condition requise pour un changement d'état est vraie, alors la valeur de l'état sera mise à jour au prochain front d'horloge

* Il faut donc « préparer » le prochain état pour qu'il soit prêt à être modifié au prochain front d'horloge

* Il est donc nécessaire que le calcul du prochain état puisse être fait en dehors des fronts, pour être prêt au prochain front

* Le calcul doit donc être fait de manière combinatoire, et mémorisé dans un registre au front d'horloge
# Synthèse : schéma-bloc

<figure><img src="image_9.png" /></figure>
# Actions non mémorisés

## Actions sur transition

* Les actions sur transition doivent être réalisées *au moment du changement d'état*

* Au front où a lieu le changement d'état, l'action sur transition associée doit donc *déjà* être active

* L'action doit donc avoir été préparée *avant* le front pour pouvoir être active au moment du front

## Actions sur état

* Les actions sur état doivent s'activer dès que l'on est dans l'état

* Or, le changement d'état se fait sur front d'horloge

* Les actions sur état doivent donc s'activer juste après la mémorisation de l'état, qui a lieu au front d'horloge

* Les actions non mémorisées doivent donc être réalisées de manière combinatoire en fonction de la valeur de l'état actuel et des autres variables
# Synthèse : schéma-bloc

Note : Si il y a des actions conditionnelles, les blocs d'action sur état peuvent également être reliées aux entrées et variables internes

<figure><img src="image_10.png" /></figure>
# Actions mémorisées

* Une mémoire est forcément synchrone

* Sauf à utiliser des latches, concept à bannir

* Donc une action mémorisée est forcément synchrone, et changera donc toujours de valeur après un front d'horloge

* Sauf à utiliser des constructions complexes, une action mémorisée aura donc un cycle de retard sur une action non mémorisée

* Une action sur transition mémorisée se produira après le front d'horloge, contrairement aux autres actions sur transition

* Une action sur état mémorisée ne se déclenchera qu'un cycle après que l'on ait changé d'état
# Synthèse : schéma-bloc

Note : Si il y a des actions conditionnelles, les blocs d'action sur état peuvent également être reliées aux entrées et variables internes

<figure><img src="image_11.png" /></figure>
# Machines de Moore et de Mealy

L'icône d'information indique que le contenu de ce slide est à titre informatif, il ne vous est pas demandé de le retenir

* Historiquement, il existe deux grands types de machines à états

* Dans une machine de Moore, les sorties sont définies en fonction de l'état

* Uniquement des actions sur état, donc

* Dans une machine de Mealy, les sorties sont définies en fonction de l'état et des entrées

* Uniquement des actions sur transition, donc

* Notez que rester dans le même état peut être vu comme une transition dans laquelle l'état cible est identique à l'état source

* Dans les deux cas, les variables sont non mémorisées, et les actions réalisées de manière asynchrone

* La vision présentée précédemment combine donc les deux : machine de Mealy pour les actions sur transition, machine de Moore pour les actions sur état

* On y ajoute également la notion de variable mémorisée

* Mais attention ! Les actions sur transition pouvant évoluer de manière asynchrone, il faut s'assurer qu'à l'extérieur de la MAE, les sorties ne soient pas rebouclées sur les entrées de manière combinatoire, sinon attention aux dégâts...

* Ce cas reste rare, il est donc relativement sûr d'utiliser ce type de machine

Pour aller plus loin...

Moore machine

Mealy machine
RAPPELS : MACHINES À ÉTATS
UNE MACHINE À ÉTATS EN ÉLECTRONIQUE NUMÉRIQUE ?

# Représentation d'une MAE en VHDL

BLOC D'ÉVOLUTION DE L'ÉTAT

CALCUL DES ACTIONS

EXERCICE

ENCODAGE DE L'ÉTAT
# Représenter une MAE en VHDL

* Pour rappel, en VHDL :

* Un bloc séquentiel est obligatoirement représenté par un process synchrone

* Note : un bloc séquentiel implémenté simultanément la mémorisation et le calcul combinatoire en amont du registre

* Un bloc combinatoire peut être représenté par du code concurrent ou un process asynchrone

* Rappel liste de sensibilité

* Un process synchrone a dans sa liste de sensibilité uniquement l'horloge et le reset

* Un process asynchrone a dans sa liste de sensibilité tous les signaux dont la valeur est lue dans le process
<figure><img src="image_12.png" /><figcaption># Schéma-bloc pour le VHDL</figcaption></figure>
# Point de syntaxe VHDL : les types personnalisés

* Il est possible de définir des types avec la syntaxe suivante :

```vhdl
type monType is (valeur1, valeur2, valeur3);
```

* Équivalent du « typedef enum » en C/C++

* Une fois le type défini, il est possible de créer des signaux utilisant ce type

* Par exemple :

```vhdl
architecture ar of compo is
  type monType is (ouvert, ferme);
  signal monSignal : monType;
begin
    monSignal <= ouvert when condition else ferme;
end architecture;
```
# Équivalence des notions en VHDL

## État

* Un état sera défini par un signal de type personnalisé

## Variable

* Une variable sera définie par un signal

* Signal « in » défini dans l'entity pour une variable d'entrée

* Signal interne défini dans l'architecture pour une variable interne

* Signal « out » défini dans l'entity pour une variable de sortie
RAPPELS : MACHINES À ÉTATS

UNE MACHINE À ÉTATS EN ÉLECTRONIQUE NUMÉRIQUE ?

REPRÉSENTATION D'UNE MAE EN VHDL

BLOC DE CALCUL DE L'ÉTAT SUIVANT

# Bloc d'évolution de l'état

CALCUL DES ACTIONS

EXERCICE

ENCODAGE DE L'ÉTAT
# Bloc d'évolution de l'état

<figure><img src="image_13.png" /></figure>

* Le prochain état est défini par

* L'état actuel

* Les valeurs des conditions associées aux transitions sortant de l'état

* Si l'état 1 est actif, alors

* Si la `condition 1_2` est vraie, on passe à l'état 2

* Si la `condition 1_3` est vraie, on passe à l'état 3

* Sinon, on reste dans l'état 1

* Solution naïve de codage

Rappel : dans un process synchrone, si on ne modifie pas la valeur d'un signal, alors elle conserve sa valeur précédente (else implicite)

```pascal
if etat_courant = etat_1 then
  if condition_1_2 = '1' then
    etat_courant <= etat_2;
  elsif condition_1_3 = '1' then
    etat_courant <= etat_3;
end if;
end if;
```
# Bloc d'évolution de l'état :
## Exemple

<figure><img src="image_14.png" /></figure>

Exemple de codage complet
avec un if pour la MAE ci-dessous

<figure><img src="image_15.png" /></figure>

```pascal
if etat_courant = etat_1 then
  if C1_2 = '1' then
    etat_courant <= etat_2;
  elsif C1_3 = '1' then
    etat_courant <= etat_3;
end if;
```

```pascal
 elsif etat_courant = etat_2 then
  if C2_1 = '1' then
    etat_courant <= etat_1;
end if;
```

```pascal
 elsif etat_courant = etat_3 then
  if C3_1 = '1' then
    etat_courant <= etat_1;
end if;
end if;
```
# Bloc d'évolution de l'état :
Version améliorée

* Utiliser un case permet d'éviter de
répéter `etat_courant`

<figure><img src="image_16.png" /></figure>

```python
case etat_courant is
    when etat_1 =>
        if C1_2 = '1' then
            etat_courant <= etat_2;
        elsif C1_3 = '1' then
            etat_courant <= etat_3;
        end if;
    when etat_2 =>
        if C2_1 = '1' then
            etat_courant <= etat_1;
        end if;
    when etat_3 =>
        if C3_1 = '1' then
            etat_courant <= etat_1;
        end if;
end case;
```
# Bloc d'évolution de l'état :
Process complet

* On place l'ensemble dans un
process synchrone

* Rappels

* La liste de sensibilité d'un process
synchrone contient uniquement
l'horloge et le reset

* Le reset est prioritaire, et doit donc
être testé en premier dans le if

```pascal
process(clk, reset)
begin
  if reset = '1' then
    etat_courant <= etat_initial;
  elsif rising_edge(clk) then
    case etat_courant is
      when etat_1 =>
        if C1_2 = '1' then
          etat_courant <= etat_2;
        elsif C1_3 = '1' then
          etat_courant <= etat_3;
      end if;
      when etat_2 =>
        if C2_1 = '1' then
          etat_courant <= etat_1;
      end if;
      when etat_3 =>
        if C3_1 = '1' then
          etat_courant <= etat_1;
      end if;
    end case;
  end if;
end process;
```
# Comment coder les conditions ?

* Soit on crée un signal pour chaque condition

* Avantages

* Code mutualisé avec les actions sur transition (voir plus loin)

* Soit on exprime les conditions directement dans le process

* Avantages

* Moins de signaux à déclarer

* Si pas d'actions sur transition, plus compact

État 1

<figure><img src="image_17.png" /></figure>

A.B

État 2

```s
architecture ar of mon_compo is
    signal C1_2 : std_logic;
begin
    C1_2 <= A and not B;
    process( clk, reset )
    begin
        [...]
        case etat_courant is
            when etat_1 =>
                if C1_2 = '1' then
                    etat_suivant <= etat_2;
                end if;
            end case;
        [...]
        end process;
    end architecture;
```

```s
architecture ar of mon_compo is
begin
    process( clk, reset )
    begin
        [...]
        case etat_courant is
            when etat_1 =>
                if A = '1' and B = '0' then
                    etat_suivant <= etat_2;
                end if;
            end case;
        [...]
        end process;
    end architecture;
```
RAPPELS : MACHINES À ÉTATS

UNE MACHINE À ÉTATS EN ÉLECTRONIQUE NUMÉRIQUE ?

REPRÉSENTATION D'UNE MAE EN VHDL

BLOC D'ÉVOLUTION DE L'ÉTAT

# Calcul des actions

EXERCICE

ENCODAGE DE L'ÉTAT
Différentes méthodes pour le calcul
des actions

► Les actions mémorisées et non mémorisées sont forcément traitées séparément

► Actions mémorisées dans un process synchrone

► Actions non mémorisées dans un process asynchrone ou avec du code concurrent

► Les actions sur transition et sur état peuvent être traitées conjointement ou de manière séparée
# Actions non mémorisées sur état

<figure><img src="image_18.png" /></figure>

En utilisant un process asynchrone

```perl
process( etat_courant )
begin
    mon_action1 <= valeur_par_defaut1;
    mon_action2 <= valeur_par_defaut2;

    case etat_courant is
    when etat_1 =>
        mon_action1 <= valeur_1;
    when etat_2 =>
        mon_action1 <= valeur_2;
        mon_action2 <= valeur_3;
end case;
end process;
```

Les valeurs par défaut sont obligatoires dans un process asynchrone, sinon on crée une mémoire implicite

<figure><img src="image_19.png" /></figure>

En utilisant du code concurrent

```perl
with etat_courant select mon_action1 <=
    valeur_1              when etat_1
    valeur_2              when etat_2,
    valeur_par_defaut1    when others;

with etat_courant select mon_action2 <=
    valeur_3              when etat_2,
    valeur_par_defaut2    when others;
```

Attention, avec du code concurrent, on traite action par action, et non état par état (rappelez-vous : un seul driver pour un signal !)
# Comprendre les valeurs par défaut

```perl
process( etat_courant )
begin
    mon_action1 <= valeur_par_defaut1;
    mon_action2 <= valeur_par_defaut2;
```

```perl
case etat_courant is
    when etat_1 =>
        mon_action1 <= valeur_1;
    when etat_2 =>
        mon_action1 <= valeur_2;
        mon_action2 <= valeur_3;
end case;
end process;
```

* Si on suppose qu'il n'y a pas de valeur par défaut

* Quelle sera la valeur de `mon_action2` si `etat_courant` vaut `etat_1` ?

* Non précisée : on conserve donc la valeur précédente

* Mais on est dans un process asynchrone ! Il n'y a pas d'horloge pour synchroniser la mémoire

* Cela crée une latch (mémoire sans horloge) → PAS BIEN !

* On ajoute donc des valeurs par défaut qui s'appliqueront si aucune autre valeur n'est fournie au signal dans le process
# Actions non mémorisées sur transition

<figure><img src="image_20.png" /></figure>

En utilisant un process asynchrone

```python
process( etat_courant, C1_2, C2_1 )
begin
    mon_action1 <= valeur_par_defaut1;
    mon_action2 <= valeur_par_defaut2;

    case etat_courant is
        when etat_1 =>
            if C1_2 = '1' then
                mon_action1 <= valeur_1;
            end if;
        when etat_2 =>
            if C2_1 = '1' then
                mon_action2 <= valeur_2;
            end if;
    end case;
end process;
```

<figure><img src="image_21.png" /></figure>

En utilisant du code concurrent

```python
mon_action1 <=
    valeur_1 when etat_courant = etat_1 and C1_2 = '1' else
    valeur_par_defaut1;

mon_action2 <=
    valeur_2 when etat_courant = etat_2 and C2_1 = '1' else
    valeur_par_defaut2;
```

Cet exemple nécessite d'avoir défini des signaux intermédiaires pour les conditions, sinon il faut remettre la condition complète
# Actions non mémorisées en un seul bloc

* Il suffit de combiner les deux

* En utilisant un process

* Faire un seul process, qui contient un seul case

* Les actions sur état apparaissent directement après le *when*

* Les actions sur transition sont en plus protégées par un *if*

* Attention à la liste de sensibilité !
Actions mémorisées

* Les actions mémorisées sont forcément gérées dans un process synchrone

* Comme pour les actions non mémorisées, on peut également faire deux process indépendants pour les actions sur état et sur transition

```perl
process( clk, reset )
begin
    if reset = '1' then
        mon_action1 <= valeur_initiale1;
        mon_action2 <= valeur_initiale2;
    elsif rising_edge(clk) then
        case etat_courant is
            when etat_1 =>
                -- Action sur état
                mon_action1 <= valeur_1;
            when etat_2 =>
                -- Action sur transition
                if C2_1 = '1' then
                    mon_action2 <= valeur_2;
                end if;
            end case;
        end if;
    end process;
```
# Actions conditionnelles

* Et les actions conditionnelles dans tout ça ?

* Il suffit d'ajouter la condition de l'action

* Dans un process

* Ajouter un `if` pour les actions sur état

* Ajouter la condition au `if` existant pour les actions sur transition

* En combinatoire

* Il faut forcément utiliser un `when ... else`, même pour les actions sur état
RAPPELS : MACHINES À ÉTATS

UNE MACHINE À ÉTATS EN ÉLECTRONIQUE NUMÉRIQUE ?

REPRÉSENTATION D'UNE MAE EN VHDL

BLOC D'ÉVOLUTION DE L'ÉTAT

CALCUL DES ACTIONS

Exercice

ENCODAGE DE L'ÉTAT
# Exercice d'application

► 1) Décrire le type état, le signal état et les conditions

<figure><img src="image_22.png" /></figure>

architecture ar of ma_mae is

type etat_t is (etat_1, etat_2, etat_3);
signal etat_courant : etat_t;

signal C1_2 : std_logic;

signal C1_3 : std_logic;

signal C2_1 : std_logic;

signal C2_3 : std_logic;

signal C3_1 : std_logic;

begin

C1_2 <= Dem and not BAU;

C1_3 <= BAU;

C2_1 <= Stop;

C2_3 <= BAU;

C3_1 <= not BAU;

end architecture;
# Exercice d'application

* 1) Décrire le type état, le signal état et les conditions

* 2) Décrire le bloc d'évolution de l'état

<figure><img src="image_23.png" /></figure>

```pascal
process(clk, reset)
begin
  if reset = '1' then
    etat_courant <= etat_1;
  elsif rising_edge(clk) then
    case etat_courant is
      when etat_1 =>
        if C1_2 = '1' then
          etat_courant <= etat_2;
        elsif C1_3 = '1' then
          etat_courant <= etat_3;
      end if;
      when etat_2 =>
        if C2_1 = '1' then
          etat_courant <= etat_1;
        elsif C2_3 = '1' then
          etat_courant <= etat_3;
      end if;
      when etat_3 =>
        if C3_1 = '1' then
          etat_courant <= etat_1;
      end if;
    end case;
  end if;
end process;
```
Attention, il faut
penser à indiquer
à côté du graphe
d'états les valeurs
initiales et valeurs
par défaut

Exercice d'application

<figure><img src="image_24.png" /></figure>

1) Décrire le type état, le signal état et les conditions

<figure><img src="image_25.png" /></figure>

2) Décrire le bloc d'évolution de l'état

<figure><img src="image_26.png" /></figure>

3) Décrire les actions en utilisant des process

<figure><img src="image_27.png" /></figure>

process (etat_courant)

Begin

moteur <= '0';

case etat_courant is

when etat_2 =>

moteur <= '1';

end case;

end if;

end process;

process(clk, reset)

begin

if reset = '1' then
alarme <= '0';

elif risingEdge(clk) then
case etat_courant is

when etat_1 =>
    if C1_3 = '1' then
        alarme <= '1';
    end if;

when etat_2 =>

if C2_3 = '1' then
alarme <= '1';
end if;

when etat_3 =>

if C3_1 = '1' then
alarme <= '0';
end if;

end case;

end if;

end process;
RAPPELS : MACHINES À ÉTATS

UNE MACHINE À ÉTATS EN ÉLECTRONIQUE NUMÉRIQUE ?

REPRÉSENTATION D'UNE MAE EN VHDL

BLOC D'ÉVOLUTION DE L'ÉTAT

CALCUL DES ACTIONS

EXERCICE

Encodage de l'état
# Encodage de l'état

* On l'a vu, l'état courant de la MAE est une variable interne mémorisée

* Mais comment cette variable est-elle stockée ? En VHDL, on définit un type spécial...

* On laisse donc le choix au compilateur de la gérer comme il le souhaite

* Souvent, on peut choisir l'encodage de l'état des MAE via les options de compilation du logiciel
# Encodage one-hot

* Une bascule pour chaque état

* À tout instant, une et une seule bascule est à '1', toutes les autres sont à '0'

* Avantage

* Le fait qu'un état soit actif ou non est accessible immédiatement sans avoir besoin d'un circuit combinatoire de décodage ➔ réduit le nombre de composants combinatoires utilisés

* Inconvénient

* Occupe beaucoup de bascules ➔ augmente le nombre de bascules utilisées

<figure><img src="image_28.png" /></figure>

* Exemple

* Chaque état a sa bascule

* Une bascule pour État 0

* Une bascule pour État 1

* Les conditions « état_courant = état_0 » ou « état_courant = état_1 » deviennent simplinement « bascule D0 active » ou « bascule D1 active »
# Encodage numérique

<figure><img src="image_29.png" /></figure>

* Comme un seul état peut être actif à un instant t, on stocke le numéro de l'état actif

* Avantage

* Avec $n$ bascules, on peut stocker $2^n$ états ➔ réduit le nombre de composants combinatoires utilisés

* Inconvénient

* Il faut décodeer le numéro pour savoir dans quel état on est en utilisant un circuit combinatoire ➔ augmente le nombre de composants combinatoires utilisés

* Note : l'encodage numérique n'utilise pas forcément le binaire naturel pour la représentation

* Dans cet exemple, une seule bascule peut être utilisée : si elle vaut 0, on est dans l'état 0, et si elle vaut 1, on est dans l'état 1

* La condition combinatoire pour savoir quel est état l'actuel augmente à mesure que le nombre de bits pour stocker l'état augmente

* Par exemple, avec 4 bits pour le stockage de l'état, pour savoir si on est dans l'état 7, il faut comparer la valeur à « 0111 » ➔ autant de comparateurs que de bits
L'icône d'information
indique que le contenu de
ces slides est à titre
informatif, il ne vous est pas
demandé de le retenir

Bonus
Variante en utilisant des booléens

architecture ar of ma_mae is

signal C1_2 : boolean;

signal C1_3 : boolean;

signal C2_1 : boolean;

signal C2_3 : boolean;

signal C3_1 : boolean;

begin

C1_2 <= true when Dem = '1' and BAU = '0' else false;

C1_3 <= true when BAU = '1'                 else false;

C2_1 <= true when Stop = '1'                else false;

C2_3 <= true when BAU = '1'                 else false;

C3_1 <= true when BAU = '0'                 else false;

end architecture;

process(clk, reset)

begin

if reset = '1' then

etat_courant <= etat_1;

elif rising_edge(clk) then

case etat_courant is

when etat_1 =>

if C1_2 then

etat_courant <= etat_2;

elif C1_3 then

etat_courant <= etat_3;

end if;

when etat_2 =>

if C2_1 then

etat_courant <= etat_1;

elif C2_3 then

etat_courant <= etat_3;

end if;

when etat_3 =>

if C3_1 then

etat_courant <= etat_1;

end if;

end case;

end if;

end process;
<figure><img src="image_30.png" /></figure>

# Notion d'état total

* Connaître l'état actif d'une machine à état suffit-il à décrire complètement l'état de la machine ?

* Oui... si il n'y a aucune variable mémorisée

* Dans le cas où il y a des variables mémorisées, on parle d'« état total » pour décrire la totalité de l'état de la machine, qui contient

* L'état courant

* Les valeurs courantes de toutes les variables mémorisées

* Voilà pourquoi c'est parfois un abus de langage de parler de « l'état de la MAE » ou de dire qu'une MAE « est dans un état »
<figure><img src="image_31.png" /></figure>

Pour aller plus loin...

* One-process vs two-process vs three-process state machine

* Moore machine

* Mealy machine