Leçons de niveau 15

Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/TP 5

Une page de Wikiversité.
Aller à : navigation, rechercher
Début de la boite de navigation du travail pratique
Icon falscher Titel.svg
En raison de limitations techniques, la typographie souhaitable du titre, « Travail pratique : TP 5
Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/TP 5
 », n'a pu être restituée correctement ci-dessus.


Nous allons dans ce dernier chapitre mettre en œuvre des processeurs softcore variés. Je ne pense pas qu’il y ait un intérêt particulier pour un étudiant de connaître tous les processeurs softcores présentés. Faites votre choix parmi le PicoBlaze, le PIC 16F84 et le ATMega8. Nous commençons par le PicoBlaze.

Le PicoBlaze[modifier | modifier le wikicode]

Avant de débuter ce TP, essayez d'obtenir le fichier "kcpsm3.zip" chez Xilinx. Cela vous permettra d’avoir l'assembleur (sous Windows), et surtout le fichier kcpsm3.vhd qui décrit le PicoBlaze.

Nous allons commencer par une mise en œuvre du PicoBlaze sans nous occuper de la lecture d'un clavier PS/2. Le plus simple est donc d’utiliser les interrupteurs de la carte et les afficheurs sept segments.

PicoBlaze sans clavier PS/2[modifier | modifier le wikicode]

Searchtool.svg Lire dans le cours, particulièrement la partie matérielle, du chapitre : Micro contrôleur embarqué : le PicoBlaze.

On désire faire fonctionner le PicoBlaze pour réaliser l’affichage complet sur 8 bits et deux digits du TP 1.

Architecture[modifier | modifier le wikicode]

  • Entrées : 8 bits en entrées correspondent à un PORT. Il vous faut donc partir de l'architecture à quatre PORTs présentée dans le cours et la simplifier pour en garder un seulement.
  • Sorties : un port est nécessaire pour gérer les sept segments, un autre pour gérer la sélection des afficheurs.

Il est temps de présenter le schéma à implanter :

Utiliser le PicoBlaze pour afficher sur deux digits

Dans ce schéma le démultiplexeur est responsable d'envoyer le signal write_strobe en fonction du bit de poids faible de port_id sur une de ses deux sorties. Les bascules D sont naturellement des registres 8 bits avec entrée de validation. Quelque chose comme :

process(clk) begin
    if clk'event and clk = '1' then
	 if en0 ='1' then 
		 q_lsb <= s_out_port ;
      end if;		
	 end if;
  end process;

devrait convenir.

Panneau d’avertissement Le morceau de programme donné ci-dessus est une implantation sans composant, donc directement dans un process d'où la présence de signaux (que je note souvent avec le préfixe "s_"). Si vous utilisez des composants changez les noms de variables ci-dessus.

Le contenu de la mémoire programme à gauche de la figure vous est donné un peu plus loin dans ce document.

Programme[modifier | modifier le wikicode]

Pour simplifier le développement on vous donne le programme complet de gestion des afficheurs. Évidemment le PicoBlaze fonctionnant à 50 Mhz, il faut gérer des boucles d'attentes.

;;; Sortie sur deux digits
constant MAX, FF
namereg s0,i
NAMEREG s1, octet_lsb
NAMEREG s3, s7seg  ; rename register s3 as “s7seg”
NAMEREG s4, Aff
debut:
        ; initialisation RAM : table de conversion
        LOAD s0,01
        STORE s0,00 
        LOAD s0,4F
        STORE s0,01
        LOAD s0,12
        STORE s0,02
        LOAD s0,06
        STORE s0,03 
        LOAD s0,4C
        STORE s0,04 
        LOAD s0,24
        STORE s0,05
        LOAD s0,20
        STORE s0,06
        LOAD s0,0F
        STORE s0,07
        LOAD s0,00
        STORE s0,08 
        LOAD s0,04
        STORE s0,09
        LOAD s0,08
        STORE s0,0A
        LOAD s0,60
        STORE s0,0B
        LOAD s0,31
        STORE s0,0C 
        LOAD s0,42
        STORE s0,0D
        LOAD s0,30
        STORE s0,0E
        LOAD s0,38
        STORE s0,0F     
boucle: 
        ;entree des {{Unité|8|bits}} 
        INPUT octet_lsb,0
        AND octet_lsb,0F
        ;conversion par RAM
        FETCH s7seg,(octet_lsb)
        ;sortie 7 segs
        OUTPUT s7seg,0
        LOAD Aff,FE
        ;sélection afficheur
        OUTPUT Aff,1
        CALL wait
        ; maintenant {{Unité|4|bits}} poids forts
        INPUT octet_lsb,0
        SR0 octet_lsb
        SR0 octet_lsb
        SR0 octet_lsb
        SR0 octet_lsb
        AND octet_lsb,0F ;inutile en principe
        ;conversion par RAM
        FETCH s7seg,(octet_lsb)
        ;sortie 7 segs
        OUTPUT s7seg,0
        LOAD Aff,FD
        ;sélection afficheur
        OUTPUT Aff,1
        CALL wait
        JUMP boucle
wait:
        LOAD i,MAX
loop:   SUB i,01
        JUMP NZ,loop
        RETURN
Panneau d’avertissement La boucle d'attente présentée est relativement rapide avec une horloge à 50 Mhz, mais des tests ont montré le bon fonctionnement de ce programme. Pour une autre carte il faudrait éventuellement ralentir en faisant une double boucle ou en appelant plusieurs fois de suite le sous-programme "wait".

Un programme assembleur est ensuite assemblé pour donner un composant VHDL représentant le contenu de la ROM du PicoBlaze. Pour éviter la compilation aux étudiants dans un premier temps, je donne le contenu VHDL équivalent au programme adssembleur. Pour éviter de polluer cette page avec un long programme VHDL pas utile pour tout le monde, je met le programme correspondant dans une boîte déroulante :

Exercice[modifier | modifier le wikicode]

On vous demande de réaliser l'architecture globale utilisant le PicoBlaze, la mémoire les PORTs de sortie. En ce qui concerne le PORT d'entrée on se contentera de faire ce qu'on ne fait jamais, de relier directement les entrées au PORT d'entrée du PicoBlaze.



PicoBlaze et clavier[modifier | modifier le wikicode]

Nous allons maintenant interfacer le clavier du TP 3 à notre PicoBlaze. Nous allons nous intéresser à la version dans laquelle on a ajouté un registre d'affichage. Ce registre d'affichage constituera un port d'entrées. Un autre port d'entrée sera encore constitué par les interrupteurs. Ces interrupteurs doivent servir à naviguer dans la mémoire donnée du picoblaze. Le fonctionnement est donc le suivant :

  • Pour chaque appui de touches sur le clavier une interruption est générée qui vient lire l'octet qui vient d’être lu pour le ranger en mémoire (après l'adresse 0x00F).
  • La session d'acquisition étant terminée, il vous est possible de naviguer dans la mémoire donnée pour afficher les scancodes reçus : la navigation se fait en binaire avec les quatre interrupteurs.

Notre programme[modifier | modifier le wikicode]

Le programme est naturellement plus complexe que le précédent puisqu’il gère une interruption.

;;; Sortie sur deux digits
constant MAX, 80
namereg s0,i
NAMEREG s1, octet_lsb
NAMEREG s2, adr_mem
NAMEREG s3, s7seg  ; rename register s3 as “s7seg”
NAMEREG s4, Aff
NAMEREG s5, switch
NAMEREG s6, ps2
debut:
        ENABLE Interrupt
        ; initialisation RAM : table de conversion
        LOAD s0,01
        STORE s0,00 
        LOAD s0,4F
        STORE s0,01
        LOAD s0,12
        STORE s0,02
        LOAD s0,06
        STORE s0,03 
        LOAD s0,4C
        STORE s0,04 
        LOAD s0,24
        STORE s0,05
        LOAD s0,20
        STORE s0,06
        LOAD s0,0F
        STORE s0,07
        LOAD s0,00
        STORE s0,08 
        LOAD s0,04
        STORE s0,09
        LOAD s0,08
        STORE s0,0A
        LOAD s0,60
        STORE s0,0B
        LOAD s0,31
        STORE s0,0C 
        LOAD s0,42
        STORE s0,0D
        LOAD s0,30
        STORE s0,0E
        LOAD s0,38
        STORE s0,0F
;initialisation pointeur mémoire
        LOAD adr_mem,10 
boucle: 
;lecture des switchs
        INPUT switch,1
;;      AND switch,0F
;;      ADD switch,10
        ;entree des {{Unité|8|bits}} 
        FETCH octet_lsb,(switch)
;je ne garde que la partie basse :
        AND octet_lsb,0F
;conversion par RAM
        FETCH s7seg,(octet_lsb)
;sortie 7 segs
        OUTPUT s7seg,0
        LOAD Aff,FE
;sélection afficheur droite
        OUTPUT Aff,1
        CALL wait
; maintenant {{Unité|4|bits}} poids forts
        INPUT switch,1
;;      AND switch,0F
;;      ADD switch,10
        ;entree des {{Unité|8|bits}} 
        FETCH octet_lsb,(switch)
;decalage de {{Unité|4|bits}} vers la droite
        SR0 octet_lsb
        SR0 octet_lsb
        SR0 octet_lsb
        SR0 octet_lsb
        ;conversion par RAM
        FETCH s7seg,(octet_lsb)
;sortie 7 segs
        OUTPUT s7seg,0
        LOAD Aff,FD
;sélection afficheur gauche
        OUTPUT Aff,1
        CALL wait
;;;;;;; to remove
        INPUT ps2,0
;;      LOAD ps2,1F
;;      ADD ps2,01
        STORE ps2,(adr_mem)
;;      ADD adr_mem,01
;;;;;;;;;end to remove
        JUMP boucle
;=== boucle d'attente===
wait:
        LOAD i,MAX
loop:   SUB i,01
        JUMP NZ,loop
        RETURN
;=== code de l'interuption===
isr:
; lecture du registre PS2
;;      INPUT ps2,0
        LOAD ps2,20
        ADD ps2,adr_mem
; stockage en RAM
        STORE ps2,(adr_mem)
;increment adresse RAM
        ADD adr_mem,01
        RETURNI ENABLE
;=== verteur d'interruption===
ADDRESS 0X3FF
        JUMP isr

Exercice[modifier | modifier le wikicode]

Réaliser l'architecture complète.

Le PIC 16F84 embarqué[modifier | modifier le wikicode]

Panneau d’avertissement L'ensemble de ce chapitre n'a pas encore été testé. Ainsi le programme C donné ne comporte aucune erreur de syntaxe puisqu’il a été compilé mais peut comporter des erreurs sémantiques !!!

Un moyen de commencer avec un projet simple est d’utiliser le PIC 16F84 pour afficher sur deux afficheurs sept segments multiplexés. L'intérêt par rapport au PicoBlaze est que maintenant on peut travailler avec le langage C.

Le PIC16F84 pour gérer des afficheurs sept segments[modifier | modifier le wikicode]

Searchtool.svg Lire dans le cours, particulièrement la partie matérielle, du chapitre : Embarquer_un_PIC_16F84.

Notre objectif est assez modeste : afficher une donnée provenant de huit interrupteurs sur deux afficheurs sept segments en hexadécimal. Nous commençons par donner notre programme en C.

Le programme de départ en C[modifier | modifier le wikicode]

Nous avons choisi PORTA pour gérer les afficheurs et PORTB en entrée pour les interrupteurs et PORTB en sortie pour les afficheurs sept segments.

#include <pic.h>
char conv[]={0x01,0x4F,0x12,0x06,0x4C,0x24,0x20,0x0F,0x00,0x04,
             0x08,0x60,0x31,0x42,0x30,0x38};
void wait(unsigned char tempo);
void main(void)
{ char entree_PORTB,pdsfaible,pdsfort;
   TRISA = 0x00; // PORTA en sortie
   while(1) {
// Lecture du port B
	TRISB = 0xFF;
    entree_PORTB=PORTB;
// calcul intermédiaire
	pdsfaible = entree_PORTB & 0x0F;
    pdsfort = (entree_PORTB >> 4) & 0x0F;
// sortie du port B
    TRISB = 0x00;
    PORTB=conv[pdsfaible];
// sélection afficheur poids faible
    PORTA = 0xFE;
	wait(255); // On attend
    PORTB=conv[pdsfort];
// sélection afficheur poids faible
    PORTA = 0xFD;
	wait(255); // On attend
  }
}
void wait(unsigned char tempo){ 
OPTION=0x07; // div 256 et source=quartz 
TMR0 =0; 
while(TMR0<tempo); 
}


On rappelle qu'une fois le programme C compilé, on dispose d'un fichier .hex qui doit être transformer en VHDL avec l'utilitaire approprié.

Le fichier mémoire ROM[modifier | modifier le wikicode]

Si le fichier à convertir s’appelle demo16F84.hex on utilise la commande :

hex2rom demo16F84.hex progrom 13l14s >progrom.vhd

Le fichier progrom.vhd possède plus de 1000 lignes et il nous est donc impossible de le donner pour éviter aux utilisateurs la compilation. On va vous donner le fichier .hex, beaucoup plus compact :

Le fichier RAM[modifier | modifier le wikicode]

Ce fichier a déjà été donné dans le chapitre Embarquer un PIC 16F84.

Le projet complet[modifier | modifier le wikicode]

À faire