# Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/TPs de préparation

Nous allons regrouper dans ce chapitre un ensemble de TPs qui sont réalisées en niveau 14 (L1). Ils ne correspondent pas au niveau de ce livre, mais sont livrés ici pour permettre justement une préparation au contenu de ce livre. En clair il s'agit plutôt de TPs de préparation ou même de révision.
Quelques questions de ce TP sont formulées en anglais. Cela peut choquer les amoureux de la langue de Molière, mais il faut savoir que nous sommes très incités à le faire le plus possible dans notre enseignement. Alors pourquoi pas ici ?

## Utilisation DE10 Lite

À partir de 2019, nous remplaçons la basys2 (Digilent et Xilinx) par la DE-10 Lite (Intel/Altera Terasic).
Les gros changements seront dans le fichier de contraintes. Il sera constitué par un fichier au format .csv qui sera à importer.
Les anciens TPs sont gardés en fin de chapitre. Les nouveaux auront un contenu similaires mais ne peuvent pas être utilisés tels quels. Il y a des spécificités Xilinx qu'il nous faut abandonner, en particulier sur les LUTs et les mémoires. Il est possible d'utiliser les LUTs avec Altera mais pas de manière aussi simple. Nous en profitons pour les abandonner (TP2).

### Autres ressources

Le site Intel pour la DE10 Lite est : University Boards. Vous y trouverez, entre autre, en choisissant la DE10 Lite parmi les cartes :
* DE10 Lite User Manual
* un fichier DE10_Lite.qsf
Nous avons considéré à utiliser comme fichier de contraintes le fichier qsf ci-dessus à un moment. Puis nous avons abandonné l'idée aux vues des problèmes posés. Pour information, les problèmes posés étaient liés au fait que lors d'une séance de TP nous faisons faire un seul projet qui est modifié au fur et à mesure de l'avancement des différents exercices mais pas refait du départ. Certainement par ignorance, nous n'avons pas réussi à trouver une méthode efficace qui efface les contraintes du projet précédent lors de la modification du code source VHDL et de la modification des contraintes pour l'exercice en cours de construction. Ce problème ne se retrouve pas dans l'utilisation d'un fichier de type csv pour les contraintes. Cette méthode sera donc présentée dans la suite du TP.

## TP1 - Des Tables de vérité et VHDL aux simplifications (3 heures)

L'objectif de ce TP est de montrer qu'avec un FPGA la connaissance d'une table de vérité suffit pour réaliser un programme VHDL (sans les simplifier). Cependant, pour vous faire travailler les tableaux de Karnaugh, on vous demandera parfois de trouver les équations et de les implanter. À la fin de ce TP, vous serez capable
* d'établir une table de vérité
** d'en déduire immédiatement le programme VHDL correspondant
** ou de la transformer à l'aide d'un tableau de Karnaugh en une équation simplifiée et de l'implanter en VHDL
Tous ces allers et retours entre toutes ces formes (Table de vérité, Tableau de Karnaugh, équations) sont la base de l'apprentissage.

### Un exemple simple pour comprendre l'IDE Quartus (Exercice 0)

Vous allez réaliser un simple OU en suivant un exemple complet réalisé par votre enseignant. L'objectif est d'apprendre :
* à réaliser un fichier VHDL, le sauver et l'ajouter au projet
* à réaliser un fichier de contrainte pour choisir les entrées et sorties, et l'ajouter au projet
* à compiler
* à charger le fichier dans votre FPGA avec USB BLASTER
Voici les fichiers VHDL utilisés :
* à partir d'une table de vérité
* à partir d'une équation
Modifier cet exemple pour ajouter une sortie qui réalise un ET.

#### Fichier csv utile pour DE10-Lite

Nous utilisons depuis plusieurs années le fichier de contraintes donné avec le format csv. Il est possible cependant d'utiliser une autre méthode directement dans le code VHDL comme ci-dessous :
L'utilisation de contraintes très nombreuses alourdira cependant le code VHDL. Nous donnons aux étudiants la possibilité de séparer les contraintes dans un autre fichier.
Pour éviter de chercher nous donnons quelques contenus du fichier csv :
Ce fichier est à copier et sauver avec l'extension .csv dans votre projet Quartus.
* Ce fichier csv est un fichier général. Il faut l'adapter avec les noms de vos entrées et sorties que vous avez utilisé dans votre code source VHDL. SW[X] désigne un bouton d'entrée tandis que LEDR[Y] désigne une led rouge. Les entrées sorties utilisées dans les programmes VHDL donnés sont e0,e1 pour les entrées et s pour la sortie unique. On doit retrouver à tout prix ces noms dans le fichier de contraintes !!!!
Puis il faut l'importer dans le projet Quartus : Assignments -> Import Assignments
* Ne déduisez surtout pas de cet exercice que les programmes VHDL sont plus courts avec des équations ! Vous vous apercevrez très vite que ce n'est pas le cas en général.

### Exercice 1 : Analyse d'un schéma simple puis synthèse équivalente

On donne le schéma ci-contre.
1°) Plot the corresponding function in the truth table below and in the Karnaugh map. Find the simplified sum of product expression of s=f(e0,e1,e2).

#### Table de vérité

    EntréesSorties e2e1e0abs 000??? 001??? 010??? 011??? 100??? 101??? 110??? 111???
Remarque : a et b ne sont pas à proprement parler des sorties. Il s'agit de fils intermédiaires, mais il faut les calculer pour avoir s.
2°) Realize the corresponding simplified expression as a VHDL program with an equation.
3°) Realize the corresponding boolean function as a VHDL program with a with select when.

### Exercice 2 (Vote au directoire)

Le comité directeur d’une entreprise est constitué de quatre membres :
* le directeur D,
* ses trois adjoints A, B, C.
Lors des réunions, les décisions sont prises à la majorité.
Chaque personne dispose d’un interrupteur pour voter sur lequel elle appuie en cas d’accord avec le projet soumis au vote. En cas d'égalité du nombre de voix, celle du directeur compte double.
On vous demande de réaliser un dispositif logique permettant l’affichage du résultat du vote sur lampe V (pour nous ce sera une LED).
1°) Écrire une table de vérité pour la sortie V puis un tableau de Karnaugh
2°) Réaliser le programme VHDL pour la sortie V avec un with select when (autrement dit à partir de la table de vérité).
3°) Réaliser le programme VHDL pour la sortie V avec une équation (si possible simplifiée avec un tableau de Karnaugh).

### Exercice 3 (Vote au directoire amélioré)

Une société est composée de 4 actionnaires ayant les nombres suivants d'actions A=60, B=100, C=160 et D=180.
Nous désirons construire une machine à voter automatiquement, tenant compte dans le résultat du poids en actions de chaque personne. La machine dispose de 4 boutons poussoirs A, B, C, D et le résultat sera un voyant V qui s'allumera si la majorité pondérée appuie sur les boutons.
1°) Écrire une table de vérité pour la sortie V. Réaliser le programme VHDL correspondant et vérifier que vous avez la bonne table de vérité.
2°) Réaliser le programme VHDL avec un with select when. Remarquez l'apparition d'un WARNING.
3°) Pour comprendre le WARNING de la question précédente, on vous demande de trouver l'équation simplifiée. En l'examinant vous comprendrez quel est le problème. Puis réaliser le programme VHDL avec une équation logique pour la sortie V en supprimant le WARNING.

### Solutions générales du TP 1

Nous mettons ici un lien vers les corrigés qui se trouvent sur le WIKI de l'IUT de Troyes. Comme ces TPs sont effectivement réalisés par les étudiants de GEII, les solutions en question ne sont accessibles qu'en accès réservé sur une partie de l'année. Essayez le lien, il est librement accessible une quarantaine de semaines dans l'année voire plus si le TP est abandonné :
* Corrigé du TP1
Si l'accès vous est refusé, patientez et revenez quelques semaines plus tard.

## TP2 - Encore des tables de vérités (en VHDL)
### Fichier csv

Nous donnons le fichier de contraintes complet (pour réaliser ce TP) sous la forme d'un fichier csv :

### Multiplieur de deux nombres de 2 bits
#### Exercise 1 (English)

Design and build a combinational logic circuit with four inputs and four outputs that multiplies two 2-bits numbers, labeled X, and Y. The output is labeled Z. Use a truth table and find out the corresponding with select when.
Realize this boolean function with a "WITH SELECT WHEN"

### Transcodeur binaire 7 segments

Lire Afficheur 7 segments.
On va réaliser un transcodeur binaire décimal vers un afficheur 7 segments. L'objectif de ce TP est d'utiliser toutes les techniques classiques de synthèse combinatoire.

#### Présentation du sujet

Un schéma présente de manière symbolique ce que l'on cherche à faire.
La figure ci-dessus vous donne les contraintes de placement des entrées sorties. Vous pouvez le vérifier avec le fichier csv qui vous est donné un peu plus haut.
La valeur binaire (de 0 à F) choisie sur les interrupteurs est convertie pour être affichée comme ci-contre.

#### Exercice 2 : Transcodeur hexadécimal vers sept segments et « with select when »

1°) First complete the truth table below. Read the first line carefully before starting.

##### Table de vérité

    EntréesSorties sw3sw2sw1sw0gfedcba 00001000000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
2°) Realize this truth table as circuit in VHDL (style "with select when").
Il serait bon de mettre de côté un programme solution de la question 2°. Vous en aurez besoin plus tard.

### Exercice 3 : Transcodeur pour dé

1°) Réaliser le transcodeur ci-contre avec les LEDs présentes sur la carte FPGA en utilisant un with select when. Ce que vous avez à réaliser est donc un circuit qui comporte 3 interrupteurs en entrée et 7 leds en sortie (voir schéma ci-contre).
2°) En gardant ce que vous avez fait en question 2°, on vous demande d'y ajouter un affichage sur les sept segments en utilisant le programme de la question 2° ou 3° de l'exercice précédent (que l'on vous avez demandé de mettre de côté).
Malheureusement les tests ne seront pas facilités puisque les leds utilisées sont alignées... ce qui ne serait pas le cas pour un dé commercialisé... mais l'esprit humain peut contourner ce genre de détail.

### Exercice 4

Reprendre l'exercice 2 et l'étendre pour 8 bits d'entrée et un affichage sur 2 digits. Les poids faibles seront naturellement à droite HEX0 et les poids forts à gauche HEX1.
Il existe aux moins trois méthodes pour résoudre ce problème :
* Une première méthode serait de faire une table de vérité sur toutes les entrées. Pour 8 entrées cela fait une table de vérité de 256 lignes avec une gestion de 2x7=14 sorties. Avis aux amateurs !
* Une deuxième méthode consiste à faire deux "with select when" séparés dans une seule architecture. Chacun des "with select when" gérera 4 bits d'entrées et 7 bits de sortie.
* Une troisième méthode consiste à prendre le premier transcodeur binaire/7 segments réalisé en exercice 2 et d'en faire un composant. Cette façon de faire les choses est absolument fondamentale mais ne peut être réalisée par les étudiants que si elle a déjà été expliquée en cours et/ou en TD. Pour ceux qui désirent apprendre seuls, vous avez un lien ci-dessous.

#### Voir aussi

Assembler des composants en VHDL

### Solutions générales du TP 2

Nous mettons ici un lien vers les corrigés qui se trouvent sur le WIKI de l'IUT de Troyes. Comme ces TPs sont effectivement réalisés par les étudiants de GEII, les solutions en question ne sont accessibles qu'en accès réservé sur une partie de l'année. Essayez le lien, il est librement accessible une quarantaine de semaines dans l'année voire plus si le TP est abandonné :
* Corrigé du TP2
Si l'accès vous est refusé, patientez et revenez quelques semaines plus tard.

## TP3 Arithmétique, comparateurs et multiplexeurs

L'arithmétique consiste à implanter des fonctions de base de l'arithmétique, c'est-à-dire addition, soustraction et multiplication. L'utilisation de l'arithmétique dans un FPGA doit suivre ses propres règles. Nous allons commencer par examiner l'addition, d'abord sans se préoccuper du fait que l'on utilise un FPGA, puis on cherchera à utiliser les composants Altera.

### Fichier csv

Nous donnons le fichier de contraintes complet (pour réaliser ce TP) sous la forme d'un fichier csv :

### De l'additionneur 1 bit à l'additionneur 4 bits

Pour compléter vos connaissances, vous pouvez lire Additionneur dans Wikipédia et/ou l'addition dans Wikibook.
Les circuits de calcul entier reste le document le plus complet sur le sujet dans WIKIBOOK (surtout pour la deuxième question de l'exercice 1).

#### Exercice 1

1) Implanter un additionneur 1 bit avec un with select when. Pour les tests, les entrées seront reliées à des interrupteurs et les sorties à des LEDs.
2) Réaliser 4 fois le schéma précédent et montrer que l'on peut réaliser ainsi un additionneur 4 bits. N'oubliez pas que la somme de deux nombres de 4 bits peut donner un nombre de 5 bits. Lire additionneur parallèle à propagation de retenue et mieux encore Addition non signée où vous trouverez le schéma ci-dessous qui est demandé dans cette question 2 :

### Application simple d'un additionneur 4 bits : codage/décodage du code Excess 3

Après avoir réalisé un additionneur 4 bits, on vous propose l'exercice ci-dessous. L'additionneur 4 bits est nommé 7483 dans le schéma.

#### Exercice 2 (transcodeur BCD vers EXCESS- 3)

Code converter is a combinational circuit that translates the input code word into a new corresponding word. The (fr) excess-3 code digit is obtained by adding three to the corresponding BCD digit. To Construct a BCD-to-excess-3-code converter with a 4-bit adder feed BCD-code to the 4-bit adder as the first operand and then feed constant 3 as the second operand. The output is the corresponding excess-3 code.
Realize this circuit diagram in VHDL.
* Indications :
* Le circuit proposé réalise la conversion de code BCD vers Excess-3 mais aussi Excess-3 vers BCD. Comme indiqué sur la figure, c'est Cin qui permet de choisir le sens de fonctionnement.
* On pourrait utiliser le code ci-dessous pour l'additionneur 4 bits en lieu et place de celui qu'on a réalisé dans l'exercice 1 :
* -- addition sur 4 bits
* library IEEE;
* use IEEE.std_logic_1164.all;
* use IEEE.std_logic_arith.all;
* use IEEE.STD_LOGIC_UNSIGNED.all;
* ENTITY add4 IS
* PORT (a,b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
* Cin : IN STD_LOGIC; --retenue précédente
* s : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)); --retenue en s(4)
* END add4;
* ARCHITECTURE arch_add4 OF add4 IS
* BEGIN
* -- ne pas confondre + avec OR
* s <= conv_std_logic_vector((conv_integer(a) + conv_integer(b) + conv_integer(Cin)),5);
* END arch_add4;
Mais vous pourriez aussi utiliser la hiérarchie de l'exercice 1 pour obtenir une hiérarchie sur 3 niveau : le transcodeur qui contient un additionneur 4 bits qui contient 4 additionneurs 1 bit.
Quelque soit votre choix, les ou exclusifs (de la figure ci-dessus, pas ceux des additionneurs) seront réalisés avec de simples équations (pour éviter d'autres port map).
Pour vous aider à tester, la table de vérité du code excess-3 donnée maintenant :

##### Table de vérité du code EXCESS-3

    EntréesSorties B3B2B1B0E3E2E1E0 00000011 00010100 00100101 00110110 01000111 01011000 01101001 01111010 10001011 10011100 1010ΦΦΦΦ 1011ΦΦΦΦ 1100ΦΦΦΦ 1101ΦΦΦΦ 1110ΦΦΦΦ 1111ΦΦΦΦ

### Exercice 3

La première partie n'utilise pas le tableau de Karnaugh de la figure. Celui-ci est uniquement lié à la deuxième partie de cet exercice.

#### Première partie

Dans la figure ci-contre, la sortie GT désigne Greater Than et la sortie LT désigne quant à elle Less Than. Quand le nombre $(A_{3},A_{2},A_{1},A_{0})_{2}$ est plus grand que le nombre $(B_{3},B_{2},B_{1},B_{0})_{2}$ alors la sortie GT passe à 1. Elle reste à 0 dans tous les autres cas. Ce genre de circuit est appelé comparateur.
Réaliser une comparaison seule (figure ci-contre en remplaçant le "neuf" par des interrupteurs). Modifier le fichier csv pour utiliser sw7 ... sw0 en entrée et led0 en sortie (pour GT seulement). Tester.
* Indication :
* Le comparateur COMPM4 présent dans cet exercice est une terminologie Xilinx. Il pourrait être avantageusement remplacé par lpm_compare avec Quartus mais celui-ci est un peu trop complexe à ce stade des TPs. Nous préférons donc donner son code VHDL (ce code VHDL est automatiquement généré dès que vous utilisez un COMPM4 dans un schéma, d'où sa lourdeur) :
* library IEEE;
* use IEEE.STD_LOGIC_1164.all;
* use ieee.std_logic_unsigned.all;
* entity COMPM4_exo3 is
* port(
* GT : out std_logic;
* LT : out std_logic;
* A0 : in std_logic;
* A1 : in std_logic;
* A2 : in std_logic;
* A3 : in std_logic;
* B0 : in std_logic;
* B1 : in std_logic;
* B2 : in std_logic;
* B3 : in std_logic
* end COMPM4_exo3;
* architecture COMPM4_exo3_V of COMPM4_exo3 is
* signal a_tmp: std_logic_vector(3 downto 0);
* signal b_tmp: std_logic_vector(3 downto 0);
* begin
* a_tmp <= A3&A2&A1&A0;
* b_tmp <= B3&B2&B1&B0;
* GT <= '1' when (a_tmp > b_tmp ) else '0';
* LT <= '1' when (a_tmp < b_tmp ) else '0';
* end COMPM4_exo3_V;
* ----- CELL CB4CE_HXILINX_chenillard -----
Pour vous obliger à bien comprendre ce code, il vous est demandé de remplacer les entrées individuelles A3,A2,A1,A0 et B3,B2,B1,B0 par deux entrées a et b en std_logic_vector( 3 downto 0). En clair vous faites certes un copier/coller du code, mais vous le modifiez ensuite. Le code final doit être ainsi simplifié (d'au moins 10 lignes).

#### Deuxième partie

Puis fixer les entrées Bi à 9 pour en faire une fonction de 4 entrées A3,A2,A1,A0 comme dans la figure. Remplir une table de vérité puis un tableau de Karnaugh.

##### Table de vérité du comparateur à 9

    EntréesSorties A3A2A1A0GT 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
Table de Karnaugh :
* S
* A3 A2
* 00
* 01
* 11
* 10
1°) Implanter la table de vérité réalisant l'ensemble. La câbler puis l'essayer dans le FPGA. Faire constater à l'enseignant.
2°) Déduire du tableau de Karnaugh une équation simplifiée que l'on implantera en VHDL.

### Exercice 4 : additionneur complet (1 bit) et multiplexeur

* L'objectif de cet exercice est de réaliser une synthèse avec un ou plusieurs multiplexeurs. Ce type de synthèse n'a pas forcément été abordée en TD. Donc, avant de vous lancer dans cet exercice, demandez à l'enseignant quelques indications.
Implement a full 1-bit adder
(a) using two 8-to-1 MUXes. Connect X,Y, and Cin in to the control inputs of the MUXes and connect 1 or 0 to each data input.
(b) using two 4-to-1 MUXes and one inverter. Connect X and Y to the control inputs of the MUXes, and connect 1’s, 0’s, Cin in , or Cin′ in to each data input.
(c) again using two 4-to-1 MUXes, but this time connect Cin in and Y to the control inputs of the MUXes, and connect 1’s, 0’s, X, or X′ to each data input. Note that in this fashion, any N-variable logic function may be implemented using a 2 (N−1) to-1 MUX.
* Indication :
* ce travail nécessite de réaliser un assemblage de circuits donc se fait avec des PORT MAP: voir Assembler des composants en VHDL.
* Voici le code de départ d'un multiplexeur 8 vers 1.
* -- description du multiplexeur
* library ieee;
* use ieee.std_logic_1164.all;
* entity mux8 is port (
* sel: in std_logic_vector(2 downto 0);
* e : in std_logic_vector(7 downto 0);
* s : out std_logic
* end entity mux8;
* architecture behavior of mux8 is
* begin
* with sel select
* s <= e(0) when "000",
* e(1) when "001",
* e(2) when "010",
* e(3) when "011",
* e(4) when "100",
* e(5) when "101",
* e(6) when "110",
* e(7) when others;
* end behavior;

### Solutions générales du TP 3

Nous mettons ici un lien vers les corrigés qui se trouvent sur le WIKI de l'IUT de Troyes. Comme ces TPs sont effectivement réalisés par les étudiants de GEII, les solutions en question ne sont accessibles qu'en accès réservé sur une partie de l'année. Essayez le lien, il est librement accessible une quarantaine de semaines dans l'année voire plus si le TP est abandonné :
* Corrigé du TP3
Si l'accès vous est refusé, patientez et revenez quelques semaines plus tard.

## TP4 Introduction au séquentiel (3 heures)
### Besoin d'une horloge pour dépasser le combinatoire

Les compteurs permettent de diminuer la fréquence d'horloge (entre autre).

### Fichier csv

Nous donnons le fichier de contraintes complet (pour réaliser ce TP) sous la forme d'un fichier csv :

#### Exercice 1

Vous disposez d'une horloge 50MHz en broche "P11" de votre composant FPGA MAX10. Réaliser à l'aide d'un compteur 24 bits une horloge d'environ 3 Hz. Sortie sur une LED, le clignotement de celle-ci doit être visible à l'œil.
* Indications
* Un exemple de compteur est donné ci-dessous. Il s'agit d'un compteur 8 bits. Vous devez donc l'adapter pour l'exercice 1 :
* Changer le nom de l'entité, cmpt8bits ne correspondra plus à la fonction réalisée. cmpt24bits serait plus adapté
* diminuer la taille de la sortie qui passe de 8 bits à un bit et l'appeler clk_slow par exemple
* augmenter la taille du compteur qui passe de 8 bits à 24 bits
* changer la toute dernière équation (qui est combinatoire)
* library IEEE;
* use IEEE.STD_LOGIC_1164.ALL;
* use ieee.std_logic_arith.all;
* use ieee.std_logic_unsigned.all;
* ENTITY cmpt8bits IS
* PORT(clk_50 : IN STD_LOGIC;
* cnt : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
* END cmpt8bits;
* ARCHITECTURE arch_cmpt8bits OF cmpt8bits IS
* signal cmpt : std_logic_vector(7 downto 0);
* BEGIN
* process(clk_50) begin
* if rising_edge(clk_50) then
* cmpt <= cmpt + 1;
* end if;
* end process;
* cnt <= cmpt;
* END arch_cmpt8bits;
* L'horloge que l'on vient de réaliser sera utilisée presque systématiquement par la suite. Il faut donc sauvegarder à tout prix ce fichier source.
* Cette façon de réaliser une horloge lente est déconseillée dans les FPGA. Nous décidons quand même de l'utiliser par souci de simplification pour des étudiants débutants.
Par abus de langage on appellera compteur dans toute la suite de ces TPs, un élément séquentiel qui comporte une horloge mais qui ne compte pas forcément en binaire. Dans ce dernier cas, son équation de récurrence ne peut donc pas s'écrire simplement à l'aide d'une addition.

### Réaliser un graphe d'évolution simple

Avant toute chose, il nous faut nous demander comment utiliser des équations de récurrences booléennes. On vous représente ci-après la façon de procéder :
* trouver le diagramme d'évolution
* en déduire le tableau état présent/état futur
* en déduire les équations en utilisant éventuellement un tableau de Karnaugh
Lisez Des diagrammes d'évolutions aux équations de récurrences pour la partie théorique. Vous y trouverez les équations de récurrences nécessaires à la réalisation de l'exercice 2.

#### Exercice 2

1°) Realize the system specified above with a state diagram. The clock is, as usual, "clk_slow" (see l'exercise 1). Add two LEDs as outputs to be able to check your VHDL program.
2°) Design a modulo-4 counter with an input D, for Down. When D is not asserted, the counter counts up, modulo-4. When D is asserted (1), the counter counts down, modulo-4. Draw a state diagram to implement it and derive the state table. Then design a complete sequential circuit using VHDL. Please use a 7 segments display to check your VHDL code.
* Indication :
* Si vous voulez avoir une chance de voir les LEDs défiler, vous devez utiliser le compteur de l'exercice 1 pour faire une horloge lente et l'utiliser comme entrée horloge de ce qui vous est demandé. Il y a donc du PORT MAP dans l'air.
* library ieee;
* use ieee.std_logic_1164.all;
* ENTITY cmpt_exo2 IS PORT (
* clk: IN std_logic;
* q0,q1: OUT std_logic);
* END cmpt_exo2;
* ARCHITECTURE arch_cmpt_exo2 OF cmpt_exo2 IS
* SIGNAL q1q0 : std_logic_vector(1 downto 0);
* BEGIN
* PROCESS (clk) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
* IF (clk'EVENT AND clk='1') THEN
* q1q0(0) <= NOT q1q0(0);
* -- add the second equation here
* END IF;
* END PROCESS;
* -- mise à jour des sorties
* q0 <= q1q0(0);
* q1 <= q1q0(1);
* END arch_cmpt_exo2;

### Compteur décimal à sortie directe sept segments (1 digit en VHDL)

Le compteur sept segments est réalisé en VHDL et sera assemblé avec le dispositif destiné à réaliser l'horloge lente : compteur 24 bits de l'exercice 1.

#### Exercice 3

1°) Écrire les équations logiques a+, b+, c+, d+ ,e+, f+, g+ en fonction des entrées a, b, c, d, e, f, g. Implanter en VHDL.
Il nous reste un problème important à résoudre, c'est l'initialisation. En effet pour bien faire il faudrait étudier les 127-10=117 états restants pour voir comment ils se connectent sur notre cycle. C'est un travail important qu'il est impossible de réaliser à moins d'y passer 117 soirées (à raison d'une transition par soirée) soit presque 4 mois !!!
Pour éviter cela on va prévoir une entrée d'initialisation appelée Init au cas où à la mise sous tension on se trouve dans un état non prévu. Cette entrée fonctionnera de manière synchrone, lorsqu'elle sera à 1 un front d'horloge provoquera l'affichage du 0 en sortie du compteur.
2°) Écrire maintenant les équations de récurrence trouvées en 1°) en ajoutant convenablement l'entrée Init.

#### Exercice 4

Refaire le même travail que l'exo3 en utilisant un case when et toujours "clk_slow" comme horloge.
Remarquez l'utilisation du STD_LOGIC_VECTOR au lieu des sorties individuelles. Le fait qu'il soit en OUT implique que l'on utilisera un signal interne pour les "CASE".
Indication : Implanter un diagramme d'évolution en VHDL peut se faire de manière systématique :
* library ieee;
* use ieee.std_logic_1164.all;
* ENTITY demo IS PORT(
* clock : IN std_logic;
* q : OUT std_logic_VECTOR(1 DOWNTO 0));
* END demo;
* ARCHITECTURE mydemo OF demo IS
* SIGNAL q1q0 : std_logic_vector(1 downto 0);
* BEGIN
* PROCESS(clock) BEGIN
* IF clock'EVENT AND clock='1' THEN
* CASE q1q0 IS --style case when
* WHEN "00" => q1q0 <="01";
* WHEN "01" => q1q0 <="10";
* WHEN "10" => q1q0 <="11";
* WHEN OTHERS => q1q0 <="00" ;
* END CASE;
* END IF;
* END PROCESS;
* q <= q1q0;
* END mydemo;

### Solutions générales du TP 4

Nous mettons ici un lien vers les corrigés qui se trouvent sur le WIKI de l'IUT de Troyes. Comme ces TPs sont effectivement réalisés par les étudiants de GEII, les solutions en question ne sont accessibles qu'en accès réservé sur une partie de l'année. Essayez le lien, il est librement accessible une quarantaine de semaines dans l'année voire plus si le TP est abandonné :
* Corrigé du TP4
Si l'accès vous est refusé, patientez et revenez quelques semaines plus tard.

## TP5 M1102 : VHDL et Compteurs
### Exercice 1

Cet exercice ne sera réalisé que par les étudiants qui ne sont pas allés jusqu'au bout du TP 4.
Nous vous donnons deux composants VHDL et on vous demande d'en réaliser un assemblage.
On vous donne les deux composants VHDL suivants. On vous demande de les assembler (en complétant les transitions de « cmpt7seg » ) dans un programme TOP.
Nous allons reprendre le problème du compteur sept segments mais de façon plus normale.

### Compteur à sortie sept segments sur deux digits en VHDL

Cette partie doit être réalisée avec les afficheurs sept segments reliés à la carte.
Nous allons réaliser cet exercice en plusieurs étapes.

#### Exercice 2

Nous désirons implanter un ensemble composé d'un compteur 8 bits et sortant sa valeur sur deux afficheurs sept segments ( affichage de 00 à FF)...
Attention, le poids faible doit être à droite !!!
1°) Réaliser d'abord un compteur simple 8 bit associé à une division par 2**24 et sortant directement sur des LEDs. La seule entrée est clk_50 qui se trouve en "P11" sur le FPGA. Les 8 sorties sont reliées aux 8 LEDs de la carte. Remarquez que le seul compteur qui nous intéresse est le compteur 8 bits de droite, l'autre étant là pour ralentir l'horloge.
2°) Réaliser maintenant l'affichage des 4 bits de poids faibles sur un seul afficheur.
3°) Réaliser maintenant l'affichage des 8 bits du compteur sur deux afficheurs. La figure donne en principe ce que l'on cherche à faire. Vous devez comprendre la présence des deux transcodeurs.
4°) Il peut être aussi très important de savoir utiliser le travail des autres. Une librairie intéressante (parcequ'elle est universelle) est la librairie "library of parameterized modules" (LPM). Réaliser le même montage que la question 3 en utilisant un compteur générique lpm
* Indications :
* Vous devriez avoir sauvegardé depuis longtemps le transcodeur :
* library IEEE;
* use IEEE.STD_LOGIC_1164.ALL;
* ENTITY transcod7segs IS PORT(
* e : in std_logic_vector(3 downto 0);
* s7segs : out std_logic_vector(6 downto 0));
* END transcod7segs;
* ARCHITECTURE arch of transcod7segs IS
* BEGIN
* with e select
* --gfedcba
* s7segs <= "1000000" when "0000",
* "1111001" when "0001",
* "0100100" when "0010",
* "0110000" when "0011",
* "0011001" when "0100",
* "0010010" when "0101",
* "0000010" when "0110",
* "1111000" when "0111",
* "0000000" when "1000",
* "0010000" when "1001",
* "0001000" when "1010",
* "0000011" when "1011",
* "1000110" when "1100",
* "0100001" when "1101",
* "0000110" when "1110",
* "0001110" when others;
* END;
* L'utilisation de la librairie LPM se fait par :
* -- a mettre dans la partie entête
* library IEEE;
* use IEEE.STD_LOGIC_1164.ALL;
* use IEEE.STD_LOGIC_ARITH.ALL;
* use IEEE.STD_LOGIC_UNSIGNED.ALL;
* LIBRARY lpm; -- for LPM
* USE lpm.lpm_components.ALL;
* -- a mettre dans l'architecture --
* -- apres le begin --
* ic2: lpm_counter GENERIC MAP (
* LPM_WIDTH => 8
* PORT MAP (CLOCK => s_clk_slow,
* q(7 downto 4) => s_transcod1,
* q(3 downto 0) => s_transcod0);

### Compteur BCD sur deux digits

Nous cherchons maintenant à modifier le compteur de l'exercice précédent (exercice 2) pour qu'il affiche de 00 à 99 (et non plus de 00 à FF). En clair, à partir de maintenant chaque digit ne variera plus que de 0 à 9. C'est cela que l'on appelle BCD : Binary coded decimal en anglais ou DCB : Décimal codé binaire en français. On utilisera plus souvent la dénomination anglaise BCD pour ce type de données dans la suite des TPs.

#### Exercice 3

1°) Réaliser un compteur BCD 4 bits sur un seul digit.
2°) Rendre ce compteur BCD cascadable et le cascader pour fournir un compteur BCD sur 8 bits (deux digits).
* Indication : une aide pour réaliser un compteur BCD vous est présentée. Vous devez le modifier pour le rendre cascadable.
* library IEEE;
* use IEEE.STD_LOGIC_1164.ALL;
* use IEEE.STD_LOGIC_ARITH.ALL;
* use IEEE.STD_LOGIC_UNSIGNED.ALL;
* entity CounterBCD is
* port( EN: in std_logic;
* Clock: in std_logic;
* Reset: in std_logic;
* -- ENO : out std_logic;
* Output: out std_logic_vector(3 downto 0));
* end CounterBCD;
* architecture Behavioral of CounterBCD is
* signal cmpt: std_logic_vector(3 downto 0);
* begin process(Clock,Reset)
* begin
* if Reset='1' then
* cmpt <= "0000";
* elsif(rising_edge(Clock)) then
* if EN='1' then
* if cmpt="1001" then
* cmpt<="0000";
* else
* cmpt <= cmpt + 1;
* end if;
* end if;
* end if;
* end process;
* Output <= cmpt;
* end Behavioral;
* La réalisation de ENO étant combinatoire, on vous demande de le réaliser avec un with select when. En remarquant que ENO est à 1 si EN=1 et cmpt=9, il est possible de réaliser une concaténation du signal pour l'utiliser dans le with select when. Voici le tout en image :
* s_en_cmpt <= en & cmpt; -- operateur '&' est une concatenation
* with s_en_cmpt select
* ENO <= '1' when "?????",
* '0' when others;

#### Exercice 4 Compteur/décompteur BCD sur deux digits

Réaliser un compteur/décompteur BCD 4 bits. Prévoir les tests correspondants à partir du schéma de l'exercice 2.
Indication : une aide pour réaliser un compteur décompteur BCD cascadable peut être trouvée ici.

### Solutions générales du TP 5

Nous mettons ici un lien vers les corrigés qui se trouvent sur le WIKI de l'IUT de Troyes. Comme ces TPs sont effectivement réalisés par les étudiants de GEII, les solutions en question ne sont accessibles qu'en accès réservé sur une partie de l'année. Essayez le lien, il est librement accessible une quarantaine de semaines dans l'année voire plus si le TP est abandonné :
* Corrigé du TP5
Si l'accès vous est refusé, patientez et revenez quelques semaines plus tard.

## TP6 : Séquentiel (suite) et mémoires
### Fichier csv

Nous donnons le fichier de contraintes complet (pour réaliser ce TP) sous la forme d'un fichier csv :

### Le mécanisme du réveil

Dans la partie droite de la figure ci-dessus, vous pouvez apercevoir le diagramme d'évolution du réveil qui sera utilisé comme exemple par la suite.
Principe de fonctionnement du réveil : à partir de "Off", "key"=1 arme le réveil. Si "trip" passe à 1 (c'est-à-dire que l'heure courante devient égale à l'heure de réveil) le réveil passe en "ringing" et sonne. "trip" ne reste pas très longtemps à un (1 seconde). Son retour à 0 ne suffit pas à arrêter la sonnerie. Seul le passage de "key" à 0 peut l'arrêter.

#### Les graphes d'évolutions et le style « case when »

On rappelle encore une fois que le style « case when » permet de ne pas chercher les équations de récurrences. Mais comme nos diagrammes d'évolutions se sont compliqués (par l'ajout d'étiquettes sur les transitions), il nous faudra ajouter des "if then". Cela est tellement intuitif que nous passons directement aux exemples. Nous commençons par présenter partiellement le réveil.

#### Programmation sans initialisation

Le principe consiste à déclarer d'abord un type énuméré avec une définition symbolique de chacun des états (ici Armed, Off, Ringing) :
Ensuite dans un « case when » on détaillera toutes les transitions possibles comme montré ci-dessous dans le cas où l'on ne s'intéresse pas à une initialisation :
L'idée générale est donc d'utiliser un « case » sur les états avec des « if » pour gérer l'ensemble des transitions.

#### Exercice 1

Réaliser le réveil ci-dessus en n'oubliant pas de ralentir l'horloge du séquenceur pour éviter les problèmes de rebonds.
* Indications :
* Vous aurez deux boutons en entrée :
* un bouton d'armement du réveil appelé key dans le diagramme d'évolution
* un bouton simulant l'égalité entre heure réveil et heure courante appelé Trip dans le diagramme d'évolution
* Vous avez naturellement l'horloge en entrée qui peut être branchée sur la sortie d'un habituel compteur 24 bits que l'on peut trouver dans cette page (TP5 exo1).
* La sonnerie du réveil sera une simple LED

### Compteur à sortie sept segments avec mémoire

Nous allons utiliser un compteur normal, c'est-à-dire qui compte en binaire sur 4 bits suivi d'une mémoire pour le transcodage.
L'initialisation des mémoires du MAX10 nécessite une configuration particulière de la compilation :
* assignments-->device-->device and pin options -->configuration-->configuration mode :single uncompressed image with Memory Initialization (512Kbit) UFM
Le "smart compilation" ne peut pas être géré directement par l'IDE pour les FPGA de type MAX10 pour une raison inconnue de nous. Il vous faut le forcer en ajoutant dans le fichier .qsf la ligne :
* set_global_assignment -name SMART_RECOMPILE ON
La "smart compilation" dont il est question ici veut dire qu'un changement du contenu du fichier .mif ne provoque pas la recompilation globale. C'est beaucoup plus rapide pour tester des contenus de mémoire et pour mettre au point. Lors de la rédaction des correction, l'auteur n'a pas utilisé cette option.

#### Présentation de la lpm_rom

Pour les utiliser, il ne pas oublier les lignes
devant toute entité qui utilise ces mémoires.
L'idée générale est de remplir une ROM à l'aide d'un fichier extérieur. Son format est appelé MIF et il s'agit d'un fichier texte qui peut donc être fabriqué à la main quand la mémoire est de petite taille, ce qui est justement ce qui nous intéresse ici. Voici un fichier MIF d'exemple :
Si vous voulez utiliser cet exemple, il faut naturellement remplacer les ?? par des valeurs à calculer.
L'instanciation peut se faire par
Tout ceci sera mis dans l'architecture après le begin.

#### Exercice 2 Travail à réaliser (VHDL)

Calculer les valeurs hexadécimales contenues dans cette ROM pour réaliser le transcodage qui convient.
Reprendre le diviseur de fréquence par 2**24.
Assembler le tout.
* Indications : Partez du programme ci-dessous en complétant tous les points d'interrogations et les entités et architecture de ce qui manque, à savoir le compteur 24 bits et le compteur 4 bits.
* library IEEE;
* use IEEE.STD_LOGIC_1164.ALL;
* -- pour la mémoire
* LIBRARY lpm;
* USE lpm.lpm_components.ALL;
* entity top is port(
* clock_50 : in std_logic;
* hex0 : out std_logic_vector(6 downto 0));
* end top;
* architecture arch_top of top is
* COMPONENT cmpt4bits IS
* PORT(clk : IN STD_LOGIC;
* Q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
* END COMPONENT;
* COMPONENT cmpt24bits IS
* PORT(clk_50MHz : IN STD_LOGIC;
* clk_slow : OUT STD_LOGIC);
* END COMPONENT;
* SIGNAL s_clk_slow : std_logic;
* SIGNAL s_transcod : std_logic_vector(3 downto 0);
* begin
* lent: cmpt24bits port map(
* clk_50MHz => ????,
* clk_slow => ???);
* cmpt: cmpt4bits port map(
* clk => ????,
* Q => s_transcod);
* ic3 : lpm_rom GENERIC MAP (
* LPM_ADDRESS_CONTROL => "UNREGISTERED",
* LPM_FILE => "TP6exo2.mif",
* LPM_WIDTH => 8,
* LPM_WIDTHAD => 4)
* PORT MAP (
* outclock => clock_50,
* address => s_transcod,
* q(6 downto 0) => hex0
* end arch_top;

### Exercice 3 : Texte défilant

Donner le contenu de la RAM pour afficher le texte : "bonjour A touS" qui défile sur un afficheur.
Réaliser l'ensemble et tester. Faire constater.
* Indication : Il n'y a que très peu de choses à changer par rapport à l'exercice 2.

### Exercice 4 : Chenillard sur LEDs

1°) On reprend l'exercice précédent mais on sort maintenant sur 8 LEDs (schéma ci-contre). On vous demande de réaliser un chenillard aller et retour. Il faut donc changer le fichier csv et le contenu de la lpm_rom à l'aide du fichier MIF correspondant.
2°) DS 2014. Modifier seulement le contenu de la ROM pour réaliser le chenillard présenté dans le schéma. Faire constater.
* Indication : on utilisera encore une lpm_rom et non une RAM16X8 (Xilinx).

### Autre méthode pour utiliser des RAMs

Si vous voulez que votre outil de synthèse infère une RAM/ROM il vous faut écrire votre RAM/ROM avec un style spécifique. Nous présentons ici un exemple sur lequel nous nous appuierons dans la suite : ROM avec sortie Registered

#### Exercice 5 : Travail à réaliser

1°) En partant de l'exercice 2, on vous demande de modifier toute la partie mémoire : on n'utilisera plus la LPM_ROM mais une ROM décrite en VHDL comme ci-dessus. Assembler le tout, vérifier.
2°) En partant de l'exercice 3, on vous demande de modifier toute la partie mémoire : on n'utilisera plus la LPM_ROM mais une ROM décrite en VHDL comme ci-dessus. Assembler le tout, vérifier.
3°) Pouvez-vous imaginer une architecture qui fasse défiler le texte sur 6 digits.

### Exercice 6 : Barregraphe sur LEDs

On désire afficher une valeur de 0 (tout éteint) à 8 (tout allumé) sur les 8 LEDs. Toute valeur supérieure à 8 affichera 8 (effet de saturation).
* Expliquer quel type de mémoire doit-on choisir.
* Calculer son contenu et tester avec le même schéma que exo2.
* Implanter et tester en prenant un compteur qui compte de 0 à 8 seulement.
* On complique maintenant le compteur. Il devient un compteur/décompteur.

### Solutions générales du TP 6

Nous mettons ici un lien vers les corrigés qui se trouvent sur le WIKI de l'IUT de Troyes. Comme ces TPs sont effectivement réalisés par les étudiants de GEII, les solutions en question ne sont accessibles qu'en accès réservé sur une partie de l'année. Essayez le lien, il est librement accessible une quarantaine de semaines dans l'année voire plus si le TP est abandonné :
* Corrigé du TP6
Si l'accès vous est refusé, patientez et revenez quelques semaines plus tard.
La solution présentée ici utilise une lpm_rom.
Il y a plusieurs solutions possibles :
* ne pas garder les transcodeurs et sortir directement sur les afficheurs 7 segments. Cela nécessite une mémoire de 48 bits de large (6 afficheurs x 8 bits)
* garder l'idée des transcodeurs en changeant leur contenu.
Voici le contenu d'une ROM 16x48 pour faire défiler le texte :
Si vous voulez vérifier que vos données sont bien en mémoire, vous pouvez alors lire le rapport de compilation (Compilation report) et trouver une ligne comme :
Et voici maintenant le code source VHDL :

## Utilisation Basys2 avec ADEPT sous Linux

En principe, avec les versions modernes de l'ISE, c'est IMPACT qui se chargera de télécharger dans le FPGA. Si vous rencontrez des problèmes de téléchargement, ADEPT peut être utilisé en ligne de commande.
On utilisera la carte Basys 2 avec un SPARTAN 3E 250 (xc3s250e) dans un boîtier CP132.

### Commandes ADEPT et ISE

    Detectiondjtgcfg enum donne Basys2 come username Téléchargementdjtgcfg prog -d Basys2 --index 0 --file toto.bit <<<y Lancement ISE/opt/Xilinx/14.5/ISE_DS/ISE/bin/lin/ise &

## TP1 - Des Tables de vérité et VHDL aux simplifications (3 heures)

L'objectif de ce TP est de montrer qu'avec un FPGA la connaissance d'une table de vérité suffit pour réaliser un programme VHDL (sans les simplifier). Cependant, pour vous faire travailler les tableaux de Karnaugh, on vous demandera parfois de trouver les équations et de les implanter. À la fin de ce TP, vous serez capable
* d'établir une table de vérité
** d'en déduire immédiatement le programme VHDL correspondant
** ou de la transformer à l'aide d'un tableau de Karnaugh en une équation simplifiée et de l'implanter en VHDL
Tous ces allers et retours entre toutes ces formes (Table de vérité, Tableau de Karnaugh, équations) sont la base de l'apprentissage.

### Un exemple simple pour comprendre l'IDE Xilinx

Vous allez réaliser un simple OU en suivant un exemple complet réalisé par votre enseignant. L'objectif est d'apprendre :
* à réaliser un fichier VHDL, le sauver et l'ajouter au projet
* à réaliser un fichier de contrainte pour choisir les entrées et sorties, et l'ajouter au projet
* à compiler
* à charger le fichier dans votre FPGA avec IMPACT ou ADEPT
Voici les fichiers VHDL utilisés :
* à partir d'une table de vérité
* à partir d'une équation
Modifier cet exemple pour ajouter une sortie qui réalise un ET.

#### Fichier ucf utile pour Basys 2

Pour éviter de chercher nous donnons quelques contenus du fichier ucf :

### Exercice 1 : Analyse d'un schéma simple puis synthèse équivalente

On donne le schéma ci-contre.
1°) Plot the corresponding function in the truth table below and in the Karnaugh map. Find the simplified sum of product expression of s=f(e0,e1,e2).

#### Table de vérité

    EntréesSorties e2e1e0abs 000??? 001??? 010??? 011??? 100??? 101??? 110??? 111???
Remarque : a et b ne sont pas à proprement parler des sorties. Il s'agit de fils intermédiaires, mais il faut les calculer pour avoir s.
2°) Realize the corresponding simplified expression as a VHDL program with an equation.
3°) Realize the corresponding boolean function as a VHDL program with a with select when.

### Exercice 2 (Vote au directoire)

Le comité directeur d’une entreprise est constitué de quatre membres :
* le directeur D,
* ses trois adjoints A, B, C.
Lors des réunions, les décisions sont prises à la majorité.
Chaque personne dispose d’un interrupteur pour voter sur lequel elle appuie en cas d’accord avec le projet soumis au vote. En cas d'égalité du nombre de voix, celle du directeur compte double.
On vous demande de réaliser un dispositif logique permettant l’affichage du résultat du vote sur lampe V (pour nous ce sera une LED).
1°) Écrire une table de vérité pour la sortie V puis un tableau de Karnaugh
2°) Réaliser le programme VHDL pour la sortie V avec un with select when (autrement dit à partir de la table de vérité).
3°) Réaliser le programme VHDL pour la sortie V avec une équation (si possible simplifiée avec un tableau de Karnaugh).

### Exercice 3 (Vote au directoire amélioré)

Une société est composée de 4 actionnaires ayant les nombres suivants d'actions A=60, B=100, C=160 et D=180.
Nous désirons construire une machine à voter automatiquement, tenant compte dans le résultat du poids en actions de chaque personne. La machine dispose de 4 boutons poussoirs A, B, C, D et le résultat sera un voyant V qui s'allumera si la majorité pondérée appuie sur les boutons.
1°) Écrire une table de vérité pour la sortie V. Réaliser le programme VHDL correspondant et vérifier que vous avez la bonne table de vérité.
2°) Réaliser le programme VHDL avec un with select when. Remarquez l'apparition d'un WARNING.
3°) Pour comprendre le WARNING de la question précédente, on vous demande de trouver l'équation simplifiée. En l'examinant vous comprendrez quel est le problème. Puis réaliser le programme VHDL avec une équation logique pour la sortie V en supprimant le WARNING.

## TP2 - Des tables de vérités aux LUT4 (en VHDL)

Les LUT4 sont aux FPGA ce que les portes logiques sont aux schémas : des briques de base à assembler. Les portes logiques sont figées mais vous pouvez choisir celles qui vous intéressent. Pour les LUT4, ce sont des composants à 4 entrées qui sont universels : ils peuvent réaliser n'importe quelle fonction logique.

### Des tables de vérité à l'hexadécimal (cours sur LUTs)

Une table de vérité de trois entrées peut être représentée par un nombre 8 bits que l'on convertit en hexadécimal. Soit donc la table de vérité suivante (trois entrées notées e0, e1 et e2, une sortie notée s) :

#### Table de vérité

    EntréesSortiesbits e2e1e0s 0000b0 0011b1 0101b2 0110b3 1001b4 1010b5 1101b6 1110b7
Vous pouvez synthétiser la table de vérité à l'aide d'un seul nombre sur 8 bit (poids faible en haut) :
* en binaire ce nombre vaut : 0b01010110
* en hexadécimal ce nombre vaut : 0x56 (X"56" en VHDL)
La valeur hexadécimale 56 est la valeur qu'il vous faudra utiliser dans la partie INIT d'une (catégorie) LUT qu'il faudra câbler.
Combien de bits nécessite l'initialisation d'une lut4 à 4 entrées ? Combien de chiffres hexadécimaux ?

#### Utiliser des LUTs en VHDL

Un exemple est donné maintenant :
Cet exemple vous montre comment on câble une LUT4 en VHDL (port map) et comment on l'initialise (generic map). Le câblage de ce composant est correct mais pas son initialisation puisqu'on vous demande de la calculer plus loin.
Les deux lignes library ... et use ... sont à ajouter avant toute entité qui utilise une LUT en plus bien sûr de "library ieee;".

### Multiplieur de deux nombres de 2 bits
#### Exercise 1 (English)

Design and build a combinational logic circuit with four inputs and four outputs that multiplies two 2-bits numbers, labeled X, and Y. The output is labeled Z. Use a truth table and find out the corresponding with select when.
1°) Realize this boolean function with a "WITH SELECT WHEN"
2°) Then, realize the same function with four LUT4

### Transcodeur binaire 7 segments

Lire Afficheur 7 segments.
On va réaliser un transcodeur binaire décimal vers un afficheur 7 segments. L'objectif de ce TP est d'utiliser toutes les techniques classiques de synthèse combinatoire.

#### Présentation du sujet

Un schéma présente de manière symbolique ce que l'on cherche à faire.
sel est choisi à 0 pour sélectionner l'afficheur de gauche. La valeur binaire (de 0 à F) choisie sur les interrupteurs est convertie pour être affichée comme ci-contre.
Le fichier ucf pour les afficheurs 7 segments est présenté maintenant :

#### Exercice 2 : Transcodeur hexadécimal vers sept segments et « with select when »

1°) First complete the truth table below. Read the first line carefully before starting.

##### Table de vérité

    EntréesSorties sw3sw2sw1sw0abcdefg 00000000001 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
2°) Realize this truth table as circuit in VHDL (style "with select when").
3°) Faire la même réalisation en utilisant des LUT4.
Il serait bon de mettre de côté un programme solution de la question 2° ou celle de l'équation 3°. Vous en aurez besoin plus tard.

### Exercice 3 : Transcodeur pour dé

1°) Réaliser le transcodeur ci-contre avec les LEDs présentes sur la carte FPGA en utilisant un with select when. Ce que vous avez à réaliser est donc un circuit qui comporte 3 interrupteurs en entrée et 7 leds en sortie (voir schéma ci-contre).
2°) Faire le même travail avec 7 LUT4.
3°) En gardant ce que vous avez fait en question 2°, on vous demande d'y ajouter un affichage sur les sept segments en utilisant le programme de la question 2° ou 3° de l'exercice précédent (que l'on vous avez demandé de mettre de côté).
Malheureusement les tests ne seront pas facilités puisque les leds utilisées sont alignées... mais l'esprit humain peut contourner ce genre de détail.

## TP3 Arithmétique, comparateurs et multiplexeurs

L'arithmétique consiste à implanter des fonctions de base de l'arithmétique, c'est-à-dire addition, soustraction et multiplication. L'utilisation de l'arithmétique dans un FPGA doit suivre ses propres règles. Nous allons commencer par examiner l'addition, d'abord sans se préoccuper du fait que l'on utilise un FPGA, puis on cherchera à utiliser les composants Xilinx.

### Du demi-additionneur à l'additionneur 1 bit

Lire Additionneur dans Wikipédia.

### Exercice 1

1) Implanter un additionneur 1 bit avec deux LUTs. Pour les tests, les entrées seront reliées à des interrupteurs et les sorties à des LEDs.
2) Réaliser 4 fois le schéma précédent et montrer que l'on peut réaliser ainsi un additionneur 4 bits. N'oubliez pas que la somme de deux nombres de 4 bits peut donner un nombre de 5 bits. (Lire additionneur parallèle à propagation de retenue)

### Additionneur 4 bits

Après avoir réalisé un additionneur 4 bits, on vous propose l'exercice ci-dessous. L'additionneur 4 bits est nommé 7483 dans le schéma.

#### Exercice 2 (transcodeur BCD vers EXCESS- 3)

Code converter is a combinational circuit that translates the input code word into a new corresponding word. The excess-3 code digit is obtained by adding three to the corresponding BCD digit. To Construct a BCD-to-excess-3-code converter with a 4-bit adder feed BCD-code to the 4-bit adder as the first operand and then feed constant 3 as the second operand. The output is the corresponding excess-3 code.
Realize this circuit diagram in VHDL.
Indications :
* Un transcodeur comme celui demandé peut être réalisé avec 4 LUT4. Mais remarquez que celui qui est proposé dans le schéma est bidirectionnel.
* On pourrait utiliser le code ci-dessous pour l'additionneur 4 bits en lieu et place de celui qu'on a réalisé dans l'exercice 1 :
mais on vous demande plutôt d'utiliser la hiérarchie de l'exercice 1 pour obtenir une hiérarchie sur 3 niveau : le transcodeur qui contient un additionneur 4 bits qui contient 4 additionneurs 1 bit.
* La table de vérité du code excess-3 est :

##### Table de vérité du code EXCESS-3

    EntréesSorties B3B2B1B0E3E2E1E0 00000011 00010100 00100101 00110110 01000111 01011000 01101001 01111010 10001011 10011100 1010ΦΦΦΦ 1011ΦΦΦΦ 1100ΦΦΦΦ 1101ΦΦΦΦ 1110ΦΦΦΦ 1111ΦΦΦΦ

### Exercice 3
#### Première partie

Réaliser une comparaison seule (figure ci-contre en remplaçant le "neuf" par des interrupteurs). Réaliser le fichier ucf pour utiliser sw7 ... sw0 en entrée et led0 en sortie (pour GT seulement). Tester.
Indication : Le comparateur COMPM4 présent dans cet exercice peut être réalisé par le code VHDL :
Pour bien comprendre ce code, il vous est demandé de remplacer les entrées par deux entrées a et b en std_logic_vector( 3 downto 0)

#### Deuxième partie

Puis fixer les entrées Bi à 9 pour en faire une fonction de 4 entrées A3,A2,A1,A0 comme dans la figure. Remplir une table de vérité puis un tableau de Karnaugh.

##### Table de vérité du comparateur à 9

    EntréesSorties A3A2A1A0GT 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
Table de Karnaugh :
* S
* A3 A2
* 00
* 01
* 11
* 10
1°) Déduire de la table de vérité une LUT4 réalisant l'ensemble. La câbler puis l'essayer dans le FPGA. Faire constater à l'enseignant.
2°) Déduire du tableau de Karnaugh une équation simplifiée que l'on implantera en VHDL.

### Exercice 4 : additionneur complet (1 bit) et multiplexeur

Implement a full 1-bit adder
(a) using two 8-to-1 MUXes. Connect X,Y, and Cin in to the control inputs of the MUXes and connect 1 or 0 to each data input.
(b) using two 4-to-1 MUXes and one inverter. Connect X and Y to the control inputs of the MUXes, and connect 1’s, 0’s, Cin in , or Cin′ in to each data input.
(c) again using two 4-to-1 MUXes, but this time connect Cin in and Y to the control inputs of the MUXes, and connect 1’s, 0’s, X, or X′ to each data input. Note that in this fashion, any N-variable logic function may be implemented using a 2 (N−1) to-1 MUX.

#### Indication

Ce travail nécessite de réaliser un assemblage de circuits donc se fait avec des PORT MAP.
Voici le code de départ d'un multiplexeur 8 vers 1.

## TP4 Introduction au séquentiel (3 heures)
### Besoin d'une horloge pour dépasser le combinatoire

Les compteurs permettent de diminuer la fréquence d'horloge.

#### Exercice 1

Vous disposez d'une horloge 50MHz en broche "B8" de votre composant FPGA SPARTAN 3E. Réaliser à l'aide d'un compteur 24 bits une horloge d'environ 3 Hz. Sortie sur une LED, le clignotement de celle-ci doit être visible à l'œil.
Indications
* Un exemple de compteur est donné ci-dessous. Il s'agit d'un compteur 8 bits. Vous devez donc l'adapter pour l'exercice 1 :
** Changer le nom de l'entité, cmpt8bits ne correspondra plus à la fonction réalisée. cmpt24bits serait plus adapté
** diminuer la taille de la sortie qui passe de 8 bits à un bit et l'appeler clk_slow par exemple
** augmenter la taille du compteur qui passe de 8 bits à 24 bits
** changer la toute dernière équation
* Le fichier ucf est :
L'horloge que l'on vient de réaliser sera utilisée presque systématiquement par la suite. Il faut donc sauvegarder à tout prix ce fichier source.
Par abus de langage on appellera compteur dans la suite un élément séquentiel qui comporte une horloge mais qui ne compte pas forcément en binaire. Dans ce dernier cas, son équation de récurrence ne peut donc pas s'écrire simplement à l'aide d'une addition.

### Réaliser un graphe d'évolution simple

Avant toute chose, il nous faut nous demander comment utiliser des équations de récurrences booléennes. On vous représente ci-après la façon de procéder :
* trouver le diagramme d'évolution
* en déduire le tableau état présent/état futur
* en déduire les équations en utilisant éventuellement un tableau de Karnaugh
Lisez Des diagrammes d'évolutions aux équations de récurrences pour la partie théorique. Vous y trouverez les équations de récurrences nécessaires à la réalisation de l'exercice 2.

#### Exercice 2

1°) Realize the system specified above with a state diagram. The clock is, as usual, "clk_slow" (see l'exercise 1). Add two LEDs as outputs to be able to check your VHDL program.
2°) Design a modulo-4 counter with an input D, for Down. When D is not asserted, the counter counts up, modulo-4. When D is asserted (1), the counter counts down, modulo-4. Draw a state diagram to implement it and derive the state table. Then design a complete sequential circuit using VHDL. Please use a 7 segments display to check your VHDL code.
Indication : Si vous voulez avoir une chance de voir les LEDs défiler, vous devez utiliser le compteur de l'exercice 1 pour faire une horloge lente et l'utiliser comme entrée horloge de ce qui vous est demandé. Il y a donc du PORT MAP dans l'air.

### Compteur décimal à sortie directe sept segments (1 digit en VHDL)

Le compteur sept segments est réalisé en VHDL et sera assemblé avec le dispositif destiné à réaliser l'horloge lente : compteur 24 bits de l'exercice 1.

#### Exercice 3

1°) Écrire les équations logiques a+, b+, c+, d+ ,e+, f+, g+ en fonction des entrées a, b, c, d, e, f, g. Implanter en VHDL.
Il nous reste un problème important à résoudre, c'est l'initialisation. En effet pour bien faire il faudrait étudier les 127-10=117 états restants pour voir comment ils se connectent sur notre cycle. C'est un travail important qu'il est impossible de réaliser à moins d'y passer 117 soirées (à raison d'une transition par soirée) soit presque 4 mois !!!
Pour éviter cela on va prévoir une entrée d'initialisation appelée Init au cas où à la mise sous tension on se trouve dans un état non prévu. Cette entrée fonctionnera de manière synchrone, lorsqu'elle sera à 1 un front d'horloge provoquera l'affichage du 0 en sortie du compteur.
2°) Écrire maintenant les équations de récurrence trouvées en 1°) en ajoutant convenablement l'entrée Init.

#### Exercice 4

Refaire le même travail que l'exo4 en utilisant un case when et toujours "clk_slow" comme horloge.
Remarquez l'utilisation du STD_LOGIC_VECTOR au lieu des sorties individuelles. Le fait qu'il soit en OUT implique que l'on utilisera un signal interne pour les "CASE".
Indication : Implanter un diagramme d'évolution en VHDL peut se faire de manière systématique :
* library ieee;
* use ieee.std_logic_1164.all;
* ENTITY demo IS PORT(
* clock : IN std_logic;
* q : OUT std_logic_VECTOR(1 DOWNTO 0));
* END demo;
* ARCHITECTURE mydemo OF demo IS
* SIGNAL q1q0 : std_logic_vector(1 downto 0);
* BEGIN
* PROCESS(clock) BEGIN
* IF clock'EVENT AND clock='1' THEN
* CASE q1q0 IS --style case when
* WHEN "00" => q1q0 <="01";
* WHEN "01" => q1q0 <="10";
* WHEN "10" => q1q0 <="11";
* WHEN OTHERS => q1q0 <="00" ;
* END CASE;
* END IF;
* END PROCESS;
* q <= q1q0;
* END mydemo;

## TP5 M1102 : VHDL et Compteurs
### Exercice 1

Cet exercice ne sera réalisé que par les étudiants qui ne sont pas allés jusqu'au bout du TP 4.
Nous vous donnons deux composants VHDL et on vous demande d'en réaliser un assemblage.
On vous donne les deux composants VHDL suivants. On vous demande de les assembler (en complétant les transitions de « cmpt7seg » ) dans un programme TOP.
Nous allons reprendre le problème du compteur sept segments mais de façon plus normale.

### Compteur à sortie sept segments sur deux digits en VHDL

Cette partie doit être réalisée avec les afficheurs sept segments reliés à la carte.
Nous allons réaliser cet exercice en plusieurs étapes.

#### Exercice 2

Nous désirons implanter un ensemble composé d'un compteur 8 bits et sortant sa valeur sur deux afficheurs sept segments ( affichage de 00 à FF)...
Attention, le poids faible doit être à droite !!!
1°) Réaliser d'abord un compteur simple 8 bit associé à une division par 2**24 et sortant directement sur des LEDs. La seule entrée est clk qui se trouve en "B8" sur le FPGA. Les 8 sorties sont reliées aux 8 LEDs de la carte. Remarquez que le seul compteur qui nous intéresse est le compteur 8 bits de droite, l'autre étant là pour ralentir l'horloge.
2°) Réaliser maintenant l'affichage des 4 bits de poids faibles sur un seul afficheur.
3°) Réaliser maintenant l'affichage des 8 bits du compteur sur deux afficheurs. La figure donne en principe ce que l'on cherche à faire et l'idéal serait de la comprendre.
Indications :
* Vous devriez avoir sauvegardé depuis longtemps le transcodeur :
* le multiplexeur peut être réalisé par :
que vous compléterez pour en faire une architecture puis ajouterez une entité.
* les sorties an sont gérées avec des équations

### Compteur BCD sur deux digits

Nous cherchons maintenant à modifier le compteur de l'exercice précédent (exercice 2) pour qu'il affiche de 00 à 99.

#### Exercice 3

Réaliser un compteur BCD 4 bits cascadable. Il sera ensuite cascadé pour fournir un compteur BCD sur 8 bits (deux digits).
Indication : une aide pour réaliser un compteur BCD vous est présentée. Vous devez le modifier pour le rendre cascadable.
La réalisation de ENO étant combinatoire, on vous demande de le réaliser avec un with select when. En remarquant que ENO est à 1 si EN=1 et cmpt=9, il est possible de réaliser une concaténation du signal pour l'utiliser dans le with select when. Voici le tout en image :

#### Exercice 4 Compteur/décompteur BCD sur deux digits

Réaliser un compteur/décompteur BCD 4 bits. Prévoir les tests correspondants à partir du schéma de l'exercice 2.
Indications :
* une aide pour réaliser un compteur décompteur BCD cascadable peut être trouvée ici.
* la documentation des LPM peut être trouvée ici. Cherchez la section lpm_counter.

## TP6 : Mémoires
### Le réveil

Dans la partie droite de la figure ci-dessus, vous pouvez apercevoir le diagramme d'évolution du réveil qui sera utilisé comme exemple par la suite.
Principe de fonctionnement du réveil : à partir de "Off", "key"=1 arme le réveil. Si "trip" passe à 1 (c'est-à-dire que l'heure courante devient égale à l'heure de réveil) le réveil passe en "ringing" et sonne. "trip" ne reste pas très longtemps à un (1 seconde). Son retour à 0 ne suffit pas à arrêter la sonnerie. Seul le passage de "key" à 0 peut l'arrêter.

#### Les graphes d'évolutions et le style « case when »

On rappelle encore une fois que le style « case when » permet de ne pas chercher les équations de récurrences. Mais comme nos diagrammes d'évolutions se sont compliqués (par l'ajout d'étiquettes sur les transitions), il nous faudra ajouter des "if then". Cela est tellement intuitif que nous passons directement aux exemples. Nous commençons par présenter partiellement le réveil.

#### Programmation sans initialisation

Le principe consiste à déclarer d'abord un type énuméré avec une définition symbolique de chacun des états (ici Armed, Off, Ringing) :
Ensuite dans un « case when » on détaillera toutes les transitions possibles comme montré ci-dessous dans le cas où l'on ne s'intéresse pas à une initialisation :
L'idée générale est donc d'utiliser un « case » sur les états avec des « if » pour gérer l'ensemble des transitions.

#### Exercice 1

Réaliser le réveil ci-dessus en n'oubliant pas de ralentir l'horloge du séquenceur pour éviter les problèmes de rebonds.
Indications :
* Vous aurez deux boutons en entrée :
** un bouton d'armement du réveil appelé key dans le diagramme d'évolution
** un bouton simulant l'égalité entre heure réveil et heure courante appelé Trip dans le diagramme d'évolution
* Vous avez naturellement l'horloge en entrée qui peut être branchée sur la sortie d'un habituel compteur 24 bits que l'on peut trouver dans cette page.
* La sonnerie du réveil sera une simple LED

### Compteur à sortie sept segments avec mémoire

Nous allons utiliser un compteur normal, c'est-à-dire qui compte en binaire sur 4 bits suivi d'une mémoire pour le transcodage.

#### Présentation des RAM16X8S

Pour les utiliser, il ne pas oublier les lignes
devant toute entité qui utilise ces mémoires.
Le composant correspondant est (donné ici pour information) :
Il n'est pas à déclarer puisque c'est justement les deux lignes qu'on a rajouté qui le fait. Par contre toute utilisation nécessite un "PORT MAP" précédé par un "GENERIC MAP".

#### Exercice 2 Travail à réaliser (VHDL)

Calculer les valeurs hexadécimales contenues dans cette ROM RAM16X8S pour réaliser le transcodage qui convient.
Reprendre le diviseur de fréquence par 2**24.
Assembler le tout.
Indications : Partez du programme ci-dessous en complétant tous les points d'interrogations et les entités et architecture de ce qui manque, à savoir le compteur 24 bits et le compteur 4 bits.

### Exercice 3 : Texte défilant

Donner le contenu de la RAM pour afficher le texte : "bonjour A touS" qui défile sur un afficheur.
Réaliser l'ensemble et tester. Faire constater.
Indication : Il n'y a que très peu de choses à changer par rapport à l'exercice 2.

### Exercice 4 : Chenillard sur LEDs

1°) On reprend l'exercice précédent mais on sort maintenant sur 8 LEDs (schéma ci-contre). On vous demande de réaliser un chenillard aller et retour. Il faut donc changer le fichier ucf et le contenu de la RAM16X8S.
2°) DS 2014. Les sorties précédentes sont maintenant utilisées comme adresses d'une RAM16x8s comme dans la figure ci-contre. Donner le contenu de la RAM pour afficher le chenillard ci-contre. Réaliser l'ensemble et tester. Faire constater.

### Autre méthode pour utiliser des RAMs

Si vous voulez que votre outil de synthèse infère une RAM/ROM il vous faut écrire votre RAM/ROM avec un style spécifique. Nous présentons ici un exemple sur lequel nous nous appuierons dans la suite : ROM avec sortie Registered

#### Exercice 5 : Travail à réaliser

1°) En partant de l'exercice 2, on vous demande de modifier toute la partie mémoire : on n'utilisera plus la RAM16X8S mais une ROM décrit en VHDL comme ci-dessus. Assembler le tout, vérifier.
2°) En partant de l'exercice 3, on vous demande de modifier toute la partie mémoire : on n'utilisera plus la RAM16X8S mais une ROM décrit en VHDL comme ci-dessus. Assembler le tout, vérifier.
3°) Pouvez-vous imaginer une architecture qui fasse défiler le texte sur 4 digits.

### Exercice 6 : Barregraphe sur LEDs

On désire afficher une valeur de 0 (tout éteint) à 8 (tout allumé) sur les 8 LEDs. Toute valeur supérieure à 8 affichera 8 (effet de saturation).
* Expliquer pourquoi on doit prendre une RAM16X8S.
* Calculer son contenu et tester avec le même schéma que exo2.
* Implanter et tester en prenant un compteur qui compte de 0 à 8 seulement.
* On complique maintenant le compteur. Il devient un compteur/décompteur.
| Sommaire | TP 2 |