Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/TPs ATTiny861 avec Altera

Une page de Wikiversité.
Aller à : navigation, rechercher
Début de la boite de navigation du travail pratique
TPs ATTiny861 avec Altera
Image logo représentative de la faculté
T.P. no 9
Leçon : Very High Speed Integrated Circuit Hardware Description Language

Ce TP est de niveau 15.

Précédent : Projets pour ATMEL ATTiny861
Suivant : Utiliser des shields Arduino avec les FPGA
En raison de limitations techniques, la typographie souhaitable du titre, « Travail pratique : TPs ATTiny861 avec Altera
Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/TPs ATTiny861 avec Altera
 », n'a pu être restituée correctement ci-dessus.

Nous allons présenter dans ce chapitre une série de 6 TPs réalisés avec une carte Altera DE2-115. Il s'agit de réaliser un compteur de passages d’abord sans processeur puis avec un processeur sans périphérique particulier. On ajoutera ensuite petit à petit des périphériques.

Pour information, ces TPs ont été réalisés avec un format de 6 TPs de durée 1h30 et des étudiants de deuxième année de Génie Électrique (2015/2016). Avec ce format, la seule chose qui peut être réalisée est du TP dirigé ! Il faudrait deux ou trois heures par séance pour un fonctionnement plus interactif avec une plus grande autonomie des étudiants. Le sixième TP n'a pas été réalisé mais a été remplacé par le septième qui est une évaluation. L'objectif était de montrer à des étudiants la possibilité d’utiliser des périphériques sophistiqués pour simplifier la programmation. Il a donc été partiellement atteint avec le TP 5.

Pour éviter la création d'un autre chapitre, nous avons complété cette série par une autre série de 6 TPs qui seront réalisés dans les même conditions que la première série. Ces TPs seront numérotés TP1b, TP2b, ... et TP6b et auront pour thème la réalisation partielle d'un réveil sur des afficheurs 7 segments.

Puis... nous avons encore créé une série de 6 TPs avec un thème similaire : le réveil. Sa sortie est par contre réalisée sur l'afficheur LCD de 2x16 caractères. Ils seront numérotés de TP1c à TP6c. Ils ont été réalisés en 2016/2017 par des étudiants de GEII 2eme année.

Sommaire

Introduction[modifier | modifier le wikicode]

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7. La série d'exercices proposée ici peut certainement être réalisée avec d'autres cartes terasIC, comme la DE-2 et même probablement la DE-1. La seule chose qu’il vous faudra adapter sera le fichier de contraintes. Pour le reste, rien à changer !

Le processeur embarqué qui est utilisé dans ces séries de TPs a été conçu par Andreas Hilvarsson. Il a écrit ce cœur ATTinyx61 et l'a publié chez Opencores.org. Nous l'utiliserons avec une mémoire programme de 8ko, d'où l'appellation ATTiny861 dans ce cours. Il sera programmé en C.

Le compteur de passages est évoqué dans un autre livre : Compteur de passages revu et corrigé. Il sera le fil conducteur de la première série de TPs (TP1 à TP7).

Le réveil sera abordé dans la deuxième série de TPs (TP1b à TP6b) comme dans la troisième série (TP1c à TP6c). La différence entre les deux séries est l'affichage : soit sur des afficheurs sept segments soit sur un afficheur lcd.

Nous allons, dans cette première série de TPs, construire d’abord complètement un compteur de passages sans processeur. Une fois terminé, nous allons utiliser un processeur (embarqué) sans périphérique particulier. Pour terminer cette série, nous allons d’abord déporter le transcodage vers l'extérieur, puis l’ensemble des deux compteurs BCD et des deux transcodeurs. L'objectif de ce travail est donc de bien comprendre les rapports entre le matériel et le logiciel pour des exemples relativement simples.

TP 1 (1h30)[modifier | modifier le wikicode]

Exercice 1[modifier | modifier le wikicode]

On vous demande simplement de réaliser un transcodeur pour afficher tout nombre sur 4 bits (entrée) sur un afficheur 7 segments. Avec notre carte DE2-115, pour allumer un segment il faut mettre un '0' sur la broche correspondante. Une autre caractéristique est l'absence de multiplexage des afficheurs sept segments. Pour information il y en a 8 sur la carte en question et cela nécessite donc 8x7=56 broches de FPGA.

Indication 1[modifier | modifier le wikicode]

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 mais assumez alors 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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

Deux transcodeurs sept segments

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)

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)[modifier | modifier le wikicode]

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

Exercice 1[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

Test des compteurs BCD cascadés

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

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)[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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.

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

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



Exercice 2[modifier | modifier le wikicode]

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

TP 4 (1h30)[modifier | modifier le wikicode]

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

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

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 !

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 min) mais la simple mise en RAM/ROM du programme ne prendra que 2 min une fois cette première compilation réalisée.

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

Ressources[modifier | modifier le wikicode]

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. Nous en avons fait aussi une version directement utilisable pour les circuits Altera.




Mon site pouvant changer, nous en publions ici une version utilisée dans ce TP. Les modifications citées n'ont été réalisée que dans le fichier "microcontroleur.vhd".

Fichier top[modifier | modifier le wikicode]




Fichier de réalisation du cœur[modifier | modifier le wikicode]

Fichier mémoire RAM[modifier | modifier le wikicode]

Fichier mémoire ROM[modifier | modifier le wikicode]

Ce fichier est donné dans l'annexe un peu plus loin.

Fichier de contraintes[modifier | modifier le wikicode]

Nous donnons le fichier de contraintes sous la forme csv. Il vous faudra importer ce fichier pour qu’il soit pris en compte.

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
clk,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
Rst,Input,PIN_Y23,5,B5_N2,2.5 V,
Aff7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Aff7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Aff7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Aff7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Aff7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Aff7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Aff7segs[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,
Led[7],Output,PIN_H19,7,B7_N2,2.5 V,
Led[6],Output,PIN_J19,7,B7_N2,2.5 V,
Led[5],Output,PIN_E18,7,B7_N1,2.5 V,
Led[4],Output,PIN_F18,7,B7_N1,2.5 V,
Led[3],Output,PIN_F21,7,B7_N0,2.5 V,
Led[2],Output,PIN_E19,7,B7_N0,2.5 V,
Led[1],Output,PIN_F19,7,B7_N0,2.5 V,
Led[0],Output,PIN_G19,7,B7_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,
In_PINB[7],Input,PIN_AA22,5,B5_N2,2.5 V,
In_PINB[6],Input,PIN_AA23,5,B5_N2,2.5 V,
In_PINB[5],Input,PIN_AA24,5,B5_N2,2.5 V,
In_PINB[4],Input,PIN_AB23,5,B5_N2,2.5 V,
In_PINB[3],Input,PIN_AB24,5,B5_N2,2.5 V,
In_PINB[2],Input,PIN_AC24,5,B5_N2,2.5 V,
In_PINB[1],Input,PIN_AB25,5,B5_N1,2.5 V,
In_PINB[0],Input,PIN_AC25,5,B5_N2,2.5 V,

Ce fichier pourra être utilisé pour toute la partie processeur du TP.

Pour information[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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....

Exercice 1[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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)[modifier | modifier le wikicode]

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 le transcodage du langage C vers le matériel, comme le montre la figure ci-contre.

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[modifier | modifier le wikicode]

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

Exercice 2[modifier | modifier le wikicode]

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

Exercice 3[modifier | modifier le wikicode]

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)[modifier | modifier le wikicode]

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. Bien, le matériel fait tout mais il faut lui en donner l'ordre. Et cela, c’est de la responsabilité du processeur.

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[modifier | modifier le wikicode]

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



Exercice 2[modifier | modifier le wikicode]

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 Évaluation (1h30)[modifier | modifier le wikicode]

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.

1°) A partir de la Correction du TP6, on vous demande de montrer que vous êtes capables de :

  • faire un projet à partir de la ressource 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
  • 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. Les 8 premières leds sont présentent depuis le TP4 et sont commandées par PORTA. Les 8 nouvelles 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 qui est accessible.

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.

L'objectif de ces Travaux pratiques est de réaliser partiellement un réveil. Les trois premiers TP réalisent un comptage pour réveil en logique traditionnelle avec des composants combinatoires, les transcodeurs sept segments, et des composants séquentiels, des compteurs décimaux et modulo 6. Puis nous introduirons un processeur pour faciliter la gestion du réveil.

TP1b : Réalisation d'un transcodeur sept segments[modifier | modifier le wikicode]

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

Pour commencer simplement avec l'environnement Quartus, nous allons réaliser le célèbre transcodeur 7 segments.

Exercice 1[modifier | modifier le wikicode]

Vous partirez du code suivant :

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 ENTITY transcod7segs;
ARCHITECTURE arch of transcod7segs IS 
BEGIN
  with e select
             --abcdefg
    s7segs  = "0000001" when "0000",
              "1001111" when "0001",
              "0010010" when "0010",
              "0000110" when "0011",
              "1001100" when "0100",
              "0100100" when "0101",
              "0100000" when "0110",
              "0001111" when "0111",
              "0000000" when "1000",
              "0000100" when "1001",
              "0001000" when "1010",
              "1100000" when "1011",
              "0110001" when "1100",
              "1000010" when "1101",
              "0110000" when "1110",
              "0111000" when others;
END;

Le fichier de contraintes sera :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
s7segs[0],Output,PIN_H22,6,B6_N0,2.5 V,
s7segs[1],Output,PIN_J22,6,B6_N0,2.5 V,
s7segs[2],Output,PIN_L25,6,B6_N1,2.5 V,
s7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
s7segs[4],Output,PIN_E17,7,B7_N2,2.5 V,
s7segs[5],Output,PIN_F22,7,B7_N0,2.5 V,
s7segs[6],Output,PIN_G18,7,B7_N2,2.5 V,
e[3],Input,PIN_AD27,5,B5_N2,2.5 V,
e[2],Input,PIN_AC27,5,B5_N2,2.5 V,
e[1],Input,PIN_AC28,5,B5_N2,2.5 V,
e[0],Input,PIN_AB28,5,B5_N1,2.5 V,

Exercice 2 : Utilisation de 4 digits[modifier | modifier le wikicode]

On désire étendre le travail réalisé en exercice 2 sur 4 digits.

Le fichier de contraintes sera :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
DIGIT0[0],Output,PIN_H22,6,B6_N0,2.5 V,
DIGIT0[1],Output,PIN_J22,6,B6_N0,2.5 V,
DIGIT0[2],Output,PIN_L25,6,B6_N1,2.5 V,
DIGIT0[3],Output,PIN_L26,6,B6_N1,2.5 V,
DIGIT0[4],Output,PIN_E17,7,B7_N2,2.5 V,
DIGIT0[5],Output,PIN_F22,7,B7_N0,2.5 V,
DIGIT0[6],Output,PIN_G18,7,B7_N2,2.5 V,
DIGIT1[0],Output,PIN_U24,5,B5_N0,2.5 V,
DIGIT1[1],Output,PIN_U23,5,B5_N1,2.5 V,
DIGIT1[2],Output,PIN_W25,5,B5_N1,2.5 V,
DIGIT1[3],Output,PIN_W22,5,B5_N0,2.5 V,
DIGIT1[4],Output,PIN_W21,5,B5_N1,2.5 V,
DIGIT1[5],Output,PIN_Y22,5,B5_N0,2.5 V,
DIGIT1[6],Output,PIN_M24,6,B6_N2,2.5 V,
DIGIT2[0],Output,PIN_W28,5,B5_N1,2.5 V,
DIGIT2[1],Output,PIN_W27,5,B5_N1,2.5 V,
DIGIT2[2],Output,PIN_Y26,5,B5_N1,2.5 V,
DIGIT2[3],Output,PIN_W26,5,B5_N1,2.5 V,
DIGIT2[4],Output,PIN_Y25,5,B5_N1,2.5 V,
DIGIT2[5],Output,PIN_AA26,5,B5_N1,2.5 V,
DIGIT2[6],Output,PIN_AA25,5,B5_N1,2.5 V,
DIGIT3[0],Output,PIN_Y19,4,B4_N0,3.3-V LVTTL,
DIGIT3[1],Output,PIN_AF23,4,B4_N0,3.3-V LVTTL,
DIGIT3[2],Output,PIN_AD24,4,B4_N0,3.3-V LVTTL,
DIGIT3[3],Output,PIN_AA21,4,B4_N0,3.3-V LVTTL,
DIGIT3[4],Output,PIN_AB20,4,B4_N0,3.3-V LVTTL,
DIGIT3[5],Output,PIN_U21,5,B5_N0,2.5 V,
DIGIT3[6],Output,PIN_V21,5,B5_N1,2.5 V,
SW[15],Input,PIN_AA22,5,B5_N2,2.5 V,
SW[14],Input,PIN_AA23,5,B5_N2,2.5 V,
SW[13],Input,PIN_AA24,5,B5_N2,2.5 V,
SW[12],Input,PIN_AB23,5,B5_N2,2.5 V,
SW[11],Input,PIN_AB24,5,B5_N2,2.5 V,
SW[10],Input,PIN_AC24,5,B5_N2,2.5 V,
SW[9],Input,PIN_AB25,5,B5_N1,2.5 V,
SW[8],Input,PIN_AC25,5,B5_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,

et vous donne le nom de vos entrées et des sorties.

TP2b : Réalisation d'un réveil HH:MN à Trois hertz[modifier | modifier le wikicode]

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

Nous disposons d'un compteur BCD sur 4 digits et nous allons réaliser un réveil en modifiant un peu l'ensemble.

Exercice 1 : Faire fonctionner l'ensemble donné[modifier | modifier le wikicode]

Cascader des compteurs décimaux pour 4 digits

Nous allons réaliser ce qui est présenté dans la figure ci-contre mais sans le multiplexeur. Le retrait du multiplexeur est lié à la gestion des afficheurs sur la carte qui va nous servir pour les TPs. Sur cette carte il n'y a aucun multiplexage, c'est à dire qu'il est possible d'envoyer des valeurs différentes sur chacun des afficheurs sept segments.

Étant donné que chacun des compteurs a une sortie sur 4 bits et que celle-ci doit commander un affichage 7 segments, il faut donc remplacer le multiplexeur par 4 transcodeurs.

Pour vous entraîner à la lecture des "PORT MAP", un exercice intéressant est de partir du code donné ci-dessous et de refaire le schéma correspondant. Une autre manière de dire les choses est que le schéma ci-contre donne l'idée générale (cascader des compteurs BCD) mais ne représente pas complètement le code ci-dessous. Nous garderons cet étrangeté pour vous obliger à faire un dessin.

On vous donne donc le code suivant :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Compteur4Digits is
port (
   clk : in std_logic;
   DIGIT3, DIGIT2, DIGIT1, DIGIT0 : out std_logic_vector(6 downto 0)
  );
end Compteur4Digits;

architecture arch_Compteur4Digits of Compteur4Digits is

COMPONENT cmpt24bits IS
  PORT(clk : IN STD_LOGIC;
    eno3Hz : OUT STD_LOGIC);
END COMPONENT cmpt24bits;

component 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 component CounterBCD;

component transcod7segs IS PORT(
  e : in std_logic_vector(3 downto 0);
  s7segs : out std_logic_vector(6 downto 0));
END component transcod7segs;

signal s_en3Hz : std_logic;
signal s_eno, s_eno2, s_eno3 : std_logic;
signal s_eno2_heure : std_logic_vector(8 downto 0);
signal s_reset : std_logic; -- pour les heures 
signal s_data16 : std_logic_vector(15 downto 0);

begin
  i1: cmpt24bits port map (
         clk =  clk,
         eno3Hz =  s_en3Hz);

  bcdUnit: CounterBCD port map( 
    EN =  s_en3Hz,
 	 Clock =  clk,
 	 Reset =  '0',
	 ENO =  s_eno,
 	 Output =  s_data16(3 downto 0));
  bcdDiz: CounterBCD port map( 
    EN =  s_eno,
 	 Clock =  clk,
 	 Reset =  '0',
	 ENO =  s_eno2,
 	 Output =  s_data16(7 downto 4));
  bcdCent: CounterBCD port map( 
    EN =  s_eno2,
 	 Clock =  clk,
 	 Reset =  s_reset,
	 ENO =  s_eno3,
 	 Output =  s_data16(11 downto 8));
  bcdMil: CounterBCD port map( 
    EN =  s_eno3,
 	 Clock =  clk,
 	 Reset =  '0',
	 ENO =  open,
 	 Output =  s_data16(15 downto 12));	
  
					  
  i4: transcod7segs port map (
         e =  s_data16(3 downto 0),
			s7segs =   DIGIT0) ;
  i5: transcod7segs port map (
         e =  s_data16(7 downto 4),
			s7segs =   DIGIT1) ;
  i6: transcod7segs port map (
         e =  s_data16(11 downto 8),
			s7segs =   DIGIT2);
  i7: transcod7segs port map (
         e =  s_data16(15 downto 12),
			s7segs =   DIGIT3) ;		
end arch_Compteur4Digits;

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);
   signal s_en_cmpt: std_logic_vector(4 downto 0);
begin   process(Clock,Reset)
   begin
      if(rising_edge(Clock)) then
		  if Reset='1' then
         cmpt  = "0000";
 	      elsif EN='1' then
	         if cmpt="1001" then
	            cmpt ="0000";
	         else
	           cmpt  = cmpt + 1;
	         end if;
         end if;
      end if;
   end process;
   Output  = cmpt;
	s_en_cmpt  = en & cmpt;

   with s_en_cmpt select
     ENO  = '1' when "11001",
            '0' when others;
end Behavioral;

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,
DIGIT0[0],Output,PIN_H22,6,B6_N0,2.5 V,
DIGIT0[1],Output,PIN_J22,6,B6_N0,2.5 V,
DIGIT0[2],Output,PIN_L25,6,B6_N1,2.5 V,
DIGIT0[3],Output,PIN_L26,6,B6_N1,2.5 V,
DIGIT0[4],Output,PIN_E17,7,B7_N2,2.5 V,
DIGIT0[5],Output,PIN_F22,7,B7_N0,2.5 V,
DIGIT0[6],Output,PIN_G18,7,B7_N2,2.5 V,
DIGIT1[0],Output,PIN_U24,5,B5_N0,2.5 V,
DIGIT1[1],Output,PIN_U23,5,B5_N1,2.5 V,
DIGIT1[2],Output,PIN_W25,5,B5_N1,2.5 V,
DIGIT1[3],Output,PIN_W22,5,B5_N0,2.5 V,
DIGIT1[4],Output,PIN_W21,5,B5_N1,2.5 V,
DIGIT1[5],Output,PIN_Y22,5,B5_N0,2.5 V,
DIGIT1[6],Output,PIN_M24,6,B6_N2,2.5 V,
DIGIT2[0],Output,PIN_W28,5,B5_N1,2.5 V,
DIGIT2[1],Output,PIN_W27,5,B5_N1,2.5 V,
DIGIT2[2],Output,PIN_Y26,5,B5_N1,2.5 V,
DIGIT2[3],Output,PIN_W26,5,B5_N1,2.5 V,
DIGIT2[4],Output,PIN_Y25,5,B5_N1,2.5 V,
DIGIT2[5],Output,PIN_AA26,5,B5_N1,2.5 V,
DIGIT2[6],Output,PIN_AA25,5,B5_N1,2.5 V,
DIGIT3[0],Output,PIN_Y19,4,B4_N0,3.3-V LVTTL,
DIGIT3[1],Output,PIN_AF23,4,B4_N0,3.3-V LVTTL,
DIGIT3[2],Output,PIN_AD24,4,B4_N0,3.3-V LVTTL,
DIGIT3[3],Output,PIN_AA21,4,B4_N0,3.3-V LVTTL,
DIGIT3[4],Output,PIN_AB20,4,B4_N0,3.3-V LVTTL,
DIGIT3[5],Output,PIN_U21,5,B5_N0,2.5 V,
DIGIT3[6],Output,PIN_V21,5,B5_N1,2.5 V,

Exercice 2 : Compteur modulo6[modifier | modifier le wikicode]

Pour compter les dizaines des minutes, il nous faut un compteur modulo 6 qui soit cascadable. Modifier le compteur BCD donné pour qu'il compte de 0 à 5 et génère un signal ENO quand il est à 5 et quand son entrée EN est à 1.

Indication : le compteur BCD à modifier est donné ci-dessous :

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);
	signal s_en_cmpt: std_logic_vector(4 downto 0);
begin   process(Clock,Reset)
   begin
      if(rising_edge(Clock)) then
		  if Reset='1' then
         cmpt  = "0000";
 	      elsif EN='1' then
	         if cmpt="1001" then
	            cmpt ="0000";
	         else
	           cmpt  = cmpt + 1;
	         end if;
         end if;
      end if;
   end process;
   Output  = cmpt;
	s_en_cmpt  = en & cmpt;
   with s_en_cmpt select
     ENO  = '1' when "11001",
            '0' when others;
end Behavioral;

Vous remplacerez le compteur des dizaines des minutes par ce nouveau compteur et en ferez un test. Restera donc la réalisation correcte des heures.

Exercice 3 : Compteur des heures[modifier | modifier le wikicode]

Nous allons ajouter un comptage correct des heures au compteur de l'exercice 2 qui compte normalement la partie minutes.

Le comptage des heures est lui aussi très particulier. Les unités nécessitent un compteur décimal mais qui doit être interrompu lorsque les dizaines passent à 2 ! On ne doit pas alors dépasser 3. Nous allons utiliser un montage bouclé pour réaliser cela : lorsque l'on est à 23, un EN='1' fait repasser les heures à 0. Ce n'est pas la peine de le faire pour les minutes, cela sera automatique.

Indication : la gestion du bouclage peut être réalisé par quelque chose du genre :

HeurUnit: CounterBCD port map( 
    EN =  s_eno2,
 	 Clock =  clk,
 	 Reset =  s_reset,
	 ENO =  s_eno3,
 	 Output =  s_data16(11 downto 8));
  HeurDiz: CounterBCD port map( 
    EN =  s_eno3,
 	 Clock =  clk,
 	 Reset =  s_reset,
	 ENO =  open,
 	 Output =  s_data16(15 downto 12));
	
  -- reset quand 23 est detecte	par rebouclage
    s_eno2_heure  = s_eno2 & s_data16(15 downto 8);
    with s_eno2_heure select
	   s_reset  = '1' when "100100011",
                 '0' when others;

Faites un schéma pour comprendre.

TP3b : Réaliser un réveil qui sonne[modifier | modifier le wikicode]

Le diagramme d'évolution comme moyen de spécifier le calcul de l'état futur en fonction de l'état présent

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

Le graphe d'évolution du réveil qui sonne est présenté ci-contre. La réalisation de ce graphe d'évolution nécessite la réalisation de ses deux entrées :

  • Key : sera simplement une entrée (un switch). Il sert pour l'armement de la sonnerie du réveil.
  • Trip : détecte que l'heure de sonnerie est égale à l'heure courante. L'heure courante est naturellement réalisé par le travail du TP2. L'heure de réveil à ce stade sera réalisée par 16 interrupteurs

La sortie sonnerie sera matérialisée par une LED. Une autre LED peut être utilisée pour matérialisée l'armement du réveil

Exercice : Un réveil qui sonne[modifier | modifier le wikicode]

Le graphe d'évolution sera réalisé avec un case when et sans initialisation. Le test de bon fonctionnement ne peut se faire qu'avec deux interrupteurs en entrées (un pour ArmKey et un pour Trip) et pas à 50 MHz pour éviter la prise en compte des rebonds. La sortie se fera sur une LED.

Indication 1 : 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.

Indication 2 : 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) :

TYPE typetat IS (Armed, Off, Ringing); -- dans architecture
SIGNAL etat : typetat;

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 :

-- sans initialisation
BEGIN
  PROCESS (clock) BEGIN
    IF clock'EVENT AND clock='1' THEN
      CASE etat IS
      WHEN Off =  IF key ='1' THEN etat  = Armed; 
                  ELSE etat  = Off; 
                  END IF;
                  ....
      END CASE;
    END IF;
  END PROCESS;
  ....

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.

Indication 3 : Il serait bon d'ajouter au réveil une entrée ENA qui sera une division de l'horloge par 2**20. Ceci pour éviter les rebonds des interrupteurs.

Indication 4 : le réveil est abordé dans un autre livre sous toutes les formes et il est même possible d'y trouver une solution sans initialisation et avec l'entrée ena.

Exercice 2 : Un réveil qui sonne (suite)[modifier | modifier le wikicode]

Compléter l'exercice 1 pour utiliser le séquenceur de la sonnerie mais avec Trip réalisé avec l'heure courante qui défile. Par contre l'heure de sonnerie sera réalisée par des interrupteurs.

TP4b : Un processeur seul[modifier | modifier le wikicode]

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

Tiny 861 de départ avec ses afficheurs, ses leds et ses interrupteurs

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 !

Voir le TP4 de ce chapitre pour la présentation.

Évidemment, la ressource donnée n'est pas identique à celle du TP4 puisque nous avons besoin de 4 digits d'affichage. C'est ce qui est présenté dans la figure.

Votre objectif sera de prendre contact avec un processeur qui ne possède aucun périphérique. Votre travail consistera à réaliser :

  • quelques chenillards
  • un comptage BCD sur 4 digits, en utilisant les sous-programmes du TP4, puis

TP5b : Déplacer les transcodeurs et s'en servir comme périphérique[modifier | modifier le wikicode]

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

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 !

Déplacer les transcodeurs comme périphérique du Tiny 861

L'utilisation de l'affichage sur quatre digits avec le Tiny861 nécessite l'utilisation de quatre registres : un par afficheur. Elle nécessite aussi l'utilisation d'un tableau pour transcoder. En clair pour que 0x1234 finisse sur les afficheurs sept segments il faut d'abord découper 0x1234 en quatre parties contenant 1, 2, 3 et 4 et les transcoder. Cela représente un travail important à réaliser par programme. Nous désirons simplifier le travail du programmeur en déplaçant le transcodage logiciel (par tableau) dans le matériel à l'aide des transcodeurs déjà réalisés dans les TPs précédents. L'affichage de 0x1234 sera alors simplement coupé en deux 0x12 et 0x34 et envoyés sur deux ports. Le transcodage sera alors complètement automatique.

Exercice 1[modifier | modifier le wikicode]

  1. Réaliser le périphérique demandé. Ce qui est demandé est dessiné en rouge dans la figure de cette section.
  2. Modifier le programme de l'exercice précédent pour que l'on affiche toujours les heures d'un réveil sur ce nouveau matériel.

TP6b : Un compteur complet comme périphérique[modifier | modifier le wikicode]

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

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 !

Interface pour retrouver l'heure courante

Nous allons utiliser la correction de l'exercice 3 du TP2b et en faire un périphérique. Il s'agit de l'ajouter à ce qui a été fait dans le TP5b. Ainsi l'heure du TP 5b correspond à une heure de réveil. Il est très facile de manipuler celle-ci en incrémentation ou décrémentation par un processeur.

Exercice 1[modifier | modifier le wikicode]

Prendre les 4 compteurs HH:MM du TP2 et en faire un composant.

Il devra donc avoir 2 entrées :

  • horloge encore appelée clk,
  • EN entrée de validation qui est reliée à un signal de 3 Hz. Le processeur devra pouvoir accéder directement aux sorties de tous les compteurs, avant le transcodage. Celles-ci devront donc être des entrées pour le processeur.

Les nouvelles sorties globales sept segments devront utiliser quatre autre digits.

Montrer qu'après réalisation de la partie matérielle, vous êtes capable de détecter que l'heure réveil est égale à l'heure courante en allumant une LED.

Exercice 2[modifier | modifier le wikicode]

Pouvez-vous améliorer le comportement de votre réveil pour un réglage de l'heure réveil ?


A partir de maintenant, c'est une autre série de TP qui commence.

TP1c : premier contact avec Quartus et l'affichage LCD[modifier | modifier le wikicode]

Comme nous utilisons la carte DE2-115, le FPGA utilisé est un Cyclone IVE de référence EP4CE115F29C7. Cette carte DE2-115 possède un afficheur LCD de deux lignes de 16 caractères.

Contrairement à ce qu'il se passe pour les TPs TP1 et TP1b, la sortie ne peut pas être directe sur l'afficheur LCD. Nous voulons dire que ce que vous allez réaliser est enfoui dans une partie de code VHDL qui est donné. Vous devez donc repérer l'entité et l'architecture à modifier pour arriver à vos fins.

Exercice 1[modifier | modifier le wikicode]

On vous donne complètement le module qui affiche sur l'afficheur. Pour cela, nous allons essayer dans cette section, d'utiliser un module VHDL touvé chez Opencores. Il se trouve dans Projets - Other - 16x2 LCD controller et a été réalisé par Daniel Drescher. Pour éviter d'aller les chercher sur Internet, ces fichiers vous sont fournis maintenant.

  • d'abord le fichier de démonstration
  • puis le fichier du coeur lcd, fichier que l'on gardera tout au long de ce TP

1°) En suivant ce que fait l'enseignant, on vous demande de compiler et d'essayer le module d'Opencores.org

2°) Modifier le texte affiché à votre convenance

Indications :

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
CLK,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
LCD_E,Output,PIN_L4,1,B1_N1,3.3-V LVTTL,
LCD_ON,Output,PIN_L5,1,B1_N1,3.3-V LVTTL,
LCD_RS,Output,PIN_M2,1,B1_N2,3.3-V LVTTL,
LCD_RW,Output,PIN_M1,1,B1_N2,3.3-V LVTTL,
LCD_DB[7],Output,PIN_M5,1,B1_N2,3.3-V LVTTL,
LCD_DB[6],Output,PIN_M3,1,B1_N1,3.3-V LVTTL,
LCD_DB[5],Output,PIN_K2,1,B1_N1,3.3-V LVTTL,
LCD_DB[4],Output,PIN_K1,1,B1_N1,3.3-V LVTTL,

Exercice 2[modifier | modifier le wikicode]

Notre objectif étant d'afficher des heures minutes, nous allons spécialiser un peu cet afficheur. Dans un premier temps, on le destine à afficher les 4 digits d'un compteur binaire. En clair il doit afficher entre 0000 et FFFF. Mais l'exercice précédent vous a montré que l'afficheur lcd ne connaît que les codes ASCII. Vous aller réaliser un circuit combinatoire qui réalise cela. Comme il nous faut garder le gestionnaire de l'écran lcd, nous allons vous proposer un fichier lcd16x2_ctrl_demo.vhd modifié dans lequel on vous demande de modifier la partie combinatoire en fin de fichier.

Indications :

  • on vous a préparé une horloge à 10 Hz pour le compteur
  • L'ensemble donné fonctionne mais pas correctement : il affiche mal les chiffres au-delà de 9 !!!
  • la seule chose que vous avez à réaliser est le transcodeur tout en bas du fichier. Vous remplacerez l'équation naïve par un "with select when"

TP2c : réalisation d'un affichage HH:MN[modifier | modifier le wikicode]

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

Exercice 1[modifier | modifier le wikicode]

Le problème du transcodeur réalisé dans l'exercice 2 du TP1c peut être facilement résolu si l'on remplace les compteurs hexadécimaux par des compteurs BCD (qui ne comptent que de 0 à 9). C'est ce que fait le code ci-dessous. Vous y remarquerez la disparition du transcodeur de l'exercice 2 tu TP1c. Essayez de comprendre pourquoi.

Dans cet exercice, on vous demande simplement d'insérer un ":" entre les deux premiers digits et les deux derniers. On vous rappelle en effet que l'on finira par afficher les heures et minutes (qui en général sont séparées par ce ":") d'où le titre de ce TP.

Exercice 2 : Compteur modulo6[modifier | modifier le wikicode]

Pour compter les dizaines des minutes, il nous faut un compteur modulo 6 qui soit cascadable. Modifier le compteur BCD donné pour qu'il compte de 0 à 5 et génère un signal ENO quand il est à 5 et quand son entrée EN est à 1.

Indication : le compteur BCD à modifier est donné ci-dessous :

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
      © Copyright Wikipedia authors - The articles gathered in this document are under the GFDL licence.
http://www.gnu.org/copyleft/fdl.html