Cours:TP printempsM4209

De troyesGEII
Aller à : navigation, rechercher

Introduction

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7.

Le compteur de passages est évoqué dans un autre livre : Compteur de passages revu et corrigé. Il sera le fil conducteur de ce TP.

Nous allons, dans cette série de TPs, d'abord implanter complètement un compteur de passages sous forme de fonctions logiques exprimées en langage VHDL, donc sans processeur. Ensuite nous allons implanter dans le FPGA le même compteur de passage, mais réalisé via l'exécution d'un programme C par un processeur seul, sans périphérique matériel particulier. Pour terminer cette série, nous allons d'abord déporter le transcodage, hors du processeur pour le réaliser par des fonctions logiques décrites en VHDL. Puis pour finir, nous déporterons l'ensemble compteurs BCD et transcodeurs vers la réalisation matérielle via le langage VHDL.

L'objectif de ce travail est donc, pour des exemples relativement simples, de bien comprendre les relations entre la partie matérielle (description de fonctions par le langage VHDL) et la partie logicielle ( réalisation de fonctions par l'exécution d'un programme C par un processeur), lorsque ces 2 parties concourent à l'implantation de l'application complète. Cette coopération du matérielle et du logiciel pour une application s'appelle le co-design.

TP 1 (1h30)

Corrigé uniquement accessible aux enseignants

Exercice 1

On vous demande simplement de réaliser un transcodeur pour afficher tout nombre sur 4 bits (entrée) sur un afficheur 7 segments.

Indication 1

Vous devez réaliser l'architecture correspondante pour l'entité VHDL suivante :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les LEDs
entity transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end transcod7segs;

Si le nom des entrées sorties ne vous convient pas, changez-les et assumez ces changements lors des nombreux câblages de ce transcodeurs. Tous nos schémas gardent cette convention de noms, à commencer par le fichier de contraintes que nous donnons maintenant.

Indication 2

Le fichier de contraintes sera :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
Q_7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Q_7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Q_7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Q_7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Q_7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Q_7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Q_7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,

I_in4[3],Input,PIN_AD27,5,B5_N2,2.5 V,
I_in4[2],Input,PIN_AC27,5,B5_N2,2.5 V,
I_in4[1],Input,PIN_AC28,5,B5_N2,2.5 V,
I_in4[0],Input,PIN_AB28,5,B5_N1,2.5 V,

L'enseignant vous expliquera comment trouver ces contraintes avec la documentation de la carte.

Exercice 2

Réaliser la même chose avec deux afficheurs. On aura donc maintenant 8 entrées et 14 sorties. On vous demande cette réalisation avec deux composants correspondant à l'exercice 1 (transcodeurs)

Deux transcodeurs sept segments

Le fichier de contraintes sera :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
Unit7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Unit7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Unit7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Unit7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Unit7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Unit7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Unit7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,
Diz7segs[6],Output,PIN_U24,5,B5_N0,2.5 V,
Diz7segs[5],Output,PIN_U23,5,B5_N1,2.5 V,
Diz7segs[4],Output,PIN_W25,5,B5_N1,2.5 V,
Diz7segs[3],Output,PIN_W22,5,B5_N0,2.5 V,
Diz7segs[2],Output,PIN_W21,5,B5_N1,2.5 V,
Diz7segs[1],Output,PIN_Y22,5,B5_N0,2.5 V,
Diz7segs[0],Output,PIN_M24,6,B6_N2,2.5 V,

sw[7],Input,PIN_AB26,5,B5_N1,2.5 V,
sw[6],Input,PIN_AD26,5,B5_N2,2.5 V,
sw[5],Input,PIN_AC26,5,B5_N2,2.5 V,
sw[4],Input,PIN_AB27,5,B5_N1,2.5 V,
sw[3],Input,PIN_AD27,5,B5_N2,2.5 V,
sw[2],Input,PIN_AC27,5,B5_N2,2.5 V,
sw[1],Input,PIN_AC28,5,B5_N2,2.5 V,
sw[0],Input,PIN_AB28,5,B5_N1,2.5 V,

TP 2 (1h30)

Corrigé uniquement accessible aux enseignants

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7.

Exercice 1

En vous aidant du compteur décompteur décimal présenté ici, on vous demande de compléter le code pour faire un compteur décimal cascadable.

Exercice 2

Le compteur cascadable de l'exercice 1 doit être testé. Pour cela vous devez lui envoyer une horloge lente. Vous allez donc assembler :

  • un compteur destiné à réaliser une horloge lente (division par 2**24)
  • deux compteurs décompteurs décimaux cascadés
  • deux transcodeurs
Test des compteurs BCD cascadés

Le fichier de contraintes sera :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
clk,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
Init,Input,PIN_Y23,5,B5_N2,2.5 V,
Unit7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Unit7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Unit7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Unit7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Unit7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Unit7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Unit7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,
Diz7segs[6],Output,PIN_U24,5,B5_N0,2.5 V,
Diz7segs[5],Output,PIN_U23,5,B5_N1,2.5 V,
Diz7segs[4],Output,PIN_W25,5,B5_N1,2.5 V,
Diz7segs[3],Output,PIN_W22,5,B5_N0,2.5 V,
Diz7segs[2],Output,PIN_W21,5,B5_N1,2.5 V,
Diz7segs[1],Output,PIN_Y22,5,B5_N0,2.5 V,
Diz7segs[0],Output,PIN_M24,6,B6_N2,2.5 V,
DownUp,Input,PIN_AC28,5,B5_N2,2.5 V,
en,Input,PIN_AB28,5,B5_N1,2.5 V,

Ce fichier de contraintes correspond à "en" interrupteur complètement à droite, "DownUp" juste à côté et "Init" complètement à gauche.

TP 3 (1h30)

Corrigé uniquement accessible aux enseignants

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7.

Le compteur de passages comporte deux entrées capteurs notés CapteurDroit et CapteurGauche qui sont supposés détecter un passage. Pour nous ce sera deux interrupteurs. L'objectif du montage est de compter le nombre de personnes dans une pièce (à une seule entrée) ou de voitures dans un parking (lui aussi à une entrée). On considère donc que lorsqu'on passe devant un capteur puis devant l'autre on entre dans la pièce (ou dans le parking) et lorsque les choses se passent dans l'autre sens on sort. Un séquenceur devra être couplé à un compteur décompteur pour réaliser ce cahier des charges.

Exercice 1

Séquenceur du compteur de passages

Réaliser le séquenceur en complétant le code correspondant trouvé ICI dans un autre livre. Vous allez ensuite assembler :

  • un compteur destiné à réaliser une horloge lente (division par 2**20) : ce sera l'horloge générale
  • un séquenceur
  • deux compteurs décompteurs décimaux cascadés
  • deux transcodeurs

Le fichier de contrainte sera :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
clk_50MHz,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
Init,Input,PIN_Y23,5,B5_N2,2.5 V,
Unit7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Unit7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Unit7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Unit7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Unit7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Unit7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Unit7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,
Diz7segs[6],Output,PIN_U24,5,B5_N0,2.5 V,
Diz7segs[5],Output,PIN_U23,5,B5_N1,2.5 V,
Diz7segs[4],Output,PIN_W25,5,B5_N1,2.5 V,
Diz7segs[3],Output,PIN_W22,5,B5_N0,2.5 V,
Diz7segs[2],Output,PIN_W21,5,B5_N1,2.5 V,
Diz7segs[1],Output,PIN_Y22,5,B5_N0,2.5 V,
Diz7segs[0],Output,PIN_M24,6,B6_N2,2.5 V,
CapteurGauche,Input,PIN_AC28,5,B5_N2,2.5 V,
CapteurDroit,Input,PIN_AB28,5,B5_N1,2.5 V,

CapteurDroit est l'interrupteur complètement à droite, CapteurGauche est juste à côté tandis que Init est complètement à gauche.

Voici en schéma ce que vous devez réaliser.

Aperçu général du compteur de passages

Remarque : Notez que ce séquenceur suppose qu'il n'est pas possible d'avoir en même temps capteurGauche et capteurDroit. Si ce n'est pas le cas, il serait bon d'ajouter un état sur chaque branche.

Exercice 2

Changer le séquenceur pour laisser la possibilité de réaliser un demi-tour.

TP 4 (1h30)

Corrigé uniquement accessible aux enseignants

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7. Nous mettons la ressource complète sur notre site : M4209TinyStart.zip.

Vous allez maintenant réaliser vos premiers programmes en C destinés à un processeur dans le FPGA. Le code source complet du processeur vous est donné. Vous allez donc réaliser un projet pour compiler ce processeur. Cette compilation peut être assez longue (près de 10 mn) mais la simple mise en RAM/ROM du programme ne prendra que 2 mn une fois cette première compilation réalisée. Voici comment ceci est réalisé.

Pour la mise à jour du contenu de la mémoire seulement, sans passer par un temps de recompilation complet de l'application, il faut valider l'option "use smart compilation". Pour y accéder : menu assignements => settings => compilation process settings => puis cocher l'option "use smart compilation", ne pas oublier de faire "apply" avant de quitter la fenêtre !

Voici sous forme schématique l'ensemble du processeur.

Aperçu fonctionnel de notre SOC (Tiny861) au départ

Ressources

Andreas Hilvarsson a écrit ce cœur ATTiny861 et l'a publié chez Opencores.org. Nous avons modifié sa façon d'y créer des périphériques et en particulier retiré tous les PORTs bidirectionnels qui ne servent à rien dans un FPGA.

Remarque : Nous mettons la ressource complète sur notre site : M4209TinyStart.zip.

Pour information

Pour information la réalisation des périphériques en sortie a été réalisée comme dans la figure ci-contre. Rappelez-vous que la réalisation de périphérique de sortie se fait dans le fichier microcontroleur.vhd et dans le process iowr... et que c'est ce qui est montré dans cette figure.

Périphériques au départ du TP

Exercices

Voici un exemple de programme C :

#include "avr/io.h"
#undef F_CPU 
#define F_CPU 15000000UL
#include "util/delay.h"

//#define UCSRB	_SFR_IO8(0x01) 
//#define UCSRA	_SFR_IO8(0x02) 
//#define UDR	_SFR_IO8(0x03)
// UCSRA
//#define RXC 7
//#define TXC 6
//#define UDRE 5
//UCSRB
//#define RXEN 4
//#define TXEN 3


//***********************************************************************
// main 
//*********************************************************************** 

 int main (void) {
   unsigned char ch=128; 
   while(1) { 
   // echo simple
     PORTA = ch;
     ch >>= 1; 
     if (ch == 0) ch = 128;
     _delay_ms(300); // on défiler les valeurs     
   } 
   return 0; 
 }

Repérez dans ce code comment ne pas aller trop vite, comment décaler une valeur, comment sortir sur les leds....

Indication : Pour la mise à jour du contenu de la mémoire seulement, sans passer par un temps de recompilation complet de l'application (donc plus ou moins équivalent à data2mem), il faut valider l'option "use smart compilation". Pour y accéder : menu assignements => settings => compilation process settings => puis cocher l'option . ne pas oublier de faire "apply" avant de quitter la fenêtre !

Exercice 1

Vous allez réaliser divers chenillards dans un premier temps :

  • chenillard gauche droite (très facile non ?)
  • chenillard droite gauche
  • chenillard droite et gauche simultanés
  • chenillard à accumulation

Exercice 2

On vous donne deux sous-programmes facilitant cet exercice :

void incrementBCD(unsigned char *cnt) { 
  (*cnt)++;    
  if ((*cnt & 0x0F) > 0x09) *cnt += 6; 
  if ((*cnt & 0xF0) > 0x90) *cnt = 0; 
} 

void decrementBCD(unsigned char *cnt) { 
  (*cnt)--;    
  if ((*cnt & 0x0F) == 0x0F) *cnt -= 6; 
  if ((*cnt & 0xF0) == 0xF0) *cnt = 0x99; 
}

ainsi qu'un tableau de valeurs précalculées

const unsigned char digit7segs[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};

Vous allez réaliser divers compteurs et utiliser le ou les afficheurs sept segments.

  • compteur binaire assez lent pour que l'affichage se fasse correctement en hexadécimal sur deux digits
  • compteur décimal sur deux digits

Notez que c'est à vous, programmeur, de réaliser le transcodage. Un moyen simple de faire cela est d'utiliser un tableau. Ce n'est peut être pas un hasard si l'on vous a donné un tableau.

Exercice 3

Réaliser le compteur de passages. On vous demande de repérer dans le code ci-dessous la réalisation du séquenceur.

#include "avr/io.h"
#undef F_CPU 
#define F_CPU 15000000UL
#include "util/delay.h"

//#define UCSRB	_SFR_IO8(0x01) 
//#define UCSRA	_SFR_IO8(0x02) 
//#define UDR	_SFR_IO8(0x03)
// UCSRA
//#define RXC 7
//#define TXC 6
//#define UDRE 5
//UCSRB
//#define RXEN 4
//#define TXEN 3

//const unsigned char digit7segs[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; 
void incrementBCD(unsigned char *cnt);
void decrementBCD(unsigned char *cnt);
//***********************************************************************
// main 
//*********************************************************************** 

 int main (void) {
   //unsigned char transcod7segs[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0xFF,0x00};
   unsigned char transcod7segs[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

   unsigned char cmpt=0,ch=128,swPresent=0,swPasse=0,etat=1; 
   while(1) { 
   // compteur simple
     PORTB = transcod7segs[cmpt&0x0F];
     DDRB = transcod7segs[(cmpt&0xF0)>>4];
     swPresent = PINA;
     switch (etat) {
        case 0x01 : if (((swPresent & 0x03)==0x01) && ((swPasse & 0x01)==0x00)) {etat = 0x02;break;}
                    if (((swPresent & 0x03)==0x02) && ((swPasse & 0x02)==0x00)) {etat = 0x08;break;}    
        case 0x02 : if (((swPresent & 0x03)==0x02) && ((swPasse & 0x02)==0x00)) etat = 0x04;break;
        case 0x04 : etat = 0x01; break;        
        case 0x08 : if (((swPresent & 0x03)==0x01) && ((swPasse & 0x01)==0x00)) etat = 0x10;break;
        case 0x10 : etat = 0x01; break;
        default : etat = 0x01;
      }
      if (etat==0x04) incrementBCD(&cmpt);
      if (etat==0x10) decrementBCD(&cmpt);
      swPasse = swPresent;
     PORTA = ch;
     ch >>= 1; 
     if (ch == 0) ch = 128;
     _delay_ms(300); // on verra passer les caractères     
   } 
   return 0; 
 }

void incrementBCD(unsigned char *cnt) { 
  (*cnt)++;    
  if ((*cnt & 0x0F) > 0x09) *cnt += 6; 
  if ((*cnt & 0xF0) > 0x90) *cnt = 0; 
} 

void decrementBCD(unsigned char *cnt) { 
  (*cnt)--;    
  if ((*cnt & 0x0F) == 0x0F) *cnt -= 6; 
  if ((*cnt & 0xF0) == 0xF0) *cnt = 0x99; 
}

Modifier ce code pour être plus conforme au séquenceur du TP3 (7 états contre 5 ici).

TP 5 (1h30)

Corrigé uniquement accessible aux enseignants

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7. Nous mettons la ressource complète sur notre site : M4209TinyStart.zip.

Nous allons déporter les transcodeurs maintenant comme le montre la figure ci-dessous.

Périphériques en écriture : deux transcodeurs sept segments

Vous devez remarquer sur cette figure que maintenant le PORTB (8 bits) permet de commander deux afficheurs sept segments. Votre seul problème maintenant est de réaliser un compteur BCD sur 8 bits et de sortir sa valeur dans PORTB.

Exercice 1

Réaliser la partie matérielle dans microcontroleur.vhd en ajoutant les deux transcodeurs.

Exercice 2

Réaliser un compteur BCD qui compte ou décompte en fonction d'une entrée sur un switch. Evidemment ce que l'on vous demande de faire ici, c'est un programme C qui sera compilé et chargé dans le processeur.

Exercice 3

Refaire le compteur de passages correctement. Inspirez-vous de ce que vous venez de faire dans l'exercice précédent et du compteur de passages du TP précédent.

TP 6 (1h30)

Corrigé uniquement accessible aux enseignants

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7. Nous mettons la ressource complète sur notre site : M4209TinyStart.zip.

Nous arrivons maintenant au terme de notre série de TPs. Notre objectif maintenant est d'ajouter les deux compteurs BCD comme périphériques. Ils attaqueront les deux transcodeurs qui seront chargés de l'affichage.

Périphériques : deux compteurs BCD et deux transcodeurs

A partir de maintenant, fini les calculs d'additions et de soustractions BCD en C. C'est le matériel qui fera tout.

Il y a plusieurs possibilités pour réaliser cela. Nous avons choisi de réaliser cela de la manière suivante :

  • le processeur est incapable de mettre une valeur particulière dans les deux compteurs BCD
  • pour incrémenter le processeur écrit '1' dans le PORTB
  • pour décrémenter, le processeur écrit '0' dans le PORTB

Exercice 1

  • Réaliser la partie matérielle correspondant à la figure.
  • Modifier et tester le programme du compteur de passages

Remarque : La compréhension de la présence de la bascule D n'est pas forcément très facile à appréhender. Elle est liée au fait que le bit de poids faible de PORTB sert à changer l'entrée UD (choix comptage ou décomptage) des deux compteurs. Si en même temps on valide avec 'en' et bien on aura toujours un temps de retard. En retardant, on positionne d'abord 'UD' puis on valide le comptage ou le décomptage.

Exercice 2

Modifier, pour terminer, la partie matérielle pour que la lecture par le processeur des deux compteurs BCD soit possible. Réaliser maintenant un programme pour tester. Une idée possible est d'afficher la valeur lue sur les LEDs du PORTA qui ne sont pas utilisées.

TP 7 (1h30)

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7. Nous mettons la ressource complète sur notre site : M4209TinyStart.zip.

Exercice 1

1°) A partir de la correction du TP 6, on vous demande montrer que vous êtes capables de :

  • faire un projet à partir de la ressource M4209TinyStart.zip fournie
  • mettre au bon endroit le programme C donné dans la correction
  • le transformer en fichier .mif
  • compiler la partie matérielle en remplaçant le microcontroleur.vhd de la ressource par celui de la correction du TP 6
  • faire le test qui montre que l'on a bien un compteur de passages

2°) Vous allez maintenant ajouter 8 leds en supplément dans votre microcontrôleur pour réaliser un chenillard sur 16 leds. Elles seront reliées à DDRB qui n'est plus utilisé. Montrer que vous êtes capable de rajouter une sortie sur 8 bits comme indiqué dans le schéma ci-dessous :

Ajout d'un PORT pour utiliser 8 LEDs supplémentaires

Comme d'habitude, ce que vous avez à réaliser est indiqué en rouge. Tout ce qui est en noir est déjà réalisé dans la correction que vous avez déjà utilisé. Le trapèze représente un case qui se trouve déjà dans le process iowr. Il faut donc simplement le compléter.

Les leds ajoutées nécessitent l'ajout des contraintes :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
LED2[7],Output,PIN_G15,7,B7_N2,2.5 V,
LED2[6],Output,PIN_F15,7,B7_N2,2.5 V,
LED2[5],Output,PIN_H17,7,B7_N2,2.5 V,
LED2[4],Output,PIN_J16,7,B7_N2,2.5 V,
LED2[3],Output,PIN_H16,7,B7_N2,2.5 V,
LED2[2],Output,PIN_J15,7,B7_N2,2.5 V,
LED2[1],Output,PIN_G17,7,B7_N1,2.5 V,
LED2[0],Output,PIN_J17,7,B7_N2,2.5 V,

Réaliser ensuite un chenillard simple montrant le bon fonctionnement. Il devra obligatoirement être sur 16 LEDs.

3°) Réaliser ensuite un chenillard complexe qui vous sera décrit verbalement par votre enseignant.

ANNEXE

Nous avons pour habitude d'utiliser les primitives d'instanciation des LUTs avec les outils Xilinx. Nous avons donc chercher comment faire avec les outils Altera et, à notre grande surprise, avons découvert que la primitive correspondant n'existe pas. Bien sûr les FPGAs Altera sont aussi bâtis autour des LUT (LUT4, LUT5, LUT6) mais leurs utilisation est un peu plus complexe.

Pour rendre l'utilisation plus compréhensibles pour les habitués, nous avons procédé comme ceci.

1 - Création d'un composant LUT4

Voici le composant correspondant :

library ieee;
use ieee.std_logic_1164.all;
library altera;
use altera.altera_primitives_components.all;
entity LUT4 is 
  generic(mask : std_logic_vector(15 downto 0):=X"0000");
  port (
   in4 : in std_logic_vector(3 downto 0);
	out1 : out std_logic);
end LUT4;
architecture arch_lut4 of LUT4 is
signal s_lut : std_logic_vector(3 downto 0);
signal s_out : std_logic;
begin
  ic1:lut_input port map(a_in => in4(0),a_out=>s_lut(0));
  ic2:lut_input port map(a_in => in4(1),a_out=>s_lut(1));
  ic3:lut_input port map(a_in => in4(2),a_out=>s_lut(2));
  ic4:lut_input port map(a_in => in4(3),a_out=>s_lut(3));
  with s_lut select
    s_out <= mask(0) when "0000",
             mask(1) when "0001",
             mask(2) when "0010",
             mask(3) when "0011",
             mask(4) when "0100",
             mask(5) when "0101",
             mask(6) when "0110",
             mask(7) when "0111",
             mask(8) when "1000",
             mask(9) when "1001",
             mask(10) when "1010",
             mask(11) when "1011",
             mask(12) when "1100",
             mask(13) when "1101",
             mask(14) when "1110",
             mask(15) when "1111";
	ic5: lut_output port map(a_in=>s_out,a_out=>out1);
end arch_lut4;

2 - Instanciation

Comme d'habitude :

-- declaration avant begin architecture
 component LUT4 is 
    generic(mask : std_logic_vector(15 downto 0):=X"0000");
    port (
     in4 : in std_logic_vector(3 downto 0);
	  out1 : out std_logic);
  end component LUT4;

-- puis après begin :
mylut:LUT4 generic map(mask => X"FFFE")
            port map (in4 => compteur(14 downto 11),
     	           OUT1 => led);

Chaque connaisseur aura reconnu la réalisation d'un OU à quatre entrées.