Planche TP 1

Université Joseph Fourier
Master 1 Informatique
Année 2013/2014
Option
Introduction à la modélisation et à la vérification des systèmes numériques
Planche de TP n°1
Simulation avec ModelSim (http://model.com/)
Exercice 0. Prise en main
NB. Pour tous les TP (sauf le dernier), vous travaillerez dans votre sous-répertoire projet_asic
Nous allons tout d'abord découvrir l'utilisation de ModelSim avec un exemple simple (additionneur 1 bit) qui vous est fourni dans ~xm1iarclpi/TP/Add1
Vous devez tout d'abord créer un répertoire pour cet exemple et l'organiser en 4 sousrépertoires, comme c'est le cas dans ~xm1iarclpi/TP/Add1 (attention, vous devrez reprendre la
même démarche en re-créant des répertoires similaires pour tout autre exercice de simulation) :
total 4
drwxr-xr-x
drwxr-xr-x
drwxr-xr-x
drwxr-xr-x
2
2
4
2
xm1iarclpi
xm1iarclpi
xm1iarclpi
xm1iarclpi
512
512
512
512
Feb
Feb
Feb
Feb
15
15
15
15
10:21
09:44
10:11
09:44
bench
confmodelsim
libs
srcvhd
Puis :
- récupérer les fichiers qui sont dans ~xm1iarclpi/TP/Add1/confmodelsim et les placer
dans votre répertoire du même nom, puis modifier dans ces fichiers le chemin
$HOME/TP/Add1/ par votre propre chemin d'accès
- récupérer les fichiers qui sont dans ~xm1iarclpi/TP/Add1/srcvhd et les placer dans votre
répertoire du même nom, il s'agit du source VHDL de l'additionneur 1 bit et d'un script
utile pour réaliser sa compilation
- récupérer les fichiers qui sont dans ~xm1iarclpi/TP/Add1/bench et les placer dans votre
répertoire du même nom, il s'agit d'une entité de test et d'un script utile pour réaliser sa
compilation.
Réaliser successivement les opérations suivantes :
- se placer dans votre répertoire srcvhd, faire source ../confmodelsim/config, vérifier
que le fichier add1.vhd contient bien la description d'un additionneur 1 bit (style
dataflow, temps de traversée des portes négligés), et exécuter le script script.sh pour
réaliser sa compilation (on remarque que la bibliothèque de travail utilisée est
../libs/LIB_ADD1),
- se placer dans votre répertoire bench, et éditer le fichier testAdd1.vhd : il contient une
entité de test et une configuration externe pour cette entité. Préparer le test que vous allez
utiliser pour considérer tous les cas d'essais possibles pour les stimuli d'entrée de
l'additionneur, puis compléter l'architecture de l'entité de test en conséquence,
- exécuter le script script.sh pour réaliser la compilation de ce testbench (on remarque que
la bibliothèque de travail utilisée est ../libs/LIB_ADD1_BENCH),
- lancer le simulateur par la commande vsim
Dans le menu "simulate" de vsim, sélectionner "start simulation" et choisir la configuration qu'on
vient de compiler :
Puis sélectionner les signaux dont on souhaite visualiser les valeurs dans la waveform et faire
"add to wave". Enfin, lancer la simulation, soit par la commande "run" suivie d'un temps dans le
champ de commande en bas de la fenêtre, soit en utilisant le bouton associé (et le champ de
choix d'un temps) :
Vous obtiendrez les waveforms de simulation, c'est à dire quelque chose de la forme :
Il reste à vérifier que le résultat est bien le résultat attendu !
Exercice 1.
Cet exercice constitue le début du projet qui continuera jusqu'en fin de semestre. Il est consacré à
la conception d'un système de contrôle pour un cryptogarage fictif, en s'inspirant du descriptif
qui se trouve sur http://www.cygnacom.com/labs/ceal_finite_state.htm. Diverses
adaptations ont été faites ici, et un composant AES (http://en.wikipedia.org/wiki/
Advanced_Encryption_Standard) sera utilisé pour le chiffrement (voir partie 2).
1. Obligatoire. Cette semaine, il vous est demandé d'étudier très attentivement le système décrit
ci-dessous, puis de dessiner l'automate correspondant, de réaliser sa description VHDL et des
simulations pertinentes. Attention, toute erreur dans l'analyse se propagerait tout au long du
projet !
L'entité VHDL Crypto_garage ci-dessous décrira l'interface de ce système de contrôle :
entity Crypto_garage is
port(reset, clk, aes_key, authentication, reached_bottom,
reached_top, ACSC, bad_encryption, timeout : in std_logic;
switch : in Switches;
command : in Commands;
key_led, authentication_led, open_light, close_light: out std_logic);
end Crypto_garage;
Cette description utilise le package ci-dessous :
package Garage_types is
type Switches is (die, juice); -- interrupteur arret/marche
-- commandes pour la porte du garage :
type Commands is (no_command, deactivate, d_open, d_close);
-- etats de l'automate :
type States is (PowerUp, PowerDown, NoKey, Deactivated, Activated, Down,
Up, MovingOnDown, MovingOnUp, SafetyError, SecurityError);
-- a l'origine la porte est fermee (true) ou ouverte (false) :
constant init_closed : boolean := true;
end Garage_types;
Le système est synchronisé par les fronts montants de l'horloge clk, et est muni d'un reset
asynchrone actif haut reset. Les entrées primaires (qui peuvent provenir de capteurs) jouent les
rôles suivants : aes_key indique que la clé de chiffrement est disponible, authentication
indique que l'utilisateur a été authentifié, reached_bottom indique que la porte a atteint sa
position basse, reached_top indique que la porte a atteint sa position haute, ACSC (anti-crushsmall-children) indique qu'il faut provoquer un arrêt d'urgence du mouvement de la porte,
bad_encryption indique une transmission mal chiffrée, timeout indique un timeout qui
renvoie dans l'état désactivé, switch donne la valeur de l'interrupteur, et command indique la
commande soumise. Les sorties primaires permettent d'allumer des leds ou des lampes sur
certaines transitions ou dans certains états.
L'automate possède un état PowerUp qui est l'état initial (dans lequel le système revient en cas de
reset asynchrone), qui conduit à l'état PowerDown si switch prend la valeur die; sinon, si la clé
de chiffrement est disponible alors il conduit à l'état Deactivated, et sinon à l'état NoKey, dont
on ressortira dès que la clé de chiffrement sera disponible, pour atteindre Deactivated. Cet état
est l'état d'attente du succès de l'authentification de l'utilisateur et conduit alors à l'état
Activated. A ce point, si la commande deactivate est reçue ou si le timeout est atteint alors on
retourne dans l'état Deactivated; sinon, si la porte du garage est initialement fermée
(init_closed à true), l'automate atteint l'état Down, et sinon l'état Up.
Dans l'état Down, sur réception d'une transmission mal chiffrée, l'automate transite directement
dans l'état SecurityError, qui ramène à l'état Deactivated afin de ré-exiger une
authentification de l'utilisateur. Sinon, dès que la commande d_open est reçue en entrée,
l'automate se place dans l'état MovingOnUp. Pendant que la porte du garage est ainsi en train de
s'ouvrir, deux cas d'erreur sont prioritaires : sur réception d'une transmission mal chiffrée
l'automate transite directement dans l'état SecurityError, et sinon, sur réception du signal ACSC
il transite dans l'état SafetyError. Deux cas de fonctionnement normal sont aussi possibles : si
la commande d_close est reçue alors l'automate transite directement dans l'état MovingOnDown
afin de refermer la porte; mais si la porte atteint sa position haute alors l'état Up est atteint.
Symétriquement, dans l'état Up, sur réception d'une transmission mal chiffrée l'automate transite
directement dans l'état SecurityError. Sinon, dès que la commande d_close est reçue en
entrée, l'automate se place dans l'état MovingOnDown. Pendant que la porte du garage est ainsi en
train de se fermer, deux cas d'erreur sont prioritaires : sur réception d'une transmission mal
chiffrée l'automate transite directement dans l'état SecurityError, et sinon, sur réception du
signal ACSC il transite dans l'état SafetyError. Deux cas de fonctionnement normal sont aussi
envisageables : si la commande d_open est reçue alors l'automate transite directement dans l'état
MovingOnUp afin de rouvrir la porte; mais si la porte atteint sa position basse alors l'état Down est
atteint.
Il n'est possible de ressortir de l'état SafetyError que lorsque l'entrée ACSC repasse à '0'. Dans ce
cas, si la porte était en train de s'ouvrir (d_open) alors l'automate revient dans l'état MovingOnUp.
Si elle était en train de se fermer (d_close) alors l'automate revient dans l'état MovingOnDown.
Attention, de façon prioritaire, dans les états NoKey, Deactivated, Down et Up, si switch prend
la valeur die, alors l'automate revient dans l'état PowerDown. Il n'est possible de ressortir de cet
état que lorsque l'entrée switch repasse à juice, et on retourne alors dans l'état PowerUp.
La sortie key_led passe à '1' pour indiquer que la clé de chiffrement est prise en compte, c'est à
dire sur les transitions conduisant à Deactivated, depuis les états PowerUp et NoKey. La sortie
authentication_led passe à '1' pour indiquer que l'authentification vient de réussir, c'est à dire
sur la transition conduisant à Activated. La sortie open_light est à '1' pendant que la porte est
en train de s'ouvrir, c'est à dire à partir d'une transition conduisant à MovingOnUp et tant qu'on
reste dans cet état. La sortie close_light est à '1' pendant que la porte est en train de se fermer,
c'est à dire à partir d'une transition conduisant à MovingOnDown et tant qu'on reste dans cet état.
(a) Faire soigneusement le dessin de l'automate (FSM) correspondant. Les informations relatives
au reset asynchrone n'apparaîtront pas sur ce dessin, de même que les cas de rebouclage sur les
états (mais attention, tout ceci devra être pris en compte dans la description).
Attention, bien faire apparaître sur le dessin le déterminisme de l'automate, selon les priorités
énoncées ci-dessus. Faire également apparaître les affectations des sorties.
(b) Ecrire la description VHDL comportementale de ce système ("processes" de calcul de l'état
suivant, de mise à jour de l'état, et de mise à jour des sorties).
Pour utiliser le package Garage_types, vous utiliserez :
où
library LIB_XXX;
use LIB_XXX.Garage_types.all;
LIB_XXX est le nom que vous aurez choisi
pour votre bibliothèque.
(c) Concevoir une entité de test illustrant divers cas de figure (à expliquer), en supposant une
fréquence d'horloge de 50 MHz (on rappelle que la fréquence d'horloge correspond au nombre de
cycles d'horloge effectués en 1 seconde), et réaliser la simulation. Ne pas oublier de placer le
circuit dans son état initial en provoquant un reset en début de simulation.
2. Bonus. Nous allons ici rendre un peu plus réaliste cette description, en utilisant un composant
de chiffrement AES (toutefois, pour ne pas faire trop compliqué, tout en démontrant néanmoins
comment prendre en compte un tel composant, nous allons l'utiliser seulement pour l'identifica-
tion de l'utilisateur, et pas pour la transmission de commandes chiffrées).
Le principe sera le suivant : pour authentifier l'utilisateur, la clé de chiffrement (sur 128 bits)
devra être transmise à l'AES, puis le code d'identification chiffré (sur 128 bits), et l'automate
devra attendre que le code soit déchiffré, afin de le comparer au code valide1. Tout d'abord,
l'interface du cryptogarage va être modifiée comme suit :
entity Crypto_garage is
port(reset, clk, clk_aes, aes_key, reached_bottom, reached_top, ACSC,
bad_encryption, timeout : in std_logic;
key_in : in std_logic_vector(127 downto 0); -- cle
pin : in std_logic_vector(127 downto 0); -- code identification
switch : in Switches;
command : in Commands;
key_led, authentication_led, open_light, close_light: out std_logic);
end Crypto_garage;
On propose d'ajouter un signal d'horloge clk_aes pour l'AES (pour lui permettre de calculer à
une fréquence plus élevée, afin de ne pas subir de trop longs chronogrammes de simulation !).
Nous allons placer le composant AES à l'intérieur du cryptogarage, et l'entrée authentication
va donc devenir un signal interne. Le cryptogarage a par ailleurs deux entrées supplémentaires
key_in et pin, pour l'entrée de la clé de chiffrement et du code d'identification.
Le cryptogarage va inclure une instance du composant suivant :
entity aes_wrapper is
port (data_inH : in std_logic_vector(127 downto 0);
-- donnee
input_key : in std_logic_vector(127 downto 0); -- cle
key_size_in : in std_logic_vector(1 downto 0); -- taille de la cle
go_cipher, go_key, enc_command, cbc_in : in std_logic; -- controle
-- (cbc_in ne servira pas, la maintenir à '0')
data_outH : out std_logic_vector(127 downto 0); -- resultat
data_out_ok : out std_logic;
-- resultat disponible
ack_data_out : in std_logic;
-- recuperation du resultat finie
rst, ck : in std_logic);
end aes_wrapper;
NB. Pour récupérer le code compilé de ce composant, prendre le contenu du répertoire
~xm1iarclpi/TP/AES_pour_garage/libs/LIB_AES
Le cryptogarage va de plus être modifié comme suit. Il va avoir deux états supplémentaires :
SendKey pour l'envoi de la clé à l'AES, et WaitAuthentication pour attendre que l'AES ait fini
de calculer. Dans l'état PowerUp, si aes_key est à '0' alors on va toujours atteindre l'état NoKey,
mais si aes_key est à '1' alors on va récupérer la clé sur l'entrée key_in et la placer sur l'entrée
input_key de l'AES puis transiter dans l'état SendKey. Le comportement est similaire dans l'état
d'attente de la clé NoKey. L'état SendKey a pour objet la prise en compte de la clé par l'AES :
pour ce faire, l'entrée go_key de l'AES doit être mise à '1', et l'entrée key_size_in à la valeur
binaire "01" (pour indiquer que la taille de la clé est 1 fois 128 bits), et on peut transiter vers
l'état Deactivated. Dans cet état, les entrées go_key et key_size_in de l'AES vont être remises
à '0' et à "00", et l'AES doit maintenant traiter le code d'identification chiffré : l'entrée
go_cipher de l'AES doit être mise à '1', l'entrée enc_command à '0', et le code reçu sur pin doit
être placé sur l'entrée data_inH de l'AES. Il reste alors à attendre la fin du calcul en se plaçant
dans l'état WaitAuthentication. Dans cet état, l'entrée go_cipher est remise à '0' et on reste
dans cet état tant que la sortie data_out_ok de l'AES est à '0'. Si elle passe à '1' (calcul fini), il
reste à comparer le résultat fourni sur data_outH avec le code valide (à stocker dans le
1
A noter que la mise en œuvre ci-dessous fait quelques simplifications quant à l'utilisation du composant de chiffrement, mais le
principe est respecté.
cryptogarage) et à passer dans Activated si l'authentification a réussi ou retourner dans
Deactivated sinon.
L'entrée ack_data_out de l'AES sera mise à '1' sur les transitions sortantes de l'etat
WaitAuthentication (donc si data_out_ok est à '1'), en effet 1 cycle est suffisant pour
récupérer le résultat.
Attention, la clé devant être transmise avant tout calcul, les rebouclages dans la version 1 de
Activated et SecurityError vers Deactivated deviennent ici des rebouclages vers SendKey.
Pour mettre en œuvre et tester cette version, nous vous suggérons d'utiliser :
- la clé X"2b7e151628aed2a6abf7158809cf4f3c"
- le code X"AF441F3F4606C30801B7125C373EFE80"
- et le code valide attendu X"00000006000000050000000400000003"
Adapter le dessin de l'automate, la description VHDL, et l'entité de test, pour réaliser et tester
cette deuxième version. Ne pas oublier de bien commenter les sources et les résultats de
simulation.
A rendre (ne pas oublier d'indiquer vos noms et votre numéro de login):
-
à la fin du TP : votre dessin d'automate (à la main, complet, lisible et soigné) + votre
description VHDL commentée avec soin + une indication de vos résultats de simulation.
- avant le 18 Mars soir (par mail à Laurence Pierre) : un rapport en pdf contenant
o le dessin d'automate soigné (vous pourrez utiliser un logiciel de dessin) et expliqué,
o une explication de l'interprétation de l'automate en description VHDL,
o votre description VHDL commentée avec soin,
o les scénarios que vous avez choisi de tester et les résultats de simulation
correspondants (testbenches correctement décrits, et résultats de simulation clairement commentés).
Si vous avez découvert des erreurs dans votre description faite pendant le TP, vous pourrez
ici les corriger, mais il faudra indiquer la présence de ces corrections.
Tout élément bonus également réalisé pourra aussi être rendu dans ce rapport.
NB. Si vous souhaitez faire des copies de fenêtres, vous pouvez utiliser xwd :
xwd > macopie.bmp
et click sur la fenêtre voulue. Ceci produit un fichier bitmap macopie.bmp, que vous pouvez
convertir dans d'autres formats si vous le souhaitez (jpeg par exemple) avec gimp
Une alternative est l'utilisation de Applications  Accessories  Take screenshot