Vous êtes sur la page 1sur 109

REPOBLIKAN’I MADAGASIKARA

Tanindrazana – Fahafahana – Fandrosoana

MINISTERE DE L’EDUCATION NATIONALE ET DE LA RECHERCHE SCIENTIFIQUE


ECOLE SUPERIEURE POLYTECHNIQUE D’ANTSIRANANA

TRAVAUX DE MEMOIRE
Pour l’obtention du diplôme d’ingénieur

SYNTHESE D’UNE ARCHITECTURE


SYSTOLIQUE
SUR FPGA

TRAVAUX REALISES AU SEIN DU LABORATOIRE


D’INFORMATIQUE APPLIQUEE DE L’ESP

ETUDIANT : Angelo BOTOLAHY


ENCADREUR : M.ANDRIANIVOSOA Ramamonjy

EII5
Date de soutenance : 10 Avril 2009
Synthèse d’une architecture systolique sur FPGA
Domaine : FPGA, Parallélisme

Contexte

Bon nombre de problèmes qui se posent aux scientifiques sont par nature composés de
traitements en série et parallèle. Les architectures systoliques sont des architectures bien
adaptés à ces genres de problème. Des programmes de simulation ont été conçus en JAVA à
l’Ecole dans le cadre de projets antérieurs.

But

Il s’agit d’étudier et synthétiser sur circuit reconfigurable une architecture systolique capable
d’effectuer la multiplication de deux matrices rectangulaires n*m.
Pour simplifier on se limitera à la matrice à coefficient entiers.

Travaux à faire

• Etude des architectures systoliques


• Sérialisation des traitements
• Etude de synthèse des cellules élémentaires : multiplication et additionneur
• Synthèse finale
• Test avec des valeurs simples

Responsable : ANDRIANIVOSOA Ramamonjy


REMERCIEMENTS :

Avant toute chose, je tiens à remercier l’Eternel, sans lui rien n’aurait été et ne serait
possible.

Cependant, je tiens à témoigner mes plus vifs remerciements à Madame le président


du jury ainsi que à mon encadreur : Monsieur ANDRIANIVOSOA Ramamonjy pour leurs
précieux conseils et leurs disponibilités dont ils ont fait preuve.

J’adresse maintenant mes profondes gratitudes à tous les membres de jury.

Enfin, je tiens à remercier toutes les personnes, qui ont contribué de près ou de loin à
l’accomplissement de ce mémoire.
SOMMAIRE

Chapitre1 : THEORIE DES MACHINES SYSTOLIQUES…………………………………………………… 2


1. LES MACHINES PARALLELES……………………………………………………………………………………… 2
1.1. Introduction……………………………………………………………………………………………………… 2
1.2. Les différents modèles de machines parallèles…………………………………………....... 2
1.3. Machine cellulaire……………………………………………………………………………………………… 5
1.4. Machine vectorielle…………………………………………………………………………………………… 6
1.5. Les machines systoliques………………………………………………………………………………….. 9

1.6. Application d’une machine systolique pour le calcul du produit de matrices……… 12

Chapitre 2 : Etude du système…………………………………………………………………………………. 17


2.1. Généralité………………………………………………………………………………………………………… 17
2.2. Etude des éléments logiques et des éléments combinatoires…………………………. 17
2.3. MISE EN ŒUVRE DES SCHEMAS……………………………………………………………………… 18
2.4. Circuit détaillé du bloc acquisition de données……………………………………………… 19
2.5. Architecture systolique…………………………………………………………………………………. 20
2.6. Circuit détaillé du bloc transmetteur de données…………………………………………. 21
2.7. L’unité de contrôle………………………………………………………………………………………… 22

Chapitre 3. L’architecture d’une cellule……………………………………………………………….. 24


3.1. Multiplication……………………………………………………………………………………………….. 24
3.2. Etude de chaque composant de la multiplication ………………………………………… 32
3.3. Addition………………………………………………………………………………………………………… 36

Chapitre 4 : synthèse sur FPGA……………………………………………………………………………. 38


4.1. Les circuits FPGA………………………………………………………………………………………….. 38
4.2. Le langage VHDL…………………………………………………………………………………………… 39
4.3. Codes VHDL des composants du système…………………………………………………… 40
4.4. Code VHDL d’acquisition……………………………………………………………………………….. 51
4.5. Code VHDL du circuit d’une cellule………………………………………………………………… 52
4.6. Code VHDL Datatransmitter…………………………………………………………………………… 54

Chapitre 5. Simulation et réalisation…………………………………………………………………….. 56


5.1. Simulation………………………………………………………………………………………………………. 56
5.2. Réalisation………………………………………………………………………………………………………. 57
5.3. Mise en œuvre de la communication sérielle selon le protocole
RS232 défini sur Spartan3.................................................................................. 59

Chapitre 6 : Le logiciel SystoRice…………………………………………………………………………… 61


6.1. Généralité……………………………………………………………………………………………………… 61
6.2. Les onglets…………………………………………………………………………………………………….. 61
TABLE DES FIGURES
Chapitre1 : THEORIE DES MACHINES SYSTOLIQUES
Fig. 1.1 Architecture pipeline………………………………………………………..3
Fig. 1.2 : Architecture MIMD à mémoire partagée…………………………4
Fig.1.3 Architecture d’une machine SIMD……………………………………..5

Fig.1.4 Type de réseau des machines cellulaires……………………6


Fig. 1.5 : structure d’une architecture pipeline…………………………….7
Fig.1.6 : pipeline d’instruction à 4 étages……………………………………..7
Fig. 1.7: pipeline d’instruction conditionnelle…………………………………8
Fig. 1.8: structure d’une machine systolique…………………………………….10
Fig. 1.9: Architecture d’une machine systolique…………………………………11
Fig. 1.10: Architecture systolique pour la multiplication des matrices 3x3………..13
Fig. 1.11: Fonctionnement de l’architecture systolique pour la multiplication des matrices 3x3….15

Chapitre 2 : Etude du système


Fig. 2.1. Schémas bloc du système……………………………………………………18
Fig. 2.2. Circuit de l’acquisition de données……………………………………..19
Fig. 2.3. Circuit de la machine cellulaire…………………………………………….20
Fig. 2.4. Circuit du transmetteur de données……………………………….21

Chapitre 3. L’architecture d’une cellule


Fig. 3.1 : Premier version de la multiplication…………………………………….26
Fig. 3.2 : Première version de l’algorithme de la multiplication……………27
Fig. 3.3 : deuxième version de la multiplication…………………………………..28
Fig. 3.4 : Deuxième version de l’algorithme de la multiplication ………..29
Fig. 3.5 :Troisième version de la multiplication…………………………………….30
Fig. 3.6 : Troisième version de l’algorithme de la multiplication …………31
Fig. 3.7: chemin de donnée pour la multiplication…………………………..32
Fig. 3.8 : Additionneur complet 1 bit…………………………………………………..32
Fig. 3. 9: additionneur complet 8 bits……………………………………………….33
Fig. 3.10: Composant registre………………………………………………………34
Fig. 3.11: Multiplexeur à deux entrées……………………………………………35
Fig. 3.12 : composant bascule D sans initialisation…………………………..36
Fig. 3.13 : Schémas bloc de l’additionneur……………………………………36

Chapitre 4 : synthèse sur FPGA


Fig. 4.1 : bascule D avec remise à zéro…………………………………………42
Fig. 4.2. Détecteur de bit de Start…………………………………………….43
Fig.4.3 : compteur par 9………………………………………………………..44
Fig.4.4. additionneur complet 8 bit……………………………………….47
Fig.4.5. bascule D …………………………………………………………………49
Fig. 4.6. Acquisition de données…………………………………………..52
Fig. 4.7. Architecture d’une cellule……………………………………….53
Fig. 4.8. Architecture d’une transmission de donnée……………55

Chapitre 5. Simulation et réalisation


Fig. 5.1: Configuration de l’horloge……………………………………………..56
Fig. 5.2:slack…………………………………………………………………………….57
Fig 5.3: Déphasage d’horloge (clock skew)…………………………..53
Fig. 5.4: Assign Package Pins……………………………………………………54
Fig. 5.5 : Fichier de programme……………………………………………59
Fig. 5.6: programmation réussie………………………………………..59
Fig. 5.7: RS-232 Serial Port…………………………………………………..60

Chapitre 6 : Le logiciel SystoRice


Fig.6.1: Interface de l’onglet « step by step »……………………62
Fig 6.2: L’onglet « implementation of datums in FPGA »………………………….63
TABLE DES MATIERES

Chapitre1 : THEORIE DES MACHINES SYSTOLIQUES…………………………………………………… 2


1. LES MACHINES PARALLELES……………………………………………………………………………………… 2
1.1. Introduction……………………………………………………………………………………………………… 2
1.2. Les différents modèles de machines parallèles…………………………………………....... 2
1.2.1. Machine SISD…………………………………………………………………………………………… 2
1.2.2. Machine MISD…………………………………………………………………………………………… 3
1.2.3. Machine MIMD………………………………………………………………………………………… 3
1.2.4. Machine SIMD…………………………………………………………………………………………… 4
1.3. Machine cellulaire……………………………………………………………………………………………… 5
1.4. Machine vectorielle…………………………………………………………………………………………… 6
1.4.1. Pipeline……………………………………………………………………………………………………… 6
1.4.2. Pipeline d’instruction du branchement conditionnel………………………………… 8
1.4.3. Performance du pipeline……………………………………………………………………........ 9
1.5. Les machines systoliques………………………………………………………………………… 9
1.5.1. Exploitation du parallélisme de données et de flux en mode systolique…… 10
1.5.2. Architecture générale d’une machine systolique……………………………………… 11
1.6. Application d’une machine systolique pour le calcul du produit de matrices……… 12
1.6.1. modélisation analytique……………………………………………………………………………… 12
1.6.1.1. Réseau systolique………………………………………………………………………………… 12
1.6.1.2. Principe………………………………………………………………………………………………… 12
1.6.1.3. Algorithme de calcul dans une cellule pendant un cycle d’horloge…… 13
1.6.1.4. Architecture systolique pour la multiplication des matrices et le
fonctionnement des cellules………………………………………………………… 13
Chapitre 2 : Etude du système…………………………………………………………………………………. 17
2.1. Généralité………………………………………………………………………………………………………… 17
2.2. Etude des éléments logiques et des éléments combinatoires…………………………. 17
2.3. MISE EN ŒUVRE DES SCHEMAS……………………………………………………………………… 18
2.3.1. Schéma bloc du système……………………………………………………………………….. 18
2.3.2. Fonctionnement…………………………………………………………………………………….. 18
2.4. Circuit détaillé du bloc acquisition de données……………………………………………… 19
2.4.1. Schéma………………………………………………………………………………………………….. 19
2.4.2. Fonctionnement…………………………………………………………………………………… 19
2.5. Architecture systolique…………………………………………………………………………………. 20
2.5.1. Les buffers…………………………………………………………………………………………….. 20
2.5.2. La machine cellulaire…………………………………………………………………………….. 20
2.5.2.1. Schéma du circuit………………………………………………………………………….. 20
2.5.2.2. Le fonctionnement……………………………………………………………………….. 21
2.6. Circuit détaillé du bloc transmetteur de données…………………………………………. 21
2.6.1. Schéma…………………………………………………………………………………………………. 21
2.6.2. Le fonctionnement……………………………………………………………………………….. 21
2.7. L’unité de contrôle………………………………………………………………………………………… 22
2.7.1. L’unité de commande de l’acquisition de données………………………………. 22
2.7.2. L’unité de contrôle de l’architecture systolique……………………………………. 22
2.7.3. L’unité de contrôle de transmetteur de données…………………………………. 22
2.8. Conclusion…………………………………………………………………………………………………….. 23

Chapitre 3. L’architecture d’une cellule……………………………………………………………….. 24


3.1. Multiplication……………………………………………………………………………………………….. 24
3.1.1. Concept de base…………………………………………………………………………………… 24
3.1.2. Etudes des schémas blocs pour la multiplication …………………………………. 25
3.1.2.1. Premier version du matériel et de l’algorithme pour la
multiplication……………………………………………………………………………….. 26
3.1.2.2. Deuxième version du matériel et de l’ algorithme pour la
multiplication………………………………………………………………………………… 28
3.1.2.3. Troisième version du matériel et de l’algorithme pour la
multiplication……………………………………………………………………………….. 30
3.1.3. Le schéma détaillé du chemin des données de la multiplication ….. 32
3.2. Etude de chaque composant de la multiplication ………………………………………… 32
3.2.1. Additionneur complet 1 bit………………………………………………………………… 33
3.2.1.1. Table de vérité de l’additionneur complet de 1 bit……………………… 33
3.2.1.2. Table de karnaugh………………………………………………………………………… 33
3.2.1.3. Additionneur complet 8 bits……………………………………………………… 33
3.2.2. Composant registre d’entrée de donnée (registre 8 bits)………………… 34
3.2.3 : Composant registre à décalage………………………………………………………… 34
3.2.3.1: Registre 16 bits sans chargement……………………………………………… 34
3.2.3.2. Multiplexeur à deux entrées de 8 bits………………………………………… 35
3.2.3.3. Compteur par 9…………………………………………………………………………… 35
3.2.4. Composant bascule D sans initialisation………………………………………… 36
3.3. Addition………………………………………………………………………………………………………… 36
3.3.1. Additionneur de 16 bits………………………………………………………………………… 36
3.4. Conclusion…………………………………………………………………………………………………….. 37

Chapitre 4 : synthèse sur FPGA……………………………………………………………………………. 38


4.1. Les circuits FPGA………………………………………………………………………………………….. 38
4.1.1. Présentation………………………………………………………………………………………… 38
4.1.2. Méthodologie de synthèse………………………………………………………………….. 39
4.1.3. Les circuits XILINX…………………………………………………………………………………. 39
4.1.4. Module XILINX spartan-3……………………………………………………………………… 39
4.2. Le langage VHDL…………………………………………………………………………………………… 39
4.2.1. Généralité sur langage VHDL……………………………………………………………….. 39
4.2.2. Méthode de conception adoptée……………………………………………………….. 40
4.3. Codes VHDL des composants du système…………………………………………………… 40
4.3.1. Code VHDL de l’inverseur ……………………………………………………………………. 40
4.3.2. Code VHDL de l’opérateur AND à 2 entrées………………………………………… 40
4.3.3. Code VHDL de l’opérateur OR à 2 entrées…………………………………………… 41
4.3.4. Code VHDL de L’opérateur XOR à 2 entrées…………………………………………. 41
4.3.5. Code de la bascule D avec remise à zéro………………………………………………. 42
4.3.6. Code VHDL d’un Module qui détecte le bit de Start……………………………… 43
4.3.7. Code VHDL du compteur par 9……………………………………………………………… 44
4.3.8. Code VHDL de démultiplexeur……………………………………………………………… 45
4.3.9. Code VHDL de multiplexeur………………………………………………………………….. 46
4.3.10. Code VHDL de l’additionneur complet 1 bit………………………………………… 46
4.3.11. Code VHDL de l’additionneur complet 8 bit………………………………………… 47
4.3.12. Code source du registre à décalage (shifter)………………………………………. 48
4.3.13. Le code VHDL correspondant à la bascule D ………………………………………. 49
4.3.14. Le code VHDL d’un registre 8 bits avec affectation
après 8ème coups d’horloge.57…………………………………………………………….. 50
4.4. Code VHDL d’acquisition……………………………………………………………………………….. 51
4.4.1. Entité…………………………………………………………………………………………………….. 51
4.4.2. Architecture…………………………………………………………………………………………… 51
4.5. Code VHDL du circuit d’une cellule………………………………………………………………… 52
4.5.1. Entité……………………………………………………………………………………………………… 52
4.5.2. Architecture…………………………………………………………………………………………... 53
4.6. Code VHDL Datatransmitter…………………………………………………………………………… 54
4.6.1. Entité…………………………………………………………………………………………………….. 54
4.6.2. Architecture………………………………………………………………………………………….. 54

Chapitre 5. Simulation et réalisation…………………………………………………………………….. 56


5.1. Simulation………………………………………………………………………………………………………. 56
5.1.1. Configuration de l’horloge………………………………………………………………………. 56
5.2. Réalisation………………………………………………………………………………………………………. 57
5.2.1. Processus « Synthesize-XST »…………………………………………………………………. 57
5.2.2. Création du fichier de contrainte systorice.ucf………………………………………. 57
5.2.3. Implémentation……………………………………………………………………………………… 58
5.2.4. Génération du fichier de programme…………………………………………………….. 58
5.3. Mise en œuvre de la communication sérielle selon le protocole
RS232 défini sur Spartan3.................................................................................. 59
5.3.2. Broches du port séries et FPGA pins……………………………………………………… 60

Chapitre 6 : Le logiciel SystoRice…………………………………………………………………………… 61


6.1. Généralité……………………………………………………………………………………………………… 61
6.2. Les onglets…………………………………………………………………………………………………….. 61
6.2.1. L’onglet « step by step »……………………………………………………………………….. 62
6.2.1.1. Présentation de l’interface……………………………………………………………… 62
6.2.1.2. Principe d’utilisation et fonctionnement………………………………………… 62
6.2.2. L’onglet « On the wing »…………………………………………………………………………. 63
6.2.3. L’onglet « implementation of datums in FPGA »…………………………………….. 63
Introduction
Le parallélisme permet d’augmenter de manière très significative la vitesse de traitement dans la
mesure où plusieurs actions sont effectuées simultanément. Il est utilisé dans plusieurs domaines,
entre autres le traitement scientifique.

Les machines systoliques font partie des machines à traitements parallèles. Conceptuellement, elles
sont constituées d’un ensemble de processeurs (ou cellules) élémentaires interconnectés localement
pour former un réseau nommé « réseau systolique ».
Dans ce travail nous allons étudier et implémenter l’architecture systolique sur un circuit
reconfigurable (FPGA).
Pour mieux l’éclaircir, nous le diviserons ce rapport en 6 chapitres :

• La première partie est consacrée à l’étude théorique des machines systoliques.


• Dans le deuxième chapitre, on voit l’étude du système
• Dans Le troisième chapitre nous abordons spécialement les détails de l’architecture d’un
processeur.
• Le quatrième chapitre sera basé sur la synthèse sur le FPGA
• Le cinquième chapitre met en évidence la simulation des circuits ainsi programmés et la
réalisation sur la carte.
• On finira par le sixième chapitre par le développement du logiciel nommé SystoRice.
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

Chapitre1 : THEORIE DES MACHINES SYSTOLIQUES


1. LES MACHINES PARALLELES

1.1 Introduction

Ce chapitre donne une aperçue générale des machines parallèles, particulièrement les machines
systoliques. Le parallélisme est l’évolution simultanée des différentes opérations ou calculs au
niveau des processeurs (que ce soit arithmétique ou logique). En effet, la plupart des
microprocesseurs modernes ne sont plus entièrement séquentielle ; ils sont dotés de fonctions de
parallélisme. Par exemple il n’est pas rare (Pentium, power PC, etc.) d’avoir plusieurs unités de calcul
arithmétique pouvant fonctionner en parallèles.
Avantages et inconvénients

Le principal avantage du parallélisme est la vitesse de calcul. Pour N processeurs en parallèle, le


calcul est exécuté plus vite qu’en mode séquentiel classique.
L’inconvénient est la nécessité d’une espace mémoire plus grande.
Difficultés
 Il faut gérer le partage des tâches ;
 Il faut gérer l’échange d’information car une erreur peut fausser toute l’opération.

1.2 Les différents modèles de machines parallèles

On distingue classiquement quatre types des machines parallèles : SISD, SIMD, MISD et MIMD.
Cette classification est basée sur les notions de flot de contrôle (les deux premières lettres) et flot de
données (les deux dernières lettres).

1.2.1. Machine SISD

Une machine SISD (Single Instruction Single Data) ou flux à une instruction et une donnée, est ce que
l’on appelle d’habitude une machine séquentielle, ou machine de Von Neumann. Une seule

-2-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

instruction est exécutée à un moment donné et une seule donnée (simple, non structurée) est traitée
à un moment donné.
float[10] A,B,C
for (init i=0 ;i<10 ;i++)
C[i]=A[i]+B[i];

Ce code s’exécute sur une machine séquentielle en faisant les additions :


A[0]+B[0], A[1 ]+B[1],…,A[9]+B[9] à la suite les unes des autres.

1.2.2. Machine MISD

Une machine MISD (Multiple Instruction Single Data) est une machine à plusieurs instructions. Une
donnée peut exécuter plusieurs instructions en même temps. Cela peut paraître paradoxal mais cela
recouvre en fait un type très ordinaire de microparallèlisme dans les microprocesseurs moderne : les
processeurs vectoriels et les architectures pipelines.

MEMOIRE

PI PE LI NE

Processeurs
CONTROLE

Fig. 1.1 Architecture pipeline

1.2.3. Machine MIMD

Une machine MIMD (Multiple Instruction Multiple Data) qu’on peut épeler aussi quelque fois flux à
plusieurs instructions et plusieurs données. Chaque processeur peut exécuter un programme
différent.

-3-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

C1 C2 C3 C4 C5

P1 P2 P3 P4 P5

Réseau d’interconnexion

M M M M M

Fig. 1.2 : Architecture MIMD à mémoire partagée

Légende :
C1 : contrôle n°1 ;
P1 : Processeur n°1 ;
M1 : mémoire n°1.

1.2.4. Machine SIMD

Une machine SIMD (Single Instruction Multiple Data) ou flux à plusieurs données, est une machine
qui exécute à tout instant une seule instruction, mais qui agit en parallèle sur plusieurs données ; on
parle en générale de « parallélisme de données ». Les machines SIMD peuvent être de plusieurs
types par exemple, parallèles ou systoliques. On s’intéresse à ce type de machine parce que les
machines systoliques en font parties.

-4-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

P1 P2 P3 P4 P5

Réseau d’interconnexion

M1 M2 M3 M4 M5
Fig.1.3 Architecture d’une machine SIMD

Légende :
P1 : Processeur n°1 ;
M1 : mémoire n°1.

1.3. Machine cellulaire

Dans une machine cellulaire, le mode d’exécution est toujours de type SIMD. L’unité de contrôle
envoie son instruction courante à tous les processeurs élémentaires. Ces PEs qui doivent l’exécuter
prennent pour argument les données placées dans leurs mémoires locales. L’exécution se fait en
mode synchrone c'est-à-dire on attend que tous les processeurs élémentaires aient terminé
l’exécution de l’instruction courante pour passer à l’instruction suivante.
Type de réseaux des machines cellulaires.

Une machine cellulaire est fondée par plusieurs cellules qui s’interconnectent des différentes façons,
et la façon de les communiquer s’appelle réseau. Il y a trois types de réseau :
 Réseau en grille
 Réseau en éther
 Réseau hexagonal

-5-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

Réseau d’interconnexion globale

a) Réseau en grille b) Réseau éther

c) Réseau hexagonal

Fig. 1.4 Type de réseau des machines cellulaires

Les machines cellulaires sont généralement utilisées dans le traitement d’image et aussi
dans les calcules arithmétiques.
1.4. Machine vectorielle

Les machines vectorielles se caractérisent par le principe de pipeline.

1.4.1. Pipeline

Le pipeline est une organisation du processeur qui comprend plusieurs étages et permet d’exécuter
simultanément plusieurs instructions. Il représente un moyen d’introduire le parallélisme dans la
nature essentielle d’un groupe d’instruction de machine. Dans la classification des machines
parallèles, ces machines sont de type MISD mais on peut considérer que l’effet pipeline est
semblable à un effet Multiple Data, donc en pratique, on classe les machines pipelines avec les
machines SIMD.
L’unité de traitement et l’unité de contrôle sont découpées en n étages. Ainsi, des données peuvent
être traitées à l’étage 1 pendant que d’autres sont traitées à l’étage 2.
L’unité de contrôle fournit un flux d’instruction à l’unité de traitement. L’unité de traitement opère
sur un seul flux de données provenant d’une unité de mémoire.

-6-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

Mémoire centrale

UT Etage 1 UC

Etage 2

Etage 3

Etage n

Fig. 1.5 : structure d’une architecture pipeline

On va considérer un pipeline d’instruction comme une fonction composée par des 4 fonctions
simples.

f = f4o f3 o f2 o f1

i f(i)
f1 f2 f3 f4

Fig.1.6 : pipeline d’instruction à 4 étages.

Ce pipeline possède quatre étages à savoir f1, f2, f3 et f4.


f1 lit une instruction et la place dans un tampon. Lorsque f2 (2e étage) est libre, f1 lui passe
l’instruction dans le tampon et f2 poursuit l’instruction et ainsi f1 est prêt à recevoir une
autre instruction, ainsi de suite.

Tableau 1.Chronogramme du fonctionnement d’un pipeline

Ici, la durée de chaque phase (fi ; 1≤i≤4) considérée égale.

-7-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

Les 5 instructions doivent être effectuées en 4 x 5 unités de temps réduit en 8 unités de temps. Cela
représente un gain de temps.
1.4.2. Pipeline d’instruction du branchement conditionnel

L’instruction du branchement constitue un autre obstacle car elle peut invalider plusieurs adresses
d’instructions au niveau des certains étages.
Considérons un pipeline d’instruction f défini par :

   √ ; x IR ; soient f1=Id ; f2=ln ; f3=√. et f4=e


Donc f(x) =f4 o f3 o f2 o f1(x)
On dit alors que f4, f3, f2 et f1 sont les étages de f.

Maintenant, on veut traiter les 5 instructions suivantes f(1), f() f(2), f(-1) et f(4).

Le premier problème va avoir lieu dans la 2ième instruction f() au niveau de l’étage f3, car f3 n’accepte
pas une valeur négative. Alors f() pourra être un blocage pour les autres prochaines instructions. Il
faut débloquer l’instruction en supprimant f() au niveau de l’étage f2 quand f3 demande l’adresse de
la prochaine instruction pour que f(2) s’effectuera et les autres poursuivront.

Nouvelle adresse
1/2 f1 f2 f3 f4 f(i)

Suppression

Fig. 1.7: pipeline d’instruction conditionnelle

Voici un diagramme qui montre le traitement de 5 instructions

Tableau 2: effet d’un branchement conditionnel sur le fonctionnement d’un pipeline

-8-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

1.4.3. Performance du pipeline

Un étage fi a besoin d’un temps ti pour traiter une instruction.


Mais, en générale les ti sont différents.
Supposons qu’on a un pipeline d’instruction à n étages, alors le temps nécessaire pour traiter k
instruction est :
Tn = [n + (k-1)]τ ; où τ=max[ti].
Exemple :
Un pipeline des instructions f(x) =f4 o f3 o f2 o f1(x) ;
Supposons que τ=max i [ti]=1.
Pour traiter 5 instructions on a : T4=[4 +(5 -1)].
D’où on retrouve T4 = 8 unité de temps.
Dans un calcul séquentiel classique (sans pipeline) le temps d’exécution d’instruction est :
T1=K. n. τ
On définit alors le facteur d’accélération du pipeline d’instruction composé à une exécution sans
pipeline par :

Sn= Tn/T1

On change Tn et T1 par leur valeur, on a

.. .
Sn  

Dans notre exemple, le facteur d’accélération est égal:

. 
Sn = 
 


On dit les 5 instructions sont exécutées 
fois plus vite en mode pipeline qu’en mode séquentiel
classique.

1.5. LES MACHINES SYSTOLIQUES

La machine systolique est l’une des machines qui utilisent la technique du pipeline en association
avec le modèle cellulaire et celle qui tire un grand profit de cette exploitation. Elle est alors le
fusionnement d’une machine cellulaire et d’une machine vectorielle.

-9-
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

1.5.1. Exploitation du parallélisme de données et de flux en mode systolique.

La philosophie de ce type d’architecture est d’exploiter à la fois le parallélisme de données comme


dans les machines cellulaires et le parallélisme de flux comme dans les machines vectorielles.
Elles empruntent aux machines cellulaires l’organisation générale (grille). La partie opératoire est
constituée de processeurs élémentaires PEs identiques reliés par un réseau d’interconnexion.
Elles empruntent aux machines vectorielles le mode de fonctionnement pipeline : les données de
l’application entrent dans la partie opérative en mode série et coulent sur les processeurs
élémentaires PEs vers les tampons de sortie d’où elles sont renvoyées vers l’unité de stockage
centralisées.

Mémoire de vecteur

Machine cellulaire Machine vectorielle

Buffer d’Entrée

Unité de
stockage
de
données
Buffer de sortie

Machine systolique

Fig. 1.8: structure d’une machine systolique

- 10 -
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

Cette figure montre la configuration structurale d’une machine systolique et les éléments qui la
composent.
1.5.2. Architecture générale d’une machine systolique

Le processeur systolique est connecté à une machine hôte, d’usage général, qui assure les fonctions
d’interface système avec l’utilisateur. Le processeur systolique est composé de trois éléments
essentiels :

Machine Hôte

Buffer d’entrées sorties

Unité de Unité de
stockage de contrôle
données SIMD

Matrices de PEs

Bus d’interconnexion

Fig. 1.9: Architecture d’une machine systolique

L’unité de calcul
Il s’agit d’une matrice de processeurs élémentaires PEs (identiques) qui sont reliés par un réseau
d’interconnexion statique généralement organisée en grille.

- 11 -
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

L’unité de contrôle
Il s’agit d’un contrôleur centralisé qui fonctionne en mode SIMD. Il génère à chaque cycle systolique,
une instruction qui est envoyée à tous les processeurs élémentaires PEs de la matrice et une
instruction d’entrée/sortie qui est envoyée à tous les buffers ou tampons.

L’unité d’entrées/sorties
Son rôle est de fournir à chaque cycle systolique les données en provenance de l’unité de stockage
de données (respectivement de renvoyer les données vers l’unité de stockage de données). Pour
cela, on utilise des buffers dont le rôle est semblable à celui des registres vectoriels dans une
machine vectorielle.
Dans une machine systolique, l’unité d’entrée/sortie joue un rôle critique dans la performance
globale de la machine en raison de l’exploitation intensive de la source de parallélisme de flux.

1.6. APPLICATION D’UNE MACHINE SYSTOLIQUE POUR LE CALCUL DU PRODUIT DE MATRICES

1.6.1. MODELISATION ANALYTIQUE

1.6.1.1. Réseau systolique

Comme nous l’avons dit, un réseau systolique est constitué par un groupement des cellules
(identiques) qui ne peuvent s’effectuer qu’un nombre restreint de tâches (ou calculs).
Les cellules sont reliées entre elles par un réseau (dans cette partie on convient d’utiliser le réseau en
grille), elles ne peuvent communiquer qu’avec leurs voisines. Ainsi, une cellule reçoit des données
d’une de ses voisines, fait un calcul et transmet le résultat à une voisine. Seules les cellules situées à
la frontière du réseau communiquent avec l’extérieur.

1.6.1.2. Principe

Un réseau systolique est une architecture spécialisée qui permet d’implanter un algorithme
effectuant un grand nombre de calculs simple de nature identiques. Voici les trois principales
propriétés qui le caractérisent :

-Parallélisme massif : un réseau systolique est constitué d’un nombre de cellules ou processeurs
élémentaires ; une cellule peut effectuer quelques calculs simples ; les cellules peuvent être de
plusieurs types.

-Localité : les cellules sont reliées entre elles, mais uniquement de façons locale : chaque cellule ne
peut être connectée qu’aux cellules voisines (au sens spatial du terme) ; seules les cellules situées à
la frontière du réseau communiquent avec le monde extérieur c’est-à-dire un processeur hôte qui
alimente le réseau en données d’entrée et récupère les résultats en sortie.

-synchronisme : les cellules évoluent en parallèles, sous le contrôle d’une horloge globale les calculs
sont effectués simultanément dans tout le réseau ; à chaque cycle d’horloge, chaque cellule reçoit

- 12 -
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

des données en provenance des cellules voisines, éventuellement complétées par des données de
ses registres internes, effectue un calcul simple, puis transmet les résultats toujours aux cellules
voisines un temps de cycle plus tard.

1.6.1.3. Algorithme de calcul dans une cellule pendant un cycle d’horloge

A l’instant t la cellule renferme une valeur c et reçoit deux nouvelles valeurs (données) a et b venants
des deux cellules voisines supérieures. A l’instant t+1, la valeur enfermée dans la cellule sera ajoutée
par le produit de ces deux nouvelles à fin qu’elle deviendra c’, et a et b iront sortir, puis entreront
pour les deux cellules voisines inferieures.

1.6.1.4. Architecture systolique pour la multiplication des matrices et le fonctionnement


des cellules
A et B sont appelée matrices des données et C matrice résultante.
La représentation de l’architecture est la suivante :
A t=0 b22
b21 b12
b20 b11 b02
b10 b01
b00

a02 a01 a00 C00 C10 C20

a12 a11 a10 C01 C11 C21

a22 a21 a02 C02 C12 C22

Fig. 1.10: Architecture systolique pour la multiplication des matrices 3x3

- 13 -
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

Cij =0.0 ; 0≤i,j≤2.

Et chaque cellule évolue à chaque cycle d’horloge en recevant deux nouvelles valeurs provenant des
cellules voisines ou de la machine hôte, si elle est une cellule frontière en effectuant une addition
de l’ancienne valeur enfermée dans la cellule avec le produit de deux nouvelles valeurs. Ainsi, elle
met, après l’opération, les entrées dans le tampon de sortie. Et les valeurs stockées dans le tampon
de sortie d’une cellule supérieure vont être transmise dans les tampons d’entrées des cellules
voisines inférieures à un temps de cycle plus tard.
Un produit de matrice (n x n) nécessite 3n-2 coups d’horloges.
Schématiquement voici l’évolution de chaque cellule à chaque cycle d’horloge :

A t=1
b22
b21 b12
b20 b11 b02
b10 b01

a02 a01 C00 a00 C10 C20

b00

a12 a11 a10 C01 C11 C21

a22 a21 a20 C02 C12 C22

- 14 -
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

A t=2

b22
b21 b12
b20 b11 b02

a02 C00 a01 C10 a00 C20

b10 b01

a12 a11 C01 a10 C11 C21

b00

a22 a21 a20 C02 C12 C22

- 15 -
Théorie des machines systolique
--------------------------------------------------------------------------------------------------------------------------------------

……..

A t=7
C00 C10 C20

C01 C11 C21

C02 C12 C22 a22

b22

Fig. 1.11: Fonctionnement de l’architecture systolique pour la multiplication des matrices 3x3

1.7. Résumé

La plupart des microprocesseurs modernes ne sont plus entièrement séquentielle, ils sont dotés
de fonctions de parallélisme. Le principal avantage au parallélisme est la vitesse de traitement
mais une espace mémoire plus grande exigée.

On distingue classiquement quatre types des machines parallèles mais on s’intéresse à la machine
SIMD parce que les machines systoliques en font parties. La philosophie de ces dernières est
d’exploiter à la fois le parallélisme de données comme dans les machines cellulaires et le
parallélisme de flux comme dans les machines vectorielles.

Elles empruntent aux machines cellulaires l’organisation générale des processeurs élémentaires.

Elles empruntent aux machines vectorielles le mode de fonctionnement pipeline.

Le processeur systolique est composé de trois éléments essentiels : l’unité de calcul, l’unité de
contrôle et l’unité d’entrée/sortie.

Les machines systoliques recouvrent plusieurs secteurs mais dans ce travail de mémoire nous
étudions spécialement l’architecture systolique pour la multiplication de matrices et le
fonctionnement des cellules.

Brièvement chaque cellule évolue à chaque cycle d’horloge en recevant deux nouvelles valeurs
provenant des cellules voisines ou de la machine hôte, si elle est une cellule frontière en
effectuant une addition de l’ancienne valeur enfermée dans la cellule avec le produit de deux
nouvelles valeurs. Ainsi, elle met, après l’opération, les entrées dans le tampon de sortie. Et les
valeurs stockées dans le tampon de sortie d’une cellule supérieure vont être transmise dans les
tampons d’entrées des cellules voisines inférieures à un temps de cycle plus tard.

- 16 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

Chapitre 2 : Etude du système


2.1. Généralité

On souhaite charger de données dans les buffers. Plusieurs manières sont possibles pour effectuer
l’opération :
 soit à partir des huit commutateurs sur la carte
 soit à partir du port série
 soit à partir de PS/2 extension clavier
 soit à par d’autre moyen à l’aide des ports d’extensions sur la carte.
Comme notre opérande est de 8 bits de chaque, il est impossible d’entrée en même temps les 18
opérandes par les commutateurs. Il faut concevoir une séquence d’opération qui permet d’entrée les
données. Parmi ces plusieurs possibilités cités ci-dessus, nous préférons utiliser le port série.
2.2. Etude des éléments logiques et des éléments combinatoires

Une bonne connaissance des portes logiques est nécessaire avant effectuer une synthèse numérique
sur FPGA. Nous donnons en annexe les bases fondamentales.

- 17 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

2.3. MISE EN ŒUVRE DES SCHEMAS

2.3.1. Schéma bloc du système

1 1
ACQUISITION DE
DONNEES TRANSMETTEUR

Buffer Matrice des PEs Buffer de


d’entrée sortie

Architecture systolique

Unité de contrôle

Fig. 2.1. Schémas bloc du système

2.3.2. Fonctionnement

Le circuit est composé de 4 blocs : Acquisition de données, le systolique proprement dite, le


transmetteur et enfin le cerveau du système L’UNITE DE CONTRÔLE.
Le bloc « Acquisition de donnée » reçoit les données du port série et il les transmet (bit par bit et
poids fort en tête) au registre à décalage série – parallèle 8 bits. Ceci constitue une entrée 8 bits du
démultiplexeur .Ce dernier met chaque donnée à la case mémoire qui la convienne.
Le bloc « Transmetteur » reçoit des données en 16 bits venant des buffers de sortie et il les transmet
au port série bit par bit.

- 18 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

Le bloc « systolique » sera composé de 3 éléments dont :


 Les buffers entrés reçoivent les données du bloc d’acquisition de donnée et les stockent en
attendant un traitement ultérieur.
 Les buffers de sortie mémorisent les résultats de chaque processeur.
 La matrice des PEs est l’unité de traitement des calculs.
L’unité de contrôle fournit un flux d’instruction à l’unité de traitement, à l’acquisition de données et
au transmetteur.
2.4. Circuit détaillé du bloc acquisition de données

2.4.1. Schéma

Voici le schéma détaillé du circuit qui fait l’acquisition de données

Fig. 2.2. Circuit de l’acquisition de données

2.4.2. Fonctionnement

L’entrée input fait passer les bits de données à travers la bascule à chaque fois que le bit de start de
la transmission sérielle est détecté. Le registre décalage série-parallèle 8 bits reçoit les données à
chaque fois que la sortie de la bascule change. Les sorties du registre à décalage constituent une
entrée 8 bits du démultiplexeur. Les sorties de ce dernier seront connectées aux entrées des buffers
d’entrées. L’entrée startandstop enclenche la commande du demux (cmd-demux). Le compteur par 9
après 9 comptages ou l’activation du startandstop enclenche le compteur par 9 et initialise la bascule
(bascule détecteur de bit de start).

- 19 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

2.5. Architecture systolique

2.5.1. Les buffers

Buffer est une mémoire temporaire servant de tampon en attendant un traitement ultérieur.
Ce mémoire est utilisé pour le stockage temporaire de données lors du transfert des informations
afin de compenser la différence de débit, de vitesse de traitement ou de synchronisation entre les
divers dispositifs d'un ordinateur et ses périphériques.

Dans notre architecture, on a deux sortes des buffers dont


 Les buffers d’entrés stockent les 18 coefficients de la matrice A et B en attendant le signal qui
dicte le début du traitement. Ils sont formés par 18 registres de 8 bits qui se divisent en 6
blocs des 3 registres empilés.
 Les buffers de sortie mémorisent les résultats provenant de chaque processeur. Ils sont
formés par les 9 registres de 16 bits.

2.5.2. La machines cellulaire

2.5.2.1. Schéma du circuit

La machine cellulaire est l’unité de traitement ou l’unité arithmétique qui effectue des opérations
arithmétiques. Elle est composée des 9 processeurs identiques dans le cas d’une matrice 3x3 comme
nous le voyions ci-dessous :

Fig. 2.3. Circuit de la machine cellulaire

- 20 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

2.5.2.2. Le fonctionnement

Chaque processeur évolue à chaque cycle d’horloge en recevant deux nouvelles valeurs provenant
des cellules voisines ou de la machine hôte (buffers d’entrés) si elle est une cellule frontière
effectuant une addition de l’ancienne valeur enfermée dans la cellule avec le produit de deux
nouvelles valeurs. Ainsi, elle met, après l’opération, les entrées dans le tampon de sortie. Et les
valeurs stockées dans le tampon de sortie d’une cellule supérieure vont être transmise dans les
tampons d’entrées des cellules voisines inférieures à un temps de cycle plus tard.

2.6. Circuit détaillé du bloc transmetteur de données

2.6.1. Schéma

Voici le schéma détaillé du circuit qui fait le transmetteur de données

Fig. 2.4. Circuit du transmetteur de données

2.6.2. Le fonctionnement

L’objectif de ce bloc est de transmettre les résultats mémorisés dans les buffers de sortie, bit par bit
au port série.

La sortie output de la bascule est connecté au TXD du COM1 tandis que les 9 entrées du premier
multiplexeur, aux buffers de sortie. La sortie 8 bits du deuxième multiplexeur sera générée en bit par

- 21 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

le troisième multiplexeur. L’unité de contrôle commande les sélecteurs du premier et du deuxième


multiplexeur. Il fournit aussi le byte teste qui est l’une des entrées du deuxième multiplexeur.
Enfin, il enclenche le compteur RS232 qui contrôle le troisième multiplexeur et les chargements de
données de la bascule.

2.7. L’unité de contrôle

L’unité de contrôle ou unité de commande (control unit) est responsable du séquençage des
opérations à exécuter. Elle peut recevoir des signaux de contrôle à l’entrée et en produire pour
d’autres unités.
Pour la réalisation, l’unité de contrôle est formée par trois unités de commandes :

• L’unité de commande de l’acquisition de données.


• L’unité de contrôle de l’architecture systolique.
• L’unité de contrôle de transmetteur de données.

2.7.1. L’unité de commande de l’acquisition de données

Dans l’architecture d’acqData (acquisition de données), l’unité de commande est assurée par le
composant cmd_demux (component cmd_demux).
Ses fonctions sont :
• D’activer ou d’inactiver les chargements de données dans les buffers d’entrées
• De contrôler le sélecteur du démultiplexeur.
• D’initialiser tous les registres de l’architecture systolique.

2.7.2. L’unité de contrôle de l’architecture systolique

Dans l’architecture de systolique, l’unité de contrôle est assurée par le composant count74
(component count74).
Il a pour rôle
• D’assurer les chargements de données dans tous les registres et les buffers de sortie
• D’assurer aussi la transmission de données d’une cellule à une autre.

2.7.3. L’unité de contrôle de transmetteur de données

Dans l’architecture DataTransmetter, l’unité de contrôle est assurée par le composant unit-control
(component unit-control). Il commande les sélecteurs de chaque multiplexeur, génère le byte teste
et active le compteur de Rs232.

- 22 -
Etude du système

--------------------------------------------------------------------------------------------------------------------------------------

2.8. Résumé
On souhaite charge de données dans les buffers. Plusieurs manières sont possibles pour effectuer
l’opération. Le pilotage à partir d’un ordinateur grâce au port série facilite le chargement de ces 18
opérandes. Ce port offre de nombreux avantages en particulier il est très bien protégé contre les
fausses manœuvres et autorise la connexion et déconnexion lorsque l’ordinateur est sous tension. Il
faut se souvenir que les signaux disponibles sur ce port n’ont pas le niveau TTL.
 Etat de repos 1 typiquement -10V
 Etat de travail 0 typiquement +10V
L’envoi d’un octet commence par un bit de start (niveau travail) suivi des 8 bits de l’octet.
Le schéma bloc du système est composé de 4 blocs :
 L’acquisition de données reçoit les données du port série et il les transmet aux buffers
d’entrés.
 Le transmetteur de données reçoit les données en 16 bits venant des buffers de sortie et il
les transmet au port série bit par bit.
 Le bloc systolique qui est l’unité de traitement. Il sera composé de 3 éléments dont :
• Les buffers d’entrés
• Les buffers de sortie
• La matrice des processeurs élémentaires.
 L’unité de contrôle fournit un flux d’instruction à l’unité de traitement, à l’acquisition de
données et au transmetteur.

- 23 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

Chapitre 3. L’ARCHITECTURE D’UNE CELLULE


3. 1. Multiplication

Une unité arithmétique effectue des opérations arithmétiques entre des opérandes composés des
nombres qui sont représentés uniquement par des 0 et 1. Ces nombres peuvent être représentés
sous la forme décimale ou binaire. Pour l’étude des schémas bloc de la multiplication des entiers non
signé du circuit arithmétique, on a représenté ces nombres en binaire pour faciliter le calcul. Alors la
multiplication des entiers non signés se ramènent à la multiplication binaire.
3.1.1. Concept de base

Pour mieux comprendre la multiplication binaire, examinons d’abord la multiplication décimale qui
n’utilise que des chiffres 0 et 1.
Exemple :

01012 /* multiplicande
X
01002 /* multiplicateur

0000
0000
0101
0000
000101002 /* produit

Le premier opérande est appelé multiplicande et le second est multiplicateur, le résultat est le
produit.
D’après cet exemple, on peut conclure que la multiplication est en faite une succession d’addition
des produits partiels. Chaque produit partiel est le résultat de la multiplication du multiplicande par
chaque chiffre du multiplicateur en tenant compte de leurs poids respectifs.
Ceci est illustré par l’exemple suivant :

101 x 011 = 101 x 0.102 + 101 x 1.101 + 101x 1.100

- 24 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

En analogie avec la multiplication décimale, la multiplication binaire se différencie de la


multiplication décimale au niveau du chiffre représentant les nombres.
Pour la décimale, les nombres sont représentés à l’aide des chiffre compris entre 0 à 9, tandis qu’au
binaire, on utilise que les chiffres 0 et 1.

Quant on multiple par zéros, le résultat sera donc nul, par contre, pour chaque multiplication du
chiffre de multiplicateur égal à 1, un produit partiel non nul est formé. Ce produit est constitué du
multiplicande décalé d’un certain nombre de positions de manière à aligner son chiffre de poids le
plus faible avec le 1 correspondant du multiplicateur

Exemple :

01012
X
01102

0000
0101
0101
0000
000111102

Ce qui est traduit par la table de vérité de la multiplication suivante :

Multiplicande Multiplicateur Produit


0 0 0
0 1 0
1 0 0
1 1 1

Tableau 3: Table de vérité de la multiplication

Lorsqu’on multiplie le multiplicande par un chiffre du multiplicateur, le produit soit le multiplicande,


soit 0.
Pour la multiplication des entiers binaires non signés, si le nombre de chiffres du multiplicande est n
et le nombre de chiffres du multiplicateur est m, alors on aura un produit de n+m chiffres. Lors de
l’addition des produits partiels, il se peut qu’il y ait un dépassement de la capacité du résultat
(over-flow) mais ça ne crée pas d’erreur parce que la retenue sortante va prendre sa place lors de
prochaine décalage.

3.1.2. Etudes des schémas blocs pour la multiplication :

Des registres de grande capacité ont été considérés pour mieux voir les différences entre les versions
du matériel pour la multiplication.

- 25 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

3.1.2.1. Première version du matériel et de l’algorithme pour la multiplication

16 bits
Multiplicande

UAL Unité de
Multiplicateur
contrôle
8bits

Produit

16 bits

Fig. 3.1 : Première version de la multiplication

On suppose que le multiplicateur est placé dans un registre à décalage 8 bits et que l’ on
utilise un registre de 16 bits pour le produit . Celui –ci étant initialisé à zéro.
Puisque le multiplicande sera décalé vers la gauche d’un chiffre à chaque étape , on le placera
dans la partie droite d’un registre à décalage 16 bits complété par des zéros.
L’UAL est une unité arithmétique et logique qui comporte des opérations arithmétiques telles
que l’ addition , soustraction et des opérations logique ainsi que les fonctions logiques.
Le bit de poids faible du multiplicateur détermine s’il faut ajouter ou non le multiplicande au
produit partiel.
Le sens de décalage des registres est indiqué par la flèche au dessus des registres.

- 26 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

Voici alors l’algorithme correspondant à la première version de la multiplication

Début

Multiplicateur 0= 1

Ajouter le multiplicande au produit.


Placer le résultat dans le registre produit

Décaler le registre multiplicande à gauche de


1 bit

Décaler le registre multiplicateur à droite de 1


bit

8ème répétition

Fin

Fig. 3.2 : Première version de l’algorithme de la multiplication

Si le chiffre le moins significatif du multiplicateur est à 1, le multiplicande sera ajouté au


produit sinon on passe directement à l’ étape suivant, le décalage à gauche du multiplicande
et le décalage à droite du multiplicateur de 1 bit. Ces étapes seront répétées 8 fois pour
avoir le produit.
Problèmes de la première version de matérielle pour la multiplication :
• La moitié des bits du multiplicande est toujours à zéro .
• Une UAL 16 bits est longue et peu économique puisque la moitie des bits de
l’additionneur ajoutait 0 à la somme intermédiaire ce qui augmente le temps de
calcul.

- 27 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------
Causé par les problèmes de la première version, il y avait une apparition de la seconde
version matérielle pour la multiplication.

3.1.2.2. Deuxième version du matériel et de l’ algorithme pour la multiplication

Multiplicande

8 bits

UAL 8bits
Unité de
Multiplicateur
contrôle

16bits
Produit

Fig. 3.3 : deuxième version de la multiplication

Le décalage à gauche du multiplicande dans le premier algorithme fait que les bits de poids
faible du produit ne sont jamais modifies une fois créés.
En se basant sur ceci, on fixe le multiplicande par rapport au produit et on n’additionne que
8bits. Alors la seule moitié gauche du registre produit est modifiée.
Lors de la réinitialisation, les registres 8 bits multiplicande et multiplicateur sont initialisés à
leurs valeurs et le registre de produit est initialisé à zéro.

- 28 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

Voici alors l’algorithme correspondant à la deuxième version de la multiplication

Début

Multiplicateur 0= 1

Ajouter le multiplicande à la moitie gauche


produit. Placer le résultat dans la moitie
gauche du registre produit

Décaler le registre produit à droite de 1 bit

Décaler le registre multiplicateur à droite de 1


bit

8ème répétition

Fin

Fig. 3.4 : Deuxième version de l’algorithme de la multiplication

Si le chiffre le moins significatif du multiplicateur est à 1, le multiplicande sera ajouté à la


moitié gauche du registre produit , sinon on passe directement à l’étape suivant, le décalage
à droite du registre produit et le décalage à droite du multiplicateur de 1bits. Ces étapes
seront répétés 8 fois afin d’avoir le produit.

- 29 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

3.1.2.3. Troisième version du matériel et de l’algorithme pour la multiplication

Multiplicande

Unité de
UAL
contrôle

Produit

Fig. 3.5 :Troisième version de la multiplication

Pour cette dernière version, on utilise que deux registres, l’un est de registre du multiplicande
et l’autre est le registre à décalage du produit
On place le multiplicateur dans la moitié droite du registre produit. Ce qui entraine le test du
bit de poids faible du registre produit. Au départ, le registre 8bits multiplicande est initialisé à
sa valeur. Le multiplicateur est affecté à la partie droite du registre produit et la partie
gauche est initialisée à zéro.

- 30 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

Voici alors l’algorithme correspondant à la troisième version de la multiplication

Début

Produit 0= 1

Ajouter le multiplicande à la moitie gauche


produit. Placer le résultat dans la moitie
gauche du registre produit

Décaler le registre produit à droite de 1 bit

8ème répétition

Fin

Fig. 3.6 : Troisième version de l’algorithme de la multiplication

Si le chiffre le moins significatif du produit est à 1, le multiplicande sera ajouté à la moitié


gauche du registre produit, sinon on passe directement à l’ étapes suivant qui est le décalage à
droite du registre produit de 1 bit. Ces étapes seront répétés 8 fois pour avoir le produit
final.

- 31 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------
3.1.3. Le schéma détaillé du chemin des données de la multiplication

Fig. 3.7: chemin de donnée pour la multiplication

3.2. Etude de chaque composant de la multiplication

3.2.1. Additionneur complet 1 bit

Un additionneur complet réalise l’addition de deux bits Ai et Bi plus le report Ci, en


produisant le bit de résultat Si et le bit de report Ci+1.

Fig. 3.8 : Additionneur complet 1 bit

- 32 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------
3.2.1.1. Table de vérité de l’additionneur complet 1 bit

Ci Ai Bi Si Ci+1
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

Tableau 4 : Table de vérité de l’additionneur complet 1 bit

3.2.1.2. Table de karnaugh

Si Ai Ci+1 Ai
Bi Bi
0 1 0 1 0 0 1 0
Ci 1 0 1 0 Ci 0 1 1 1

Si =A B C + A B C + A B C + A B C
Si = (A B + A B) C + (A B +A B) C
Si = (A B + A B) C + ((A+B) + (A + B)) C
Si = (A B + A B) C + ((A+B)(A + B)) C
Si = (A B + A B) C + (A B +A B) C
Si = A B C

Ci+1= A B + C A + C A B
Ci+1= A B + C (A B + A B)
Ci+1= A B + (A B) C

3.2.1.3. Additionneur complet 8 bits

A l’ aide de l’ additionneur complet, il nous est possible de réaliser itérativement notre


additionneur 8 bits selon le principe de la figure ci-dessous.

Fig. 3. 9: additionneur complet 8 bits

- 33 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

3.2.2. Composant registre d’entrée de donnée (registre 8 bits)

Le schème bloc du registre est comme suit

Fig. 3.10: Composant registre

D est l’entrée de données du registre


Q est la sortie de données du registre
Reset est le signal d’initialisation du registre à zéro
Load est le signal de chargement de données.
Clock est le signal de synchronisation de données

Les données à l’entrée du registre seront chargées dans le registre après le passage du front
montant du signal de synchronisation à condition que le signal de chargement est actif et le
signal d’initialisation est inactif.

Ceci est récapitulé par le tableau suivant :

Reset Load action


0 0 Mémorisation de la sortie
0 1 Chargement de donnée
1 0 Initialisation
1 1 Initialisation

Tableau 5: mode de fonctionnement du registre

3.2.3 : Composant registre à décalage

Dans l’architecture de base du chemin de l’ unité arithmétique la sortie du composant


additionneur est reliée à un registre à décalage dont la taille est deux fois plus grande que la
capacité du composant additionneur. Ce registre est obtenu par concaténation d’un registre de 16
bits, des multiplexeurs et d’un compteur par 9.
Voyons un à un ces composantes.
3.2.3.1: Registre 16 bits sans chargement

Lors de l’opération de la multiplication, un registre de simple capacité de 8 bits ne suffit pas pour
contenir le résultat. De ce fait, on a un registre de 16 bits pour entreposer le résultat de la
multiplication.

- 34 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------
Au départ, les bits de poids faible sont initialisés par le 2ème opérande (ou multiplicateur) et ceux du
poids fort par 0.
A propos des entrées :
 D15 est relié au « serial_inRight », il peut prendre la valeur 0 si Q0 vaut 0 ou TCout (retenue
de l’additionneur) quand Q0 vaut 1.
 D14, D13, D12, D11, D10, D9, D8, D7 sont reliés aux sorties du multiplexeur.
 D6, D5, D4, D3, D2, D1, D0 sont reliés aux sorties Q7, Q6, Q5, Q4, Q3, Q2, Q1.

3.2.3.2. Multiplexeur à deux entrées de 8 bits

Un multiplexeur à deux entrées de 8 bits nous permet de sélectionner l’une des deux sources, selon
la figure ci-dessous.

Fig. 3.11: Multiplexeur à deux entrées

Les 8 entrées « entree1 » sont reliés à la sortie Q8, Q9, Q10, Q11, Q12, Q13, Q14 et Q15 et ceux des
entrées « entree2 » aux sorties d’additionneur. Enfin, l’entrée « Selectentree » est connecté à la
sortie Q0 du registre.
3.2.3.3. Compteur par 9

Ce type de composant, nous sert à compter le nombre de décalage. Après le 8ème décalage, les sorties
Q du registre seront affectés à l’une des entrées de l’additionneur 16 bits
3.2.4. Composant bascule D sans initialisation

Cette bascule sert à la synchronisation de la retenue sortante du composant additionneur lors du


décalage à gauche du registre (Shifter).
On a besoin de synchroniser cette retenue, parce que le circuit combinatoire ADD effectue
l’opération d’addition indépendamment du signal de synchronisation. Or, le registre à décalage a un
retard d’une période pour effectuer son opération de décalage ou de chargement. Pendant ce retard,
il se peut que le circuit combinatoire effectue déjà une nouvelle opération. Si on ne synchronise pas
la retenue sortante de l’opération précédente, lors de décalage du registre, il va prendre en retenue
la nouvelle opération. Pour résoudre ceci, on a utilisé une bascule D qui mémorise l’état de la
retenue sortante du circuit combinatoire ADD et la retenue mémorisé serra lié à l’entrée série de bit
du registre à décalage.

- 35 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------

Schéma bloc de la bascule D sans initialisation :

Fig. 3.12 : composant bascule D sans initialisation

D est l’entrée de la retenue de sortie (Cout) du composant additionneur.


Q est la sortie synchronisée que l’on note TCout dans l’architecture générale du chemin de données
de l’unité arithmétique.
Clock est le signal de synchronisation de la bascule.

3.3. ADDITION

3.3.1. Additionneur de 16 bits

Le composant additionneur est un circuit combinatoire qui effectue l’opération d’addition dès qu’il y
a deux nombres sur ces entrées. Pour notre additionneur, les données d’entrées sont le résultat
obtenu lors de la multiplication et celle qui est mémorisé dans le registre 16 bits. Le résultat sera
présent sur la sortie de l’additionneur après un certain temps de calcul et sera stocké dans le registre
16 bits après un front montant de l’horloge.

Fig. 3.13 : Schémas bloc de l’additionneur

- 36 -
L’architecture d’une cellule
--------------------------------------------------------------------------------------------------------------------------------------
3.4. Résumé

Notre machine systolique est appliquée à la multiplication de deux matrices. Il est donc primordial
de comprendre le concept de base. Le premier opérande est appelé multiplicande et le second
multiplicateur, le résultat est le produit. La multiplication est en faite une succession d’addition des
produits partiels. Chaque produit partiel est le résultat de la multiplication du multiplicande par
chaque chiffre du multiplicateur en tenant compte leurs poids respectifs. Quant on multiple par
zéros, le résultat sera donc nul, par contre, pour chaque multiplication du chiffre de multiplication
égal à 1, un produit partiel non nul est formé. Ce produit est constitué du multiplicande décalé d’un
certain nombre de position de manière à aligner son chiffre de poids le plus faible .D’après ce
principe de base, on peut tirer trois algorithme différents pour la multiplication. Mais on s’intéresse à
la troisième version qui utilise que deux registres.

On additionne le résultat le résulta obtenus lors de la multiplication et celle qui est mémorisé
dans le registre pour satisfaire à la formule.

- 37 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

Chapitre 4 : SYNTHESE SUR FPGA

4.1. LES CIRCUITS FPGA


Le FPGA (Field Programmable Gate Arrays) est un circuit complexe reconfigurable. Il est utilisé
surtout pour la synthèse de circuits numérique pour le développement de prototypes. Certains types
non volatiles peuvent être directement implémentés sur site, mais le coût est relativement élevé par
rapport aux circuits spécialisés.
4.1.1. Propriétés principales
Le FPGA est caractérisé par une matrice de cellules logiques. Chaque cellule est capable de réaliser
une fonction, réalisée par programmation.
Les interconnexions entre les cellules sont programmables également.
Il existe deux types de FPGA, selon la complexité de la cellule :
 Granularité fine
 Granularité grossière
Il existe également deux types, selon le mode de programmation :
 RAM
 Anti-fusibles

4.1.2. Méthodologie de synthèse


Une hiérarchie est à respecter pour en développer une application.
 Saisir le schéma à l’aide d’un éditeur spécialisé ou le synthétiser grâce à un langage
adéquat, entre autres le VHDL ;
 On arrive à avoir le schéma logique ;
 Faire le partitionnement ;
 Placement, dans lequel on choisit l’emplacement physique des différents éléments ;

- 38 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

 Le routage, dans lequel on détermine les connexions entre éléments ;


 Finalement à des bits de configuration.

4.1.3. Les circuits XILINX


Ces circuits ont les principaux aspects suivants :
 Chaque cellule logique, appelée Configurable Logic Block (CLB), est programmée à l’aide
d’une look-up table (LUT).
 Le chargement de la configuration peut prendre plusieurs millisecondes, temps pendant
lequel le circuit est inutilisable.
Plusieurs familles sont disponible, divisées en deux grands groupes :
 Les familles à grain grossier (XC3000, XC400, XC5200, Spartan, Virtex) : il est impossible de
configurer une partie isolée du circuit.
 La famille à grain fin XC6200 : il est possible d’accéder directement à chaque cellule logique.

4.1.4. Module XILINX spartan-3


La carte d’évaluation utilisée pour l’implémentation est le « spartan-3 Starter Kit » qui est constitué
d’un circuit reconfigurable « XILINX XC3S200 Spartan-3 FPGA ». En son périphérique, des
entrées/sorties sons disponibles dont les plus utilisés sont le VGA, RS232, PS2 ainsi il est doté d’une
extension d’entrée/sortie.

4.2. LE LANGAGE VHDL


4.2.1. Généralité sur langage VHDL
Etant acronyme de Very high speed integrated circuit Hardware Description Langage, VHDL est un
langage de description matériel destine à décrire le comportement et/ou l’architecture d’un système
électronique.
En son historique, ce langage a été créé dans le cadre de l’initiative VHSIC commandé par le
Département de la Défense des Etats-Unis.
Le but du langage VHDL est de faciliter le développement d’un circuit numérique en implémentation
la description du fonctionnement et de l’architecture du circuit désirée. Il n’est plus nécessaire de
réaliser un composant réel, on utilise tout simplement les simulateurs. Un simulateur est un
programme permettant de tester le fonctionnement décrit par le programmeur.
Du côté modélisation, en VHDL, un modèle peut être comportemental, structurel ou de type data-
flow.
Quant à la synthèse, le style d’écriture anticipe un primitif circuit.
La synthèse demande une bonne connaissance du circuit et de technologie.

- 39 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.2.2. Méthode de conception adoptée


Plusieurs méthodes sont possibles pour concevoir une application en VHDL. Parmi ces méthodes, on
a adopté la méthode en 3 temps qui est expliqué ci-dessous :
 En premier temps : on fait la description comportementale.
 En deuxième temps : on fait la simulation et la validation
 En troisième temps : on passe à la description structurelle (architecture).
En rapport avec ce projet, il s’agit de faire d’abord les descriptions comportementales des
composants nécessaires à l’ensemble du système systolique. Après, on fera des descriptions
structurelles pour connecter les composants entres eux afin d’obtenir le système voulu.

4.3. CODES VHDL DES COMPOSANTS DU SYSTEME


Pour tous les codes qui suivent, les librairies suivant seront prises en considération.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

4.3.1. Code VHDL de l’inverseur


entity inverseur is
port (entree:in std_logic;
sortie:out std_logic);
end inverseur;

architecture Behavioral of inverseur is


begin
process(entree)
begin
sortie<=not entree;
end process;
end Behavioral;

4.3.2. Code VHDL de l’opérateur AND à 2 entrées


entity and_component is
Port ( EntrAnd1 : in STD_LOGIC;
EntrAnd2 : in STD_LOGIC;
SortAnd : out STD_LOGIC);
end and_component;
architecture Behavioral of and_component is
begin
process (EntrAnd1, EntrAnd2)
begin
4.3.3. CodeSortAnd
VHDL<= deEntrAnd1 and EntrAnd2;
l’opérateur OR à 2 entrées
end process;
end Behavioral;
- 40 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.3. Code VHDL de l’opérateur OR à 2 entrées

entity or_component is
Port ( EntrOr1 : in STD_LOGIC;
EntrOr2 : in STD_LOGIC;
SortOr : out STD_LOGIC);
end or_component;

architecture Behavioral of or_component is

begin
process (EntrOr1, EntrOr2)
begin
SortOr <= EntrOr1 or EntrOr2;
4.3.4.
endCode VHDL de L’opérateur XOR à 2 entrées
process;
end Behavioral;

4.3.4. Code VHDL de l’opérateur XOR à 2 entrées

entity xor_component is
Port ( EntrXor1 : in STD_LOGIC;
EntrXor2 : in STD_LOGIC;
SortXor : out STD_LOGIC);
end xor_component;

architecture Behavioral of or_component is

begin
process (EntrXor1, EntrXor2)
begin
SortXor <= EntrXor1 xor EntrXor2;
end process;
end Behavioral;

- 41 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.5. Code de la bascule D avec remise à zéro

entity BasculeDRaz is
Port ( Clk : in STD_LOGIC;
Enable : in STD_LOGIC;
Clear: in STD_LOGIC;
EntrD : in STD_LOGIC;
SortQ : out STD_LOGIC);
end BasculeDRaz;

architecture Behavioral of BasculeDRaz is

signal tmp : STD_LOGIC:='0';


begin
process (Clk, Clear, Enable)
begin
if (Enable='1') then
if (Clear ='1') then
tmp <= '0';
elsif (Clk'event and Clk='1') then
tmp <= EntrD;
end if;
end if;
end process;
SortQ <= tmp;
end Behavioral;

Résultat : Voici le schéma généré par le compilateur

Fig. 4.1 : bascule D avec remise à zéro

- 42 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.6. Code VHDL d’un Module qui détecte le bit de start

entity detecte_bit_start is
Port ( EntrMono : in STD_LOGIC;
Clear : in STD_LOGIC;
SortMono : out STD_LOGIC);
end detecte_bit_start;

architecture Behavioral of detecte_bit_start is


signal tmp : STD_LOGIC:='0';
begin
process (EntrMono)
begin
if (Clear='1') then
tmp <= '0';
elsif (EntrMono'event and EntrMono='0') then
tmp <= '1';
end if;
end process;
SortMono <= tmp;
end Behavioral;

Résultat : Voici le schéma généré par le compilateur

Fig. 4.2. Détecteur de bit de start

- 43 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.7. Code VHDL du compteur par 9

entity compteurpar9 is
Port ( clock : in STD_LOGIC;
clear : in STD_LOGIC;
clean : out STD_LOGIC;
count9 : out STD_LOGIC_VECTOR (3 downto 0));
end compteurpar9;

architecture Behavioral of compteurpar9 is

signal tmp:std_logic_vector(3 downto 0):="0000";


signal Sclean:std_logic:='0';

begin
process(clock,clear)
begin
if (clear='1')then
tmp<="0000";
Sclean<='0';
elsif (clock'event and clock='1') then
tmp<=tmp+1;
if (tmp="1000") then
SClean<='1';
end if;
end if;
end process;
clean<=Sclean;
count9<=tmp;
end Behavioral;

Résultat : Voici le schéma généré par le compilateur

Fig.4.3 : compteur par 9

- 44 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.8. Code VHDL de démultiplexeur

entity demultiplexeur is
Port ( selectentree : in STD_LOGIC_vector(17 downto 0);
entree : in STD_LOGIC_VECTOR (7 downto 0);
a11 : out STD_LOGIC_VECTOR (7 downto 0);
a12 : out STD_LOGIC_VECTOR (7 downto 0);
a13 : out STD_LOGIC_VECTOR (7 downto 0);
a21 : out STD_LOGIC_VECTOR (7 downto 0);
a22 : out STD_LOGIC_VECTOR (7 downto 0);
a23 : out STD_LOGIC_VECTOR (7 downto 0);
a31 : out STD_LOGIC_VECTOR (7 downto 0);
a32 : out STD_LOGIC_VECTOR (7 downto 0);
a33 : out STD_LOGIC_VECTOR (7 downto 0);
b11 : out STD_LOGIC_VECTOR (7 downto 0);
b12 : out STD_LOGIC_VECTOR (7 downto 0);
b13 : out STD_LOGIC_VECTOR (7 downto 0);
b21 : out STD_LOGIC_VECTOR (7 downto 0);
b22 : out STD_LOGIC_VECTOR (7 downto 0);
b23 : out STD_LOGIC_VECTOR (7 downto 0);
b31 : out STD_LOGIC_VECTOR (7 downto 0);
b32 : out STD_LOGIC_VECTOR (7 downto 0);
b33 : out STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0));
end demultiplexeur;

architecture Behavioral of demultiplexeur is


begin
process(selectentree,entree) is
begin
case selectentree is
When "000000000000000001"=>a11<=entree; --1
When "000000000000000010"=>b11<=entree; --2
When "000000000000000100"=>a12<=entree; --4
When "000000000000001000"=>b12<=entree; --8
When "000000000000010000"=>a21<=entree; --16
When "000000000000100000"=>b21<=entree; --32
When "000000000001000000"=>a13<=entree; --64
When "000000000010000000"=>b13<=entree; --128
When "000000000100000000"=>a22<=entree; --256
When "000000001000000000"=>b22<=entree; --512
When "000000010000000000"=>a31<=entree; --1024
When "000000100000000000"=>b31<=entree; --2048
When "000001000000000000"=>a23<=entree; --4096
When "000010000000000000"=>b23<=entree; --8192
When "000100000000000000"=>a32<=entree; --16384
When "001000000000000000"=>b32<=entree; --32768
When "010000000000000000"=>a33<=entree; --65536
When "100000000000000000"=>b33<=entree; --131072
When others => sortie<=(others=>'0');
end case; end process;
end Behavioral;
- 45 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.9. Code VHDL de multiplexeur

entity multiplexeur is
Port ( entree1 : in STD_LOGIC_VECTOR (3 downto 0);
entree2 : in STD_LOGIC_VECTOR (3 downto 0);
entree3 : in STD_LOGIC_VECTOR (3 downto 0);
entree4 : in STD_LOGIC_VECTOR (3 downto 0);
sortie : out STD_LOGIC_VECTOR (3 downto 0);
selectentree : in STD_LOGIC_VECTOR (1 downto 0));
end multiplexeur;

architecture Behavioral of multiplexeur is

begin
process(selectentree,entree1,entree2,entree3,entree4)
begin
case selectentree is
when "00" => sortie<=entree1;
when "01" => sortie<=entree2;
when "10" => sortie<=entree3;
when "11" => sortie<=entree4;
when others=>null;
end case;
end process;
end Behavioral;

4.3.10. Code VHDL de l’additionneur complet 1 bit

entity add is
Port ( opA : in STD_LOGIC;
opB : in STD_LOGIC;
Cin : in STD_LOGIC;
Cout : out STD_LOGIC;
Result : out STD_LOGIC);
end add;

architecture Behavioral of add is


begin
Process(opA,opB,Cin)
begin
Result<=opA xor opB xor Cin;
Cout<=(opA and opB) or (Cin and (opA xor opB));
end process;
end Behavioral;

- 46 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.11. Code VHDL de l’additionneur complet 8 bit

architecture Behavioral of full_add is

component add is
port(
opA : in STD_LOGIC;
opB : in STD_LOGIC;
Cin : in STD_LOGIC;
Result : out STD_LOGIC;
Cout : out STD_LOGIC
);
end component;
signal C: STD_LOGIC_VECTOR(0 to 8);
begin
bloc: for i in 0 to 7 generate
instance: add
port map (opA(i), opB(i),C(i) ,Result(i), C(i+1));
end generate bloc;
C(0)<=Cin;
Cout <= C(8);

end Behavioral;

Résultat : Voici le schéma généré par le compilateur

Fig.4.4. additionneur complet 8 bit

- 47 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.12. Code source du registre à décalage (shifter)

entity shifter is
Port ( clock : in STD_LOGIC;
resetSR : in STD_LOGIC;
clear : out STD_LOGIC;
Q: out std_logic_vector(15 downto 0);
Result: out std_logic_vector(15 downto 0);
operande2: in std_logic_vector(7 downto 0);
entree2: in std_logic_vector(15 downto 8);
serial_inRight : in STD_LOGIC);
end shifter;

architecture Behavioral of shifter is


signal Sclear: std_logic;
signal SQ: std_logic_vector(15 downto 0);
signal tempo:std_logic_vector(3 downto 0):="0000";

begin
process(clock,resetSR)
begin

if resetSR='1' then
SQ<="00000000"&operande2;
tempo<="0000";
elsif (clock'event and clock='1') then
tempo<=tempo+1;
if (SQ(0)='1') then
SQ(6 downto 0)<=SQ(7 downto 1);
SQ(14 downto 7)<=entree2(15 downto 8);
SQ(15)<=serial_inRight;
else
SQ(15)<='0';
SQ(14 downto 7)<=SQ(15 downto 8);
SQ(6 downto 0)<=SQ(7 downto 1);

end if;
if (tempo=8) then
result<=SQ;
Sclear<='1';
end if;
end if;
end process;
Q<=SQ;
clear<=Sclear;
end Behavioral;

- 48 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.13. Le code VHDL correspondant à la bascule D :

entity bascule_D is
Port ( clock : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end bascule_D;

architecture Behavioral of bascule_D is


signal SQ:std_logic;
begin
process(clock) is
begin
if(clock='1' and clock'event)then
SQ<=D;
end if;
end process;
Q<=SQ;
end Behavioral;

Résultat : Voici le schéma généré par le compilateur

Fig.4.5. bascule D

- 49 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.3.14. Le code VHDL d’un registre 8 bits avec affectation après 8ème coups d’horloge

entity registre8 is
Port ( ResetR : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (7 downto 0);
sortie_affect : out STD_LOGIC_VECTOR (7 downto 0);
Q : out STD_LOGIC_VECTOR (7 downto 0));
end registre8;

architecture Behavioral of registre8 is


signal SQ:std_logic_vector (7 downto 0);
signal tmp:std_logic_vector(7 downto 0):="00000000";
signal vase1,vase2,vase3:std_logic_vector (7 downto 0);

begin
process(clock,ResetR) is
begin
if ResetR='1' then
SQ<=(others=>'0');
tmp<="00000001";
Elsif clock='1' and clock'event then
if load='1' then
SQ<=D;
tmp<=tmp + 1;
end if;
if (tmp=2) then
vase1<=D;
end if;
if (tmp=9) then
sortie_affect<=vase1;
end if;
if (tmp=12) then
vase2<=D;
end if;
if (tmp=19) then
sortie_affect<=vase2;
end if;
if (tmp=22) then
vase3<=D;
end if;
if (tmp=29) then
sortie_affect<=vase3;
end if;
end if;
end process;
Q<=SQ;
end Behavioral;

- 50 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.4. Code VHDL d’acquisition


4.4.1. Entité

entity acqdata is
Port ( Clock : in STD_LOGIC;
input : in STD_LOGIC;
startandstop : in STD_LOGIC;
load_buf:out STD_LOGIC;
Sbitstart:out STD_LOGIC;
SRaz:out STD_LOGIC;
a11 : out STD_LOGIC_VECTOR (7 downto 0);
b11 : out STD_LOGIC_VECTOR (7 downto 0);
a12 : out STD_LOGIC_VECTOR (7 downto 0);
b12 : out STD_LOGIC_VECTOR (7 downto 0);
a21 : out STD_LOGIC_VECTOR (7 downto 0);
b21 : out STD_LOGIC_VECTOR (7 downto 0);
a13 : out STD_LOGIC_VECTOR (7 downto 0);
b13 : out STD_LOGIC_VECTOR (7 downto 0);
a22 : out STD_LOGIC_VECTOR (7 downto 0);
b22 : out STD_LOGIC_VECTOR (7 downto 0);
a31 : out STD_LOGIC_VECTOR (7 downto 0);
b31 : out STD_LOGIC_VECTOR (7 downto 0);
a23 : out STD_LOGIC_VECTOR (7 downto 0);
b23 : out STD_LOGIC_VECTOR (7 downto 0);
a32 : out STD_LOGIC_VECTOR (7 downto 0);
b32 : out STD_LOGIC_VECTOR (7 downto 0);
a33 : out STD_LOGIC_VECTOR (7 downto 0);
b33 : out STD_LOGIC_VECTOR (7 downto 0));
end acqdata;

4.4.2. Architecture
Architecture d’acqData est composée des composants suivants

component and_component
component or_component
component detecte_bit_start
component registre_serie_parallele
component Horloge
component ctrl_demux

- 51 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

Résultat du programme :

Fig. 4.6. Acquisition de données

4.5. Code VHDL du circuit d’une cellule


4.5.1. Entité

entity processeur is
Port ( clock : in STD_LOGIC;
load : in STD_LOGIC;
Reset : in STD_LOGIC;
resetSR : in STD_LOGIC;
Cin : in STD_LOGIC;
Sclear : in STD_LOGIC;
operande1: in std_logic_vector(7 downto 0);
operande2: in std_logic_vector(7 downto 0);
sortie_affect: out std_logic_vector(7 downto 0);
Saffect_op2 : out std_logic_vector(7 downto 0);
fin: out std_logic_vector(15 downto 0));
end processeur;

- 52 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.5.2. Architecture
Architecture structurelle d’un processeur est composée des composants suivants

component registre8
component full_add
component bascule_D
component shifter
component additionneur16
component registre16

Résultat du programme :

Fig. 4.7. Architecture d’une cellule

- 53 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

4.6. Code VHDL Datatransmitter


4.6.1. Entité

entity datatransmetter is
Port ( clock : in STD_LOGIC;
Reset : in STD_LOGIC;
c11: in STD_LOGIC_VECTOR(15 downto 0);
c12: in STD_LOGIC_VECTOR(15 downto 0);
c21: in STD_LOGIC_VECTOR(15 downto 0);
c13: in STD_LOGIC_VECTOR(15 downto 0);
c22: in STD_LOGIC_VECTOR(15 downto 0);
c31: in STD_LOGIC_VECTOR(15 downto 0);
c23: in STD_LOGIC_VECTOR(15 downto 0);
c32: in STD_LOGIC_VECTOR(15 downto 0);
c33: in STD_LOGIC_VECTOR(15 downto 0);
output : out STD_LOGIC);
end datatransmetter;

4.6.2. Architecture
Architecture Datatransmitter est composée des composants suivants

component Mux2
component Decalage
component RS232Compteur
component or2entre
component inverseur
component timing
component unit_control
component mux_9
component memoire8
component mux8

- 54 -
Synthèse sur FPGA
---------------------------------------------------------------------------------------------------------------------------

Résultat du programme :

Fig. 4.8. Architecture d’une transmission de donnée

- 55 -
Simulation et réalisation
--------------------------------------------------------------------------------------------------------------------------------------

Chapitre 5. SIMULATION ET REALISATION

5.1. SIMULATION

La simulation consiste à obtenir les chronogrammes que l’on analysera par rapport au
fonctionnement désiré. Avant tout, on a besoin de la configuration de l’horloge et la génération du
fichier de simulation appelé « Test Bench Wave Form ».Ce fichier sera nommé systorice.tbw
5.1.1. Configuration de l’horloge

On voit dans cette capture d’écran ci-dessous que la simulation s’effectue à la fréquence de 25 MHz
(période 40ns).

Fig. 5.1: Configuration de l’horloge

Une fois l’horloge configurée, on passe à la simulation proprement dite du circuit.

- 56 -
Simulation et réalisation
--------------------------------------------------------------------------------------------------------------------------------------
5.2. REALISATION

D’après la simulation, on peut dire que le circuit répond bien au fonctionnement désiré. On passe
maintenant à la réalisation proprement dite.
Cette partie consiste à programmer le circuit reconfigurable FPGA disponible au laboratoire
d’informatique appliquée de l’ESP. Quelques étapes sont nécessaires.

5.2.1. Processus « Synthesize-XST »

Ce processus assure la traduction code source en son équivalence circuit logique. Il fait des tests
standards et avancés des syntaxes du programme. Il génère ensuite le schéma de principe et le
schéma technologique du code VHDL. Il génère automatique les rapports de la synthèse en question
pour faire des vérifications en cas d’erreur de synthèse.

5.2.2. Création du fichier de contrainte systorice.ucf

Ce fichier permet de spécifier les différents timings dont avec lesquels le circuit va s’adapter. Un de
très important est de bien gérer le slack et clock skew.
On a généré les contraintes sur les timings selon la configuration par défaut en exécutant les
processus « Timing Analyzer ».

Slack : C’est la marge par laquelle la contrainte de la fréquence maximale est respectée ou pas. Un
slack négatif indique que la contrainte de la fréquence maximale n’est pas respectée.

Slack = période d’horloge requise – période d’horloge obtenue

Fig. 5.2:slack

Clock Skew : c’est la différence entre le temps d’arrivée d’un signal d’horloge à deux registres
différents. Cela peut arriver si la longueur des deux trajectoires est très différente.

Fig 5.3: Déphasage d’horloge (clock skew)

- 57 -
Simulation et réalisation
--------------------------------------------------------------------------------------------------------------------------------------
Dans un circuit synchrone, les fils et les interconnexions induisent des délais lors de la propagation
du signal d’horloge. Le signal d’horloge arrive donc aux différentes parties du circuit à des instants
différents. Ce phénomène de déphasage de l’horloge est un point important dans la conception des
circuits synchrones car la validité des données et la consommation dans le circuit en dépend.
5.2.3. Implémentation

Cette partie exécute trois processus


 Translate
 Map
 Place&Route
Les propriétés suivantes sont recommandées :
 Place & Route Effort Level [Overall] :High
 Post-Map Static Timig Report Properties: verbose Report
 Post-Place & Route Static Timing Report Properties: Verbose Report
Assign Package Pins:

Dans la section Translate, on a configuré les pins de FPGA à notre circuit systolique de la façon
suivante :

Fig 5.4: Assign Package Pins

5.2.4. Génération du fichier de programme

Le fichier systorice.bit, systorice.mcs sont requis avant de changer le programme dans le FPGA. Cette
partie exécute les processus :
 Generate PROM, ACE, JTAG File
 Configure Device [iMPACT]
Les propriétés suivantes sont requises :
 Mettre le FPGA Startup clock : JTAG Clock
 Property Display Level : Avanced

- 58 -
Simulation et réalisation
--------------------------------------------------------------------------------------------------------------------------------------
Après avoir tout configuré, on a les deux fichiers illustrés par la figure suivante :

Fig. 5.5 : Fichier de programme

Maintenant, il ne reste qu’à lancer le chargement du fichier systorice.bit vers le FPGA, pour cela, on a
utilisé la câble parallèle JTAG qui relie le module Spartan 3 et l’ordinateur en passant par le port
parallèle.
Après le chargement, le message suivant dit que la programmation de FPGA par notre programme a
réussi.

Fig. 5.6: programmation réussie

5.3. Mise en œuvre de la communication sérielle selon le protocole RS232 défini sur
Spartan3

La communication sérielle selon le protocole RS232 est possible en ce module d’FPGA. Une
entrée/sortie série est définie sur cette carte de développement. Il s’avère que sur Spartan 3 cette
interface est câblée de façon qu’on utilise seulement les pins TXD et RXD respectivement les pins 2 et
3. A l’entrée de FPGA, le signal est déjà converti au niveau TTL grâce au circuit Maxim MAX3232.

- 59 -
Simulation et réalisation
--------------------------------------------------------------------------------------------------------------------------------------

Fig. 5.7: RS-232 Serial Port

5.3.2. Broches du port séries et FPGA pins

Signal FPGA pin


RXD T13
TXD R13

Tableau 6 : Broches du port séries et FPGA pins

- 60 -
Le logiciel SystoRice
--------------------------------------------------------------------------------------------------------------------------------------

Chapitre 6 : Le logiciel SystoRice

6.1. Généralité

A titre d’essai du module, on a fait des transferts de données entre l’ordinateur et la carte spartan 3.
Pour cela, on a conçu un logiciel simple avec des raccourcis clavier, développé sous l’environnement
Delphi.
Comme tous les logiciels qui ont ses propres noms, le notre se nomme SystoRice avec S et R en
majuscule. La dénomination SystoRice provient de deux mots systolique plus matrice plus
explicitement l’architecture systoique appliquée au produit matriciel.
Le programme a été conçu selon le fonctionnement de la partie UART du circuit pour pouvoir
communiquer.

6.2. Les onglets


SystoRice a trois onglets
 Step by step
 On the wing
 Implementation of datums in FPGA

Les deux premiers onglets servent pour mieux comprendre le principe de fonctionnement de
l’architecture systolique appliquée au produit matriciel, tandis que le troisième sert à implémenter
dans la carte, les coefficients des matrices de données et de recevoir les coefficients de la matrice
résultant.

- 61 -
Le logiciel SystoRice
--------------------------------------------------------------------------------------------------------------------------------------

6.2.1. L’onglet « step by step »

Fig.6.1. L’interface de l’onglet « step by step »

6.2.1.1. Présentation de l’interface


Comme nous avons vu dans la partie théorique de l’architecture systolique. Il est composé de trois
éléments
 L’unité de calcul : La partie en bleue
 L’unité d’entrée/sortie : La partie haute et celle qui se trouvent à l’entour de l’unité de calcul.
 L’unité de contrôle : Qu’on ne voit pas sur l’interface

6.2.1.2. Principe d’utilisation et fonctionnement

 Pour démarrer, on clique sur l’onglet step by step


 En premier temps seul le bouton initialize est activé. Le bouton start process sont active en
commutation avec le bouton initialize.

- 62 -
Le logiciel SystoRice
--------------------------------------------------------------------------------------------------------------------------------------

 On saisit les valeurs de la matrice A et celle de la matrice B dans les Edits qui les corresponds.
Ensuite, on clique sur le bouton initialize pour entrer les coefficients dans les trames
d’entrée.
 On clique sur le bouton start process, nous voyons l’évolution systolique étape par étape.

6.2.2. L’onglet « On the wing »


En son principe de fonctionnement, cet onglet est similaire au celui de step by step.

6.2.3. L’onglet « implementation of datums in FPGA »

Ce programme utilise la librairie DLL de Burkhard Kainka qui permet d’avoir un accès direct sur les
différentes lignes du port série. Cette librairie DLL est un fichier (« Rscom.dll ») qui comporte des
fonctions et des procédures pouvant être appelées par le programme principal.
Ce fichier est téléchargeable dans le site : http://delpipage.free.fr/programmes/portserie.zip
Nous avons utilisé de ce fichier les procédures et les fonctions suivantes :

Fig.6.2. L’onglet « implementation of datums in FPGA »

- 63 -
Le logiciel SystoRice
--------------------------------------------------------------------------------------------------------------------------------------

6.2.3.1. Présentation de l’interface

La partie haute sert à connecter et déconnecter le logiciel au port série. La partie basse gauche sert à
entrer les valeurs de matrice A et B qu’on veut calculer sa produit. La partie basse droite sert à
l’affichage des résultats.

6.2.3.2. Principe d’utilisation et fonctionnement du logiciel

• On connecte d’abord la carte à l’ordi.


• Pour démarrer, on clique sur l’onglet implementation of datums in FPGA.
• En premier temps seuls les boutons « connexion », « Effacer » et « Fermer » sont activés.
Les boutons « Déconnexion » et « Envoyer » sont active en commutation avec le bouton
« connexion ».
• Le bouton « connexion » donne l’accès à l’ouverture du port COM1 de l’ordinateur; un bar
de progression anime la mise en ouverture du port et une fois connecté, un label
« connecté.. » est affiché.
• On saisit les valeurs de la matrice A et celle de la matrice B dans les Edits qui les corresponds.
Et un bouton « Envoyer » permet d’enclencher la procédure d’envoie des valeurs saisies un à
un (octet par octet).
• L’octet ainsi envoyé traverse le pin TXD du COM1 et mémorisé par le ROM de la carte.
• Chaque cellule traite les valeurs destinées à elle et l’envoie à l’ordinateur en passant par le
pin RXD du COM1.
• La procédure de la lecture du port série est toujours en exécution et fait la lecture toute les
millisecondes. Le message est affiché dans les labels à droit.

- 64 -
Conclusion

Au terme de cette analyse, nous pouvons dire que le vif objectif de ce projet est atteint. Il
s’agit de synthétiser une architecture systolique sur FPGA tout en commençant par comprendre
l’étude théorique que l’ancien étudiant à fait et de mettre en œuvre ces algorithmes appropriés.

L’étude de l’architecture systolique nous a donnée des connaissances plus approfondies sur
les logiques combinatoires et séquentielles, une bonne initiation au langage VHDL et à la mise en
œuvre du circuit FPGA. Cette partie nous a permis de maîtriser la configuration du logiciel de
simulation Modelsim et le logiciel de développement XILINX ISE 8.i1.

Un logiciel nommé « systorice » a été développé en Delphi pour avoir un exemple


d’utilisation du module ainsi réalisé tel que la transmission de données entre la carte FPGA Spartan 3
et un ordinateur dont ils communiquent entre eux par une liaison série.

Bref, la conception nécessite des connaissances en électronique et en informatique


industriel.

- 66 -
BIBLIOGRAPHIE

[1] Cours d’informatique industrielle ANDRIANIVOSOA Ramamonjy

[2] Cours d’électronique et de logique SAONA Jean Basile

[3] Cours de programmation avancée ANDRIANIVOSOA Ramamonjy

[4] Cours de VHDL ANDRIANIVOSOA Ramamonjy

[5] Spartan 3 Starter Kit Board User Guide Xilinx

[6] Synthèse d’un circuit de codage/décodage JAOMALAZA Philemon


polynomial sur FPGA

[7] Machines Cellulaires et Systoliques Jean-Paul Sansonnet

WEBOGRAPHIE
[1] www.xilinx.com

[2] http://cat.inist.com/Algorithmes systoliques de la théorie à la pratique = Systolic.htm

[3] http://delphipage.free.fr/programmes/porserie.zip
ANNEXE
1. Les éléments logiques de base et des éléments combinatoires

1.1. L’opération NOT ou inverseur

Une porte logique inverseur sert à inverser l’état d’une entrée d’une entrée donnée.
Il est représenté par le symbole suivant dont la table de vérité décrivant son fonctionnement est ci-
contre :

Entrée Sortie
Entrée Sortie
0 1

1 0

Fig. 1 : Symbole de l’opérateur NOT

1.2. L’opérateur ET (en anglais AND) à 2 entrées

Un « ET » sert à effectuer une opération de multiplication entre les nombres binaires.

Entrée 1 Entrée 2 Sortie


Entrée1
Sortie 0 0 0
Entrée2
0 1 0

1 0 0

1 1 1

Fig.2 : Symbole de l’opérateur AND

1.3. L’opérateur OU (en anglais OR) à 2 entrées

L’opérateur OU sert à effectuer une addition entre les nombres binaires.

Entrée1 Entrée2 Sortie

Entrée1 0 0 0
Sortie
Entrée2 0 1 1

1 0 1

1 1 1

Fig. 3. Symbole de l’opérateur OR


1.4. L’opérateur OU-Exclusif (en anglais : XOR)

Entrée1
Sortie Entrée1 Entrée2 Sortie
Entrée2
0 0 0

0 1 1

1 0 1

1 1 0

Fig. 4. Symbole de l’opérateur XOR à 2 entrées

1.5. La bascule D (Flip flop)

Une bascule D (Delay) est obtenue à partir d’une bascule J-K en envoyant simultanément une donnée
sur l’entrée J et son inverse sur l’entrée K.

Fig. 5 : Schémas de principe de la bascule D

A partir de la table de vérité d’une bascule J-K nous pouvons écrire :

Ce qui peut se résumer par Q n+1=D n. Ainsi l’état de la bascule Q pendant l’intervalle n+1 est égal à la
valeur de l’entrée D pendant l’intervalle n. Une bascule D agit comme une unité à retard pour
laquelle la sortie suit l’entrée avec un cycle de retard. Sa représentation
Fig. 6 : Symbole de la bascule D

1.6. Les registre à décalage

Dans un registre à décalage les bascules sont interconnectées de façons à ce que l’état logique de la
bascule de rang n puisse être transmis à la bascule de rang n+1 quand un signal d’horloge est
appliqué à l’ensemble des bascules. L’information peut être chargée de deux manières dans ce type
de registre.
Entrée parallèle

Comme dans le cas d’un registre de mémorisation, en général une porte d’inhibition est nécessaire
pour éviter tout risque de décalage pendant le chargement parallèle.
Entrée série

L’information est présentée séquentiellement bit après bit à l’entrée de la première bascule. A
chaque signal d’horloge un nouveau bit est introduit pendant que ceux déjà mémorisés sont décalés
d’un niveau dans le registre. La figure suivante schématise le chargement d’un registre 4 bits en
quatre coups d’horloge.

a4

a3 a4 top n°1

a2 a3 a4 top n°2

a1 a2 a3 a4 top n°3

top n°4
a1 a2 a3 a4

fig. 7: Chargement d’un registre 4 bits en 4 coups d’horloge

De même, l’information peut être lue en série ou en parallèle. Mais ce qui nous intéresse, c’est la
sortie parallèle.
1.7. Entrée série – sortie parallèle

La figure suivante donne un exemple de registre de 8 bits à entrée série et sortie parallèle réalisé
avec des bascule D.
Fig. 8 : Registre série – parallèle

1.8. Multiplexeur

Un multiplexeur utilise le principe de l’aiguillage. C’est un circuit à 2n entrées d’information, n


entrées d’adresse et une sortie. Si on applique une adresse i sur BA (B étant le poids fort, A le poids
faible), l’état de l’entrée d’information de rang i est affiché en sortie. Généralement, un multiplexeur
comporte un décodeur d’adresse et des portes permettant l’aiguillage. La figure suivante schématise
le principe d’un multiplexeur.

Fig. 9 : principe d’un multiplexeur

Décodeur

C’est un circuit à n entrées dites adresse et 2n Sorties où une seule est active à la fois. Le rang de la
sortie active correspond à la valeur binaire affichée sur les entrées d’adresses. Ce circuit s’utilise
essentiellement pour choisir un seul élément parmi 2n.
La figure suivante schématise le principe de décodeur.
Fig. 10 : Principe du décodage

1.9. Démultiplexeurs

Un démultiplexeur est un circuit combinatoire à N+1 entrées et 2N sorties. N entrées, appelées


entrées d’adressage, permettent d’envoyer sur l’une des sorties la dernière entrée, appelée l’entrée
donnée.

Table de vérité

Prenons le cas du circuit 74 ALS 139 pour étudier le diagramme fonctionnel d’un démultiplexeur. Ce
circuit comporte deux décodeurs 2 vers 4 .Chacun d'eux possède 4 sorties nommées S0, S1, S2 et S3,
et deux entrées de sélection A et B. Il possède également une entrée E, qui doit être mise à 0 pour
que le circuit fonctionne en décodeur :

E A B S0 S1 S2 S3
1 x x 1 1 1 1
0 0 0 0 1 1 1
0 0 1 1 0 1 1
0 1 0 1 1 0 1
0 1 1 1 1 1 0

Tableau.1 : Table vérité d’un démultiplexeur

Où l'on peut noter que la sortie sélectionnée est à 0, tandis que les lignes inactives sont à 1.
Equation des sorties

L'équation des quatre sorties se déduit de la table de vérité :


Diagramme fonctionnel

L'équation des sorties permet de proposer le diagramme fonctionnel :

Fig. 11 : diagramme fonctionnel d’un démultiplexeur


--------------------------------------- Listing des codes sources du programme VHDL -------------------------------

---------------------un processeur élémentaire-----------------------------------------------------------------------------


entity processeur is
Port ( clock : in STD_LOGIC;
load : in STD_LOGIC;
Reset : in STD_LOGIC;
resetSR : in STD_LOGIC;
Cin : in STD_LOGIC;
Sclear : in STD_LOGIC;
operande1: in std_logic_vector(7 downto 0);
operande2: in std_logic_vector(7 downto 0);
sortie_affect: out std_logic_vector(7 downto 0);
Saffect_op2 : out std_logic_vector(7 downto 0);
fin: out std_logic_vector(15 downto 0));
end processeur;
-------------------------------------------------------------------------------------------------------------------------------------
architecture Behavioral of processour is
-------------------------------------------------------------------------------------------------------------------------------------
component registre8 is
Port ( ResetR : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (7 downto 0);
sortie_affect : out STD_LOGIC_VECTOR (7 downto 0);
Q : out STD_LOGIC_VECTOR (7 downto 0));
end component;
------------------------------------------------------------------------------------------------------------------------------
component full_add is
Port ( opA : in STD_LOGIC_VECTOR (7 downto 0);
opB : in STD_LOGIC_VECTOR (7 downto 0);
Cin : in STD_LOGIC;
Cout : out STD_LOGIC;
Result : out STD_LOGIC_VECTOR (7 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
component bascule_D is
Port ( clock : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end component;
----------------------------------------------------------------------------------------------------------------------------------
component shifter is
Port ( clock : in STD_LOGIC;
resetSR : in STD_LOGIC;
Q: out std_logic_vector(15 downto 0);
Result: out std_logic_vector(15 downto 0);
affect_op2: out std_logic_vector(7 downto 0);
operande2: in std_logic_vector(7 downto 0);
entree2: in std_logic_vector(15 downto 8);
serial_inRight : in STD_LOGIC);
end component;
------------------------------------------------------------------------------------------------------------------------------
component additionneur16 is
Port ( opA : in STD_LOGIC_VECTOR (15 downto 0);
opB : in STD_LOGIC_VECTOR (15 downto 0);
Cin : in STD_LOGIC;
Cout : out STD_LOGIC;
Result : out STD_LOGIC_VECTOR (15 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
component registre16 is
Port ( ResetReg : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (15 downto 0);
Q : out STD_LOGIC_VECTOR (15 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
signal SQ_Reg8:std_logic_vector(7 downto 0);
signal SQ_Reg16:std_logic_vector(15 downto 0);
signal S_Resultadd16:std_logic_vector(15 downto 0);
signal S_produit:std_logic_vector(15 downto 0);
signal SQ_acc:std_logic_vector(15 downto 0);
signal S_entree2:std_logic_vector(7 downto 0);
signal SCout:std_logic;--sortie de l'additionneur 8 ou retenu
signal STCout:std_logic;
signal SSTCout:std_logic;--sortie de l'additionneur 16 ou retenu

begin
----------------------------------------------------------------------------------------------------------------------------------
instance1:registre8
portmap(ResetR=>Reset,clock=>clock,load=>load,D=>operande1,sortie_affect=>sortie_affect,
Q=>SQ_Reg8);
----------------------------------------------------------------------------------------------------------------------------------
instance2:full_add
port map(opA=>SQ_Reg16(15 downto 8),opB=>SQ_Reg8,Cin=>Cin,Cout=>SCout,Result=>S_entree2);
----------------------------------------------------------------------------------------------------------------------------------
instance3:bascule_D
port map(clock=>clock,D=>SCout,Q=>STCout);
----------------------------------------------------------------------------------------------------------------------------------
instance4:shifter
portmap(clock=>clock,resetSR=>resetSR,Q=>SQ_Reg16,Result=>S_produit,affect_op2=>Saffect_op2,
operande2=>operande2,entree2=>S_entree2,serial_inRight=>STCout);
----------------------------------------------------------------------------------------------------------------------------------
instance5:additionneur16
port map(opA=>SQ_acc,opB=>S_produit,Cin=>Cin,Cout=>SSTCout,Result=>S_Resultadd16);
----------------------------------------------------------------------------------------------------------------------------------
instance6:registre16
port map(ResetReg=>Reset,clock=>clock,load=>Sclear,D=>S_Resultadd16,Q=>SQ_acc);
----------------------------------------------------------------------------------------------------------------------------------
fin<=SQ_acc;

end Behavioral;
----------------------------------------------------additionneur 8 bits----------------------------------------------------
entity full_add is
Port ( opA : in STD_LOGIC_VECTOR (7 downto 0);
opB : in STD_LOGIC_VECTOR (7 downto 0);
Cin : in STD_LOGIC;
Cout : out STD_LOGIC;
Result : out STD_LOGIC_VECTOR (7 downto 0));
end full_add;

architecture Behavioral of full_add is


----------------------------------------------------------------------------------------------------------------------------------
component add is
port ( opA : in STD_LOGIC;
opB : in STD_LOGIC;
Cin : in STD_LOGIC;
Result : out STD_LOGIC;
Cout : out STD_LOGIC);
end component;

signal C: STD_LOGIC_VECTOR(0 to 8);


begin
bloc: for i in 0 to 7 generate
instance: add
port map (opA(i), opB(i),C(i) ,Result(i), C(i+1));
end generate bloc;
C(0)<=Cin;
Cout <= C(8);

end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------registre 8bits---------------------------------------------------------------
entity registre8 is
Port ( ResetR : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (7 downto 0);
sortie_affect : out STD_LOGIC_VECTOR (7 downto 0);
Q : out STD_LOGIC_VECTOR (7 downto 0));
end registre8;

architecture Behavioral of registre8 is


signal SQ:std_logic_vector (7 downto 0);
signal tmp:std_logic_vector(7 downto 0):="00000000";
signal vase1,vase2,vase3:std_logic_vector (7 downto 0);

begin
process(clock,ResetR) is
begin
if ResetR='1' then
SQ<=(others=>'0');
tmp<="00000001";
Elsif clock='1' and clock'event then
if load='1' then
SQ<=D;
tmp<=tmp + 1;
end if;
if (tmp=2) then
vase1<=D;
end if;
if (tmp=9) then
sortie_affect<=vase1;
end if;
if (tmp=12) then
vase2<=D;
end if;
if (tmp=19) then
sortie_affect<=vase2;
end if;
if (tmp=22) then
vase3<=D;
end if;
if (tmp=29) then
sortie_affect<=vase3;
end if;
end if;
end process;
Q<=SQ;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------registre 16bits---------------------------------------------------------------
entity registre16 is
Port ( ResetReg : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (15 downto 0);
Q : out STD_LOGIC_VECTOR (15 downto 0));
end registre16;

architecture Behavioral of registre16 is


signal SQ:std_logic_vector (15 downto 0);

begin
process(clock,ResetReg) is
begin
if ResetReg='1' then
SQ<=(others=>'0');
Elsif clock='1' and clock'event then
if (load='1') then
SQ<=D;
end if;
end if;
end process;
Q<=SQ;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------bascule D---------------------------------------------------------------
entity bascule_D is
Port ( clock : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end bascule_D;

architecture Behavioral of bascule_D is


signal SQ:std_logic;

begin
process(clock) is
begin
if(clock='1' and clock'event)then
SQ<=D;
end if;
end process;
Q<=SQ;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------Shifter---------------------------------------------------------------
entity shifter is
Port ( clock : in STD_LOGIC;
resetSR : in STD_LOGIC;
Q: out std_logic_vector(15 downto 0);
Result: out std_logic_vector(15 downto 0);
affect_op2: out std_logic_vector(7 downto 0);
operande2: in std_logic_vector(7 downto 0);
entree2: in std_logic_vector(15 downto 8);
serial_inRight : in STD_LOGIC);
end shifter;

architecture Behavioral of shifter is


signal Sclear: std_logic;
signal SQ: std_logic_vector(15 downto 0);
signal tempo:std_logic_vector(3 downto 0):="0000";

begin
process(clock,resetSR)
begin
if resetSR='1' then
SQ<="00000000"&operande2;
tempo<="0000";
elsif (clock'event and clock='1') then
tempo<=tempo+1;
if (SQ(0)='1') then
SQ(6 downto 0)<=SQ(7 downto 1);
SQ(14 downto 7)<=entree2(15 downto 8);
SQ(15)<=serial_inRight;
else
SQ(15)<='0';
SQ(14 downto 7)<=SQ(15 downto 8);
SQ(6 downto 0)<=SQ(7 downto 1);

end if;
if (tempo=7) then
affect_op2<=operande2;
end if;
if (tempo=8) then
result<=SQ;
end if;
end if;
end process;
Q<=SQ;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------count_74---------------------------------------------------------------
entity count_74 is
Port ( clock : in STD_LOGIC;
clear : in STD_LOGIC;
output1 : out STD_LOGIC;
output2 : out STD_LOGIC;
output3 : out STD_LOGIC;
output4 : out STD_LOGIC;
output5 : out STD_LOGIC;
output6 : out STD_LOGIC;
load1 : out STD_LOGIC;
load2 : out STD_LOGIC;
load3 : out STD_LOGIC;
load4 : out STD_LOGIC;
load5 : out STD_LOGIC;
sfin1 : out STD_LOGIC;
sfin2 : out STD_LOGIC;
sfin3 : out STD_LOGIC;
sfin4 : out STD_LOGIC;
sfin5 : out STD_LOGIC;
Sreset_reception: out STD_LOGIC;
count:out std_logic_vector(7 downto 0));
end count_74;

architecture Behavioral of count_74 is

signal Sactiv1,Sactiv2,Sactiv3,Sactiv4,Sactiv5,Sactiv6,Sactiv7,Sactiv8:std_logic;
signal Sload1,Sload2,Sload3,Sload4,Sload5,Sload6,Sload7,Sload8:std_logic;
signal tmp:std_logic_vector(7 downto 0):="00000000";

begin

process(clock,clear)
begin
if (clear='1')then
tmp<="00000000";
elsif (clock'event and clock='1') then
tmp<=tmp+1;
if (tmp=1) then
count<=tmp;
end if;
if (tmp=2) then
Sload1<='1';
Sactiv1<='1';
end if;
if (tmp=3) then
Sactiv1<='0';
end if;
if (tmp=11) then
count<=tmp;
end if;
if (tmp=12) then
Sload2<='1';
Sactiv2<='1';
end if;
if (tmp=13) then
Sactiv2<='0';
end if;
if (tmp=21) then
count<=tmp;
end if;
if (tmp=22) then
Sload3<='1';
Sactiv3<='1';
end if;
if (tmp=23) then
Sactiv3<='0';
end if;
if (tmp=31) then
count<=tmp;
end if;
if (tmp=32) then
Sload4<='1';
Sactiv4<='1';
Sreset_reception<='1';
end if;
if (tmp=33) then
Sactiv4<='0';
sfin1<='1';
Sreset_reception<='0';
end if;
if (tmp=34) then
sfin1<='0';
end if;
if (tmp=41) then
count<=tmp;
end if;
if (tmp=42) then
Sload5<='1';
Sactiv5<='1';
end if;
if (tmp=43) then
Sactiv5<='0';
sfin2<='1';
end if;
if (tmp=44) then
sfin2<='0';
end if;
if (tmp=52) then
Sload6<='1';
Sactiv6<='1';
end if;
if (tmp=53) then
Sactiv6<='0';
sfin3<='1';
end if;
if (tmp=54) then
sfin3<='0';
end if;
if (tmp=62) then
Sload7<='1';
Sactiv7<='1';
end if;
if (tmp=63) then
Sactiv7<='0';
sfin4<='1';
end if;
if (tmp=64) then
sfin4<='0';
end if;
if (tmp=72) then
Sload8<='1';
Sactiv8<='1';
end if;
if (tmp=73) then
Sactiv8<='0';
sfin5<='1';
end if;
if (tmp=74) then
sfin5<='0';
end if;
end if;
end process;
output1 <= Sactiv1 or Sactiv2 or Sactiv3;--resetSr processor
output2 <= Sactiv2 or Sactiv3 or Sactiv4;
output3 <= Sactiv3 or Sactiv4 or Sactiv5;
output4 <= Sactiv4 or Sactiv5 or Sactiv6;
output5 <= Sactiv5 or Sactiv6 or Sactiv7;
output6 <= Sactiv6 or Sactiv7 or Sactiv8;
load1 <=Sload1 or Sload2 or Sload3;--load processor
load2 <=Sload2 or Sload3 or Sload4;
load3 <=Sload3 or Sload4 or Sload5;
load4 <=Sload4 or Sload5 or Sload6;
load5 <=Sload5 or Sload6 or Sload7;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
Buffer d’entrée
----------------------------------------------------------------------------------------------------------------------------------
entity buffer_d_entree is
Port ( clock : in STD_LOGIC;
Reset : in STD_LOGIC;
load : in STD_LOGIC;
Selecteur:in STD_LOGIC_VECTOR (7 downto 0);
receivePc_a11 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a12 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a13 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a21 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a22 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a23 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a31 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a32 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a33 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b11 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b12 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b13 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b21 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b22 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b23 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b31 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b32 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b33 : in STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne1 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne2 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne3 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne1 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne2 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne3 : out STD_LOGIC_VECTOR(7 downto 0));
end buffer_d_entree;

architecture Behavioral of buffer_d_entree is


----------------------------------------------------------------------------------------------------------------------------------
component memoire is
Port ( ResetR : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (7 downto 0);
Q : out STD_LOGIC_VECTOR (7 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
component acq_1 is
Port ( entree1 : in STD_LOGIC_VECTOR (7 downto 0);
entree2 : in STD_LOGIC_VECTOR (7 downto 0);
entree3 : in STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0);
Selecteur:in STD_LOGIC_VECTOR (7 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
component acq_2 is
Port ( entree1 : in STD_LOGIC_VECTOR (7 downto 0);
entree2 : in STD_LOGIC_VECTOR (7 downto 0);
entree3 : in STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0);
Selecteur:in STD_LOGIC_VECTOR (7 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
component acq_3 is
Port ( entree1 : in STD_LOGIC_VECTOR (7 downto 0);
entree2 : in STD_LOGIC_VECTOR (7 downto 0);
entree3 : in STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0);
Selecteur:in STD_LOGIC_VECTOR (7 downto 0));
end component;
----------------------------------------------------------------------------------------------------------------------------------
signal SQ_a11,SQ_a12,SQ_a13,SQ_a21,SQ_a22,SQ_a23,SQ_a31,SQ_a32,SQ_a33:std_logic_vector(7
downto 0);
signal SQ_b11,SQ_b12,SQ_b13,SQ_b21,SQ_b22,SQ_b23,SQ_b31,SQ_b32,SQ_b33:std_logic_vector(7
downto 0);

begin
----------------------------------------------------------------------------------------------------------------------------------
a11:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a11,Q=>SQ_a11);
------------------------------------------------------------------------------------------------------------------------------
a12:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a12,Q=>SQ_a12);
------------------------------------------------------------------------------------------------------------------------------
a13:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a13,Q=>SQ_a13);
------------------------------------------------------------------------------------------------------------------------------
acq_a:acq_1
port
map(entree1=>SQ_a11,entree2=>SQ_a12,entree3=>SQ_a13,sortie=>sortie_ligne1,Selecteur=>Select
eur);
----------------
b11:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b11,Q=>SQ_b11);
------------------------------------------------------------------------------------------------------------------------------
b21:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b21,Q=>SQ_b21);
------------------------------------------------------------------------------------------------------------------------------
b31:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b31,Q=>SQ_b31);
------------------------------------------------------------------------------------------------------------------------------
acq_b:acq_1
port
map(entree1=>SQ_b11,entree2=>SQ_b21,entree3=>SQ_b31,sortie=>sortie_colonne1,Selecteur=>Sel
ecteur);
------------------------------------------------------------------------------------------------------------------------------
a21:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a21,Q=>SQ_a21);
------------------------------------------------------------------------------------------------------------------------------
a22:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a22,Q=>SQ_a22);
------------------------------------------------------------------------------------------------------------------------------
a23:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a23,Q=>SQ_a23);
------------------------------------------------------------------------------------------------------------------------------
acquisition2_a:acq_2
port
map(entree1=>SQ_a21,entree2=>SQ_a22,entree3=>SQ_a23,sortie=>sortie_ligne2,Selecteur=>Select
eur);
------------------------------------------------------------------------------------------------------------------------------
b12:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b12,Q=>SQ_b12);
------------------------------------------------------------------------------------------------------------------------------
b22:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b22,Q=>SQ_b22);
------------------------------------------------------------------------------------------------------------------------------
b32:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b32,Q=>SQ_b32);
------------------------------------------------------------------------------------------------------------------------------
acquisition2_b:acq_2
portmap(entree1=>SQ_b12,entree2=>SQ_b22,entree3=>SQ_b32,sortie=>sortie_colonne2,Se
lecteur=>Selecteur);
------------------------------------------------------------------------------------------------------------------------------
a31:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a31,Q=>SQ_a31);
------------------------------------------------------------------------------------------------------------------------------
a32:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a32,Q=>SQ_a32);
------------------------------------------------------------------------------------------------------------------------------
a33:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_a33,Q=>SQ_a33);
------------------------------------------------------------------------------------------------------------------------------
acquisition3_a:acq_3
port
map(entree1=>SQ_a31,entree2=>SQ_a32,entree3=>SQ_a33,sortie=>sortie_ligne3,Selecteur=>Select
eur);
------------------------------------------------------------------------------------------------------------------------------
b13:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b13,Q=>SQ_b13);
------------------------------------------------------------------------------------------------------------------------------
b23:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b23,Q=>SQ_b23);
------------------------------------------------------------------------------------------------------------------------------
b33:memoire
port map(ResetR=>Reset,clock=>clock,load=>load,D=>receivePc_b33,Q=>SQ_b33);
------------------------------------------------------------------------------------------------------------------------------
acquisition3_b:acq_3
port
map(entree1=>SQ_b13,entree2=>SQ_b23,entree3=>SQ_b33,sortie=>sortie_colonne3,Selecteur=>Sel
ecteur);
------------------------------------------------------------------------------------------------------------------------------
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------acq_1---------------------------------------------------------------
entity acq_1 is
Port ( entree1 : in STD_LOGIC_VECTOR (7 downto 0);
entree2 : in STD_LOGIC_VECTOR (7 downto 0);
entree3 : in STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0);
Selecteur:in STD_LOGIC_VECTOR (7 downto 0));
end acq_1;

architecture Behavioral of acq_1 is

begin
process (Selecteur, entree1, entree2, entree3)
begin
CASE selecteur IS
when "00000001" => sortie<= entree1; -- 1
when "00001011" => sortie<= entree2; -- 11
when "00010101" => sortie<= entree3; -- 21
when others => sortie<=(others=>'0');
end case;
end process;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------acq_2---------------------------------------------------------------
entity acq_2 is
Port ( entree1 : in STD_LOGIC_VECTOR (7 downto 0);
entree2 : in STD_LOGIC_VECTOR (7 downto 0);
entree3 : in STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0);
Selecteur:in STD_LOGIC_VECTOR (7 downto 0));
end acq_2;

architecture Behavioral of acq_2 is

begin
process (Selecteur, entree1, entree2, entree3)
begin
CASE selecteur IS
when "00001011" => sortie<= entree1; -- 11
when "00010101" => sortie<= entree2; -- 21
when "00011111" => sortie<= entree3; -- 31
when others => sortie<=(others=>'0');
end case;
end process;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------acq_3---------------------------------------------------------------
entity acq_3 is
Port ( entree1 : in STD_LOGIC_VECTOR (7 downto 0);
entree2 : in STD_LOGIC_VECTOR (7 downto 0);
entree3 : in STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0);
Selecteur:in STD_LOGIC_VECTOR (7 downto 0));
end acq_3;

architecture Behavioral of acq_3 is

begin
process (Selecteur, entree1, entree2, entree3)
begin
CASE selecteur IS
when "00010101" => sortie<= entree1;
when "00011111" => sortie<= entree2;
when "00101001" => sortie<= entree3;
when others => sortie<=(others=>'0');
end case;
end process;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------memoire---------------------------------------------------------------
entity memoire is
Port ( ResetR : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (7 downto 0);
Q : out STD_LOGIC_VECTOR (7 downto 0));
end memoire;

architecture Behavioral of memoire is


signal SQ:std_logic_vector (7 downto 0);

begin

process(clock,ResetR) is
begin
if ResetR='1' then
SQ<=(others=>'0');
Elsif clock='1' and clock'event then
if load='1' then
SQ<=D;
end if;
end if;
end process;
Q<=SQ;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
Buffer de sortie
----------------------------------------------------------------------------------------------------------------------------------
entity buffeer_de_sortie is
Port ( clock : in STD_LOGIC;
ResetReg : in STD_LOGIC;
load1 : in STD_LOGIC;
load2 : in STD_LOGIC;
load3 : in STD_LOGIC;
load4 : in STD_LOGIC;
load5 : in STD_LOGIC;
D_c11 : in STD_LOGIC_VECTOR (15 downto 0);
D_c12 : in STD_LOGIC_VECTOR (15 downto 0);
D_c13 : in STD_LOGIC_VECTOR (15 downto 0);
D_c21 : in STD_LOGIC_VECTOR (15 downto 0);
D_c22 : in STD_LOGIC_VECTOR (15 downto 0);
D_c23 : in STD_LOGIC_VECTOR (15 downto 0);
D_c31 : in STD_LOGIC_VECTOR (15 downto 0);
D_c32 : in STD_LOGIC_VECTOR (15 downto 0);
D_c33 : in STD_LOGIC_VECTOR (15 downto 0);
Q_c11 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c12 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c13 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c21 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c22 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c23 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c31 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c32 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c33 : out STD_LOGIC_VECTOR (15 downto 0));
end buffeer_de_sortie;

architecture Behavioral of buffeer_de_sortie is

component registre_sortie16 is
Port ( ResetReg : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (15 downto 0);
Q : out STD_LOGIC_VECTOR (15 downto 0));
end component;

begin

buffer_de_sortie_c11:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load1,D=>D_c11,Q=>Q_c11);

buffer_de_sortie_c12:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load2,D=>D_c12,Q=>Q_c12);
buffer_de_sortie_c21:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load2,D=>D_c21,Q=>Q_c21);

buffer_de_sortie_c13:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load3,D=>D_c13,Q=>Q_c13);

buffer_de_sortie_c22:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load3,D=>D_c22,Q=>Q_c22);

buffer_de_sortie_c31:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load3,D=>D_c31,Q=>Q_c31);

buffer_de_sortie_c23:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load4,D=>D_c23,Q=>Q_c23);

buffer_de_sortie_c32:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load4,D=>D_c32,Q=>Q_c32);

buffer_de_sortie_c33:registre_sortie16
port map (ResetReg=>ResetReg,clock=>clock,load=>load5,D=>D_c33,Q=>Q_c33);

end Behavioral;

----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------registre de sortie--------------------------------------------------------------
entity registre_sortie16 is
Port ( ResetReg : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
D : in STD_LOGIC_VECTOR (15 downto 0);
Q : out STD_LOGIC_VECTOR (15 downto 0));
end registre_sortie16;

architecture Behavioral of registre_sortie16 is


signal SQ:std_logic_vector (15 downto 0);

begin
process(clock,ResetReg) is
begin
if ResetReg='1' then
SQ<=(others=>'0');
Elsif clock='1' and clock'event then
if (load='1') then
SQ<=D;
end if;
end if;
end process;
Q<=SQ;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------- L’architecture systolique -------------------------------------------------
entity systorice is
Port ( clock : in STD_LOGIC;
Clear : in STD_LOGIC;
Cin : in STD_LOGIC;
entree : in STD_LOGIC_VECTOR (7 downto 0);
receivePc_a11 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a12 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a13 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a21 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a22 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a23 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a31 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a32 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_a33 : out STD_LOGIC_VECTOR(7 downto 0);

receivePc_b11 : out STD_LOGIC_VECTOR(7 downto 0);


receivePc_b12 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b13 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b21 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b22 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b23 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b31 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b32 : out STD_LOGIC_VECTOR(7 downto 0);
receivePc_b33 : out STD_LOGIC_VECTOR(7 downto 0);

sendtopc: out std_logic_vector(15 downto 0);


sortie_ligne1 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne2 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne3 : out STD_LOGIC_VECTOR(7 downto 0);

sortie_colonne1 : out STD_LOGIC_VECTOR(7 downto 0);


sortie_colonne2 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne3 : out STD_LOGIC_VECTOR(7 downto 0);
Qc11: out STD_LOGIC_VECTOR(15 downto 0);
Qc12: out STD_LOGIC_VECTOR(15 downto 0);
Qc13: out STD_LOGIC_VECTOR(15 downto 0);
Qc21: out STD_LOGIC_VECTOR(15 downto 0);
Qc22: out STD_LOGIC_VECTOR(15 downto 0);
Qc23: out STD_LOGIC_VECTOR(15 downto 0);
Qc31: out STD_LOGIC_VECTOR(15 downto 0);
Qc32: out STD_LOGIC_VECTOR(15 downto 0);
Qc33: out STD_LOGIC_VECTOR(15 downto 0));
end systorice;

architecture Behavioral of systorice is

component processeur is
Port ( clock : in STD_LOGIC;
load : in STD_LOGIC;
Reset : in STD_LOGIC;
resetSR : in STD_LOGIC;
Cin : in STD_LOGIC;
Sclear : in STD_LOGIC;
operande1: in std_logic_vector(7 downto 0);
operande2: in std_logic_vector(7 downto 0);
sortie_affect: out std_logic_vector(7 downto 0);
Saffect_op2 : out std_logic_vector(7 downto 0);
fin: out std_logic_vector(15 downto 0));
end component;

component buffer_d_entree is
Port ( clock : in STD_LOGIC;
Reset : in STD_LOGIC;
load : in STD_LOGIC;
Selecteur:in STD_LOGIC_VECTOR (7 downto 0);
receivePc_a11 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a12 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a13 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a21 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a22 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a23 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a31 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a32 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_a33 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b11 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b12 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b13 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b21 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b22 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b23 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b31 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b32 : in STD_LOGIC_VECTOR(7 downto 0);
receivePc_b33 : in STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne1 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne2 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_ligne3 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne1 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne2 : out STD_LOGIC_VECTOR(7 downto 0);
sortie_colonne3 : out STD_LOGIC_VECTOR(7 downto 0));
end component;

component count_74 is
Port ( clock : in STD_LOGIC;
clear : in STD_LOGIC;
output1 : out STD_LOGIC;
output2 : out STD_LOGIC;
output3 : out STD_LOGIC;
output4 : out STD_LOGIC;
output5 : out STD_LOGIC;
output6 : out STD_LOGIC;
load1 : out STD_LOGIC;
load2 : out STD_LOGIC;
load3 : out STD_LOGIC;
load4 : out STD_LOGIC;
load5 : out STD_LOGIC;
sfin1 : out STD_LOGIC;
sfin2 : out STD_LOGIC;
sfin3 : out STD_LOGIC;
sfin4 : out STD_LOGIC;
sfin5 : out STD_LOGIC;
Sreset_reception : out STD_LOGIC;
count:out std_logic_vector(7 downto 0));
end component;

component buffeer_de_sortie is
Port ( clock : in STD_LOGIC;
ResetReg : in STD_LOGIC;
load1 : in STD_LOGIC;
load2 : in STD_LOGIC;
load3 : in STD_LOGIC;
load4 : in STD_LOGIC;
load5 : in STD_LOGIC;
D_c11 : in STD_LOGIC_VECTOR (15 downto 0);
D_c12 : in STD_LOGIC_VECTOR (15 downto 0);
D_c13 : in STD_LOGIC_VECTOR (15 downto 0);
D_c21 : in STD_LOGIC_VECTOR (15 downto 0);
D_c22 : in STD_LOGIC_VECTOR (15 downto 0);
D_c23 : in STD_LOGIC_VECTOR (15 downto 0);
D_c31 : in STD_LOGIC_VECTOR (15 downto 0);
D_c32 : in STD_LOGIC_VECTOR (15 downto 0);
D_c33 : in STD_LOGIC_VECTOR (15 downto 0);
Q_c11 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c12 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c13 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c21 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c22 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c23 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c31 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c32 : out STD_LOGIC_VECTOR (15 downto 0);
Q_c33 : out STD_LOGIC_VECTOR (15 downto 0));
end component;

component distributeur is
Port ( clear : in STD_LOGIC;
clock : in STD_LOGIC;
entree : in STD_LOGIC_VECTOR (7 downto 0);
a11 : out STD_LOGIC_VECTOR (7 downto 0);
a12 : out STD_LOGIC_VECTOR (7 downto 0);
a13 : out STD_LOGIC_VECTOR (7 downto 0);
a21 : out STD_LOGIC_VECTOR (7 downto 0);
a22 : out STD_LOGIC_VECTOR (7 downto 0);
a23 : out STD_LOGIC_VECTOR (7 downto 0);
a31 : out STD_LOGIC_VECTOR (7 downto 0);
a32 : out STD_LOGIC_VECTOR (7 downto 0);
a33 : out STD_LOGIC_VECTOR (7 downto 0);
b11 : out STD_LOGIC_VECTOR (7 downto 0);
b12 : out STD_LOGIC_VECTOR (7 downto 0);
b13 : out STD_LOGIC_VECTOR (7 downto 0);
b21 : out STD_LOGIC_VECTOR (7 downto 0);
b22 : out STD_LOGIC_VECTOR (7 downto 0);
b23 : out STD_LOGIC_VECTOR (7 downto 0);
b31 : out STD_LOGIC_VECTOR (7 downto 0);
b32 : out STD_LOGIC_VECTOR (7 downto 0);
b33 : out STD_LOGIC_VECTOR (7 downto 0);
load : out STD_LOGIC;
Sclear : out STD_LOGIC;
sortie : out STD_LOGIC_VECTOR (7 downto 0));
end component;

component reception is
Port ( clear : in STD_LOGIC;
clock : in STD_LOGIC;
c11: in STD_LOGIC_VECTOR(15 downto 0);
c12: in STD_LOGIC_VECTOR(15 downto 0);
c13: in STD_LOGIC_VECTOR(15 downto 0);
c21: in STD_LOGIC_VECTOR(15 downto 0);
c22: in STD_LOGIC_VECTOR(15 downto 0);
c23: in STD_LOGIC_VECTOR(15 downto 0);
c31: in STD_LOGIC_VECTOR(15 downto 0);
c32: in STD_LOGIC_VECTOR(15 downto 0);
c33: in STD_LOGIC_VECTOR(15 downto 0);
sendtopc: out STD_LOGIC_VECTOR(15 downto 0));
end component;

signal S_load1,S_load2,S_load3,S_load4,S_load5,SSreset_reception,SSclear:std_logic;
signal Soutput1,Soutput2,Soutput3,Soutput4,Soutput5,Soutput6:std_logic;
signal Saffect_op2_colonne1,Saffect_op2_colonne11,Saffect_op2_colonne12: std_logic_vector(7
downto 0);
signal Saffect_op2_colonne2,Saffect_op2_colonne21,Saffect_op2_colonne22: std_logic_vector(7
downto 0);
signal Saffect_op2_colonne3,Saffect_op2_colonne31,Saffect_op2_colonne32: std_logic_vector(7
downto 0);
signal Ssortie_affect11,Ssortie_affect12,Ssortie_affect13: std_logic_vector(7 downto 0);
signal Ssortie_affect21,Ssortie_affect22,Ssortie_affect23: std_logic_vector(7 downto 0);
signal Ssortie_affect31,Ssortie_affect32,Ssortie_affect33: std_logic_vector(7 downto 0);
signal Ssfin1,Ssfin2,Ssfin3,Ssfin4,Ssfin5:std_logic;
signal result_c11,result_c12,result_c13: std_logic_vector(15 downto 0);
signal result_c21,result_c22,result_c23: std_logic_vector(15 downto 0);
signal result_c31,result_c32,result_c33: std_logic_vector(15 downto 0);
signal Ssortie_ligne1,Ssortie_ligne2,Ssortie_ligne3: std_logic_vector(7 downto 0);
signal Ssortie_colonne1,Ssortie_colonne2,Ssortie_colonne3: std_logic_vector(7 downto 0);
signal Scount: std_logic_vector(7 downto 0);
signal SreceivePc_a11,SreceivePc_a12,SreceivePc_a13: std_logic_vector(7 downto 0);
signal SreceivePc_a21,SreceivePc_a22,SreceivePc_a23: std_logic_vector(7 downto 0);
signal SreceivePc_a31,SreceivePc_a32,SreceivePc_a33: std_logic_vector(7 downto 0);
signal SreceivePc_b11,SreceivePc_b12,SreceivePc_b13: std_logic_vector(7 downto 0);
signal SreceivePc_b21,SreceivePc_b22,SreceivePc_b23: std_logic_vector(7 downto 0);
signal SreceivePc_b31,SreceivePc_b32,SreceivePc_b33: std_logic_vector(7 downto 0);
signal SSortie: std_logic_vector(7 downto 0);
signal SsendtoPc_c11,SsendtoPc_c12,SsendtoPc_c13: std_logic_vector(15 downto 0);
signal SsendtoPc_c21,SsendtoPc_c22,SsendtoPc_c23: std_logic_vector(15 downto 0);
signal SsendtoPc_c31,SsendtoPc_c32,SsendtoPc_c33: std_logic_vector(15 downto 0);
signal Sload:std_logic;

begin

c11:processeur
port
map(clock=>clock,load=>S_load1,Reset=>Clear,resetSR=>Soutput1,Cin=>Cin,Sclear=>Soutput2,opera
nde1=>Ssortie_ligne1,operande2=>Ssortie_colonne1,sortie_affect=>Ssortie_affect11,Saffect_op2=>S
affect_op2_colonne1,fin=>result_c11);

c12:processeur
port
map(clock=>clock,load=>S_load2,Reset=>Clear,resetSR=>Soutput2,Cin=>Cin,Sclear=>Soutput3,opera
nde1=>Ssortie_affect11,operande2=>Ssortie_colonne2,sortie_affect=>Ssortie_affect12,Saffect_op2=
>Saffect_op2_colonne2,fin=>result_c12);

c13:processeur
port
map(clock=>clock,load=>S_load3,Reset=>Clear,resetSR=>Soutput3,Cin=>Cin,Sclear=>Soutput4,opera
nde1=>Ssortie_affect12,operande2=>Ssortie_colonne3,sortie_affect=>Ssortie_affect13,Saffect_op2=
>Saffect_op2_colonne3,fin=>result_c13);

c21:processeur
port
map(clock=>clock,load=>S_load2,Reset=>Clear,resetSR=>Soutput2,Cin=>Cin,Sclear=>Soutput3,opera
nde1=>Ssortie_ligne2,operande2=>Saffect_op2_colonne1,sortie_affect=>Ssortie_affect21,Saffect_o
p2=>Saffect_op2_colonne11,fin=>result_c21);

c22:processeur
port
map(clock=>clock,load=>S_load3,Reset=>Clear,resetSR=>Soutput3,Cin=>Cin,Sclear=>Soutput4,opera
nde1=>Ssortie_affect21,operande2=>Saffect_op2_colonne2,sortie_affect=>Ssortie_affect22,Saffect_
op2=>Saffect_op2_colonne21,fin=>result_c22);

c23:processeur
port
map(clock=>clock,load=>S_load4,Reset=>Clear,resetSR=>Soutput4,Cin=>Cin,Sclear=>Soutput5,opera
nde1=>Ssortie_affect22,operande2=>Saffect_op2_colonne3,sortie_affect=>Ssortie_affect23,Saffect_
op2=>Saffect_op2_colonne31,fin=>result_c23);

c31:processour
port
map(clock=>clock,load=>S_load3,Reset=>Clear,resetSR=>Soutput3,Cin=>Cin,Sclear=>Soutput4,opera
nde1=>Ssortie_ligne3,operande2=>Saffect_op2_colonne11,sortie_affect=>Ssortie_affect31,Saffect_
op2=>Saffect_op2_colonne12,fin=>result_c31);
c32:processour
port
map(clock=>clock,load=>S_load4,Reset=>Clear,resetSR=>Soutput4,Cin=>Cin,Sclear=>Soutput5,opera
nde1=>Ssortie_affect31,operande2=>Saffect_op2_colonne21,sortie_affect=>Ssortie_affect32,Saffect
_op2=>Saffect_op2_colonne22,fin=>result_c32);

c33:processour
port
map(clock=>clock,load=>S_load5,Reset=>Clear,resetSR=>Soutput5,Cin=>Cin,Sclear=>Soutput6,opera
nde1=>Ssortie_affect32,operande2=>Saffect_op2_colonne31,sortie_affect=>Ssortie_affect33,Saffect
_op2=>Saffect_op2_colonne32,fin=>result_c33);
----------------------
buffer_entree:buffer_d_entree
port
map(clock=>clock,Reset=>Clear,load=>Sload,Selecteur=>Scount,receivePc_a11=>SreceivePc_a11,rec
eivePc_a12=>SreceivePc_a12,receivePc_a13=>SreceivePc_a13,receivePc_a21=>SreceivePc_a21,recei
vePc_a22=>SreceivePc_a22,receivePc_a23=>SreceivePc_a23,receivePc_a31=>SreceivePc_a31,receiv
ePc_a32=>SreceivePc_a32,receivePc_a33=>SreceivePc_a33,receivePc_b11=>SreceivePc_b11,receive
Pc_b12=>SreceivePc_b12,receivePc_b13=>SreceivePc_b13,receivePc_b21=>SreceivePc_b21,receiveP
c_b22=>SreceivePc_b22,receivePc_b23=>SreceivePc_b23,receivePc_b31=>SreceivePc_b31,receivePc
_b32=>SreceivePc_b32,receivePc_b33=>SreceivePc_b33,sortie_ligne1=>Ssortie_ligne1,sortie_ligne2
=>Ssortie_ligne2,sortie_ligne3=>Ssortie_ligne3,sortie_colonne1=>Ssortie_colonne1,sortie_colonne2
=>Ssortie_colonne2,sortie_colonne3=>Ssortie_colonne3);
----------------------
count:count_74
port map(clock=>clock,clear=>SSclear,
output1=>Soutput1,output2=>Soutput2,output3=>Soutput3,output4=>Soutput4,output5=>Soutput5
,output6=>Soutput6,load1=>S_load1,load2=>S_load2,load3=>S_load3,load4=>S_load4,load5=>S_loa
d5,sfin1=>Ssfin1,sfin2=>Ssfin2,sfin3=>Ssfin3,sfin4=>Ssfin4,sfin5=>Ssfin5,Sreset_reception=>SSreset_r
eception,count=>Scount);
---------------------
buffeer_sortie:buffeer_de_sortie
port map
(clock=>clock,ResetReg=>SSclear,load1=>Ssfin1,load2=>Ssfin2,load3=>Ssfin3,load4=>Ssfin4,load5=>S
sfin5,D_c11=>result_c11,D_c12=>result_c12,D_c13=>result_c13,D_c21=>result_c21,
D_c22=>result_c22, D_c23=>result_c23,D_c31=>result_c31,D_c32=>result_c32,D_c33=>result_c33,
Q_c11=>SsendtoPc_c11,Q_c12=>SsendtoPc_c12,Q_c13=>SsendtoPc_c13,Q_c21=>SsendtoPc_c21,Q_
c22=>SsendtoPc_c22,Q_c23=>SsendtoPc_c23,Q_c31=>SsendtoPc_c31,Q_c32=>SsendtoPc_c32,Q_c3
3=>SsendtoPc_c33);
--------------------
distrib:distributeur
port
map(clear=>Clear,clock=>clock,entree=>entree,a11=>SreceivePc_a11,a12=>SreceivePc_a12,a13=>Sr
eceivePc_a13,a21=>SreceivePc_a21,a22=>SreceivePc_a22,a23=>SreceivePc_a23,a31=>SreceivePc_a
31,a32=>SreceivePc_a32,a33=>SreceivePc_a33,b11=>SreceivePc_b11,b12=>SreceivePc_b12,b13=>Sr
eceivePc_b13,b21=>SreceivePc_b21,b22=>SreceivePc_b22,b23=>SreceivePc_b23,b31=>SreceivePc_b
31,b32=>SreceivePc_b32,b33=>SreceivePc_b33,load=>Sload,Sclear=>SSclear,sortie=>SSortie);
--------------------
recept:reception
port map(clear=>SSreset_reception,clock=>clock,c11=>SsendtoPc_c11,c12=>SsendtoPc_c12,
c13=>SsendtoPc_c13,c21=>SsendtoPc_c21,c22=>SsendtoPc_c22,c23=>SsendtoPc_c23,c31=>Ssendto
Pc_c31,c32=>SsendtoPc_c32,c33=>SsendtoPc_c33,sendtopc=>sendtopc);
receivePc_a11 <= SreceivePc_a11;
receivePc_a12 <= SreceivePc_a12;
receivePc_a13 <= SreceivePc_a13;
receivePc_a21 <= SreceivePc_a21;
receivePc_a22 <= SreceivePc_a22;
receivePc_a23 <= SreceivePc_a23;
receivePc_a31 <= SreceivePc_a31;
receivePc_a32 <= SreceivePc_a32;
receivePc_a33 <= SreceivePc_a33;
receivePc_b11 <= SreceivePc_b11;
receivePc_b12 <= SreceivePc_b12;
receivePc_b13 <= SreceivePc_b13;
receivePc_b21 <= SreceivePc_b21;
receivePc_b22 <= SreceivePc_b22;
receivePc_b23 <= SreceivePc_b23;
receivePc_b31 <= SreceivePc_b31;
receivePc_b32 <= SreceivePc_b32;
receivePc_b33 <= SreceivePc_b33;

sortie_ligne1 <= Ssortie_ligne1;


sortie_ligne2 <= Ssortie_ligne2;
sortie_ligne3 <= Ssortie_ligne3;
sortie_colonne1 <= Ssortie_colonne1;
sortie_colonne2 <= Ssortie_colonne2;
sortie_colonne3 <= Ssortie_colonne3;

Qc11 <= SsendtoPc_c11;


Qc12 <= SsendtoPc_c12;
Qc13 <= SsendtoPc_c13;
Qc21 <= SsendtoPc_c21;
Qc22 <= SsendtoPc_c22;
Qc23 <= SsendtoPc_c23;
Qc31 <= SsendtoPc_c31;
Qc32 <= SsendtoPc_c32;
Qc33 <= SsendtoPc_c33;

end Behavioral;

----------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------- distributeur ---------------------------------------------------------------
entity distributeur is
Port ( clear : in STD_LOGIC;
clock : in STD_LOGIC;
entree : in STD_LOGIC_VECTOR (7 downto 0);
a11 : out STD_LOGIC_VECTOR (7 downto 0);
a12 : out STD_LOGIC_VECTOR (7 downto 0);
a13 : out STD_LOGIC_VECTOR (7 downto 0);
a21 : out STD_LOGIC_VECTOR (7 downto 0);
a22 : out STD_LOGIC_VECTOR (7 downto 0);
a23 : out STD_LOGIC_VECTOR (7 downto 0);
a31 : out STD_LOGIC_VECTOR (7 downto 0);
a32 : out STD_LOGIC_VECTOR (7 downto 0);
a33 : out STD_LOGIC_VECTOR (7 downto 0);
b11 : out STD_LOGIC_VECTOR (7 downto 0);
b12 : out STD_LOGIC_VECTOR (7 downto 0);
b13 : out STD_LOGIC_VECTOR (7 downto 0);
b21 : out STD_LOGIC_VECTOR (7 downto 0);
b22 : out STD_LOGIC_VECTOR (7 downto 0);
b23 : out STD_LOGIC_VECTOR (7 downto 0);
b31 : out STD_LOGIC_VECTOR (7 downto 0);
b32 : out STD_LOGIC_VECTOR (7 downto 0);
b33 : out STD_LOGIC_VECTOR (7 downto 0);
load : out STD_LOGIC;
Sclear : out STD_LOGIC;
sortie : out STD_LOGIC_VECTOR (7 downto 0));
end distributeur;

architecture Behavioral of distributeur is

component demultiplexeur is
Port ( selectentree : in STD_LOGIC_vector(7 downto 0);
entree : in STD_LOGIC_VECTOR (7 downto 0);
a11 : out STD_LOGIC_VECTOR (7 downto 0);
a12 : out STD_LOGIC_VECTOR (7 downto 0);
a13 : out STD_LOGIC_VECTOR (7 downto 0);
a21 : out STD_LOGIC_VECTOR (7 downto 0);
a22 : out STD_LOGIC_VECTOR (7 downto 0);
a23 : out STD_LOGIC_VECTOR (7 downto 0);
a31 : out STD_LOGIC_VECTOR (7 downto 0);
a32 : out STD_LOGIC_VECTOR (7 downto 0);
a33 : out STD_LOGIC_VECTOR (7 downto 0);
b11 : out STD_LOGIC_VECTOR (7 downto 0);
b12 : out STD_LOGIC_VECTOR (7 downto 0);
b13 : out STD_LOGIC_VECTOR (7 downto 0);
b21 : out STD_LOGIC_VECTOR (7 downto 0);
b22 : out STD_LOGIC_VECTOR (7 downto 0);
b23 : out STD_LOGIC_VECTOR (7 downto 0);
b31 : out STD_LOGIC_VECTOR (7 downto 0);
b32 : out STD_LOGIC_VECTOR (7 downto 0);
b33 : out STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0));
end component;

component counter_136 is
Port ( clear : in STD_LOGIC;
clock : in STD_LOGIC;
load : out STD_LOGIC;
Sclear : out STD_LOGIC;
count:out std_logic_vector(7 downto 0));
end component;

signal Scount:std_logic_vector(7 downto 0);


begin

instance1:demultiplexeur
port
map(selectentree=>Scount,entree=>entree,a11=>a11,a12=>a12,a13=>a13,a21=>a21,a22=>a22,a23=
>a23,a31=>a31,a32=>a32,a33=>a33,b11=>b11,b12=>b12,b13=>b13,b21=>b21,b22=>b22,b23=>b23,
b31=>b31,b32=>b32,b33=>b33,sortie=>sortie);

instance2:counter_136
port map(clear=>clear,clock=>clock,load=>load,Sclear=>Sclear,count=>Scount);

end Behavioral;

----------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------- counter_136-------------------------------------------------------------
entity counter_136 is
Port ( clear : in STD_LOGIC;
clock : in STD_LOGIC;
load : out STD_LOGIC;
Sclear : out STD_LOGIC;
count:out std_logic_vector(7 downto 0));
end counter_136;

architecture Behavioral of counter_136 is

signal tmp:std_logic_vector(7 downto 0):="00000000";


begin
process(clock,clear)
begin
if (clear='1')then
tmp<="00000000";
elsif (clock'event and clock='1') then
tmp<=tmp+1;
if (tmp=1) then
load<='1';
count<=tmp;
end if;
if (tmp=9) then
count<=tmp;
end if;
if (tmp=17) then
count<=tmp;
end if;
if (tmp=25) then
count<=tmp;
end if;
if (tmp=33) then
count<=tmp;
end if;
if (tmp=41) then
count<=tmp;
end if;
if (tmp=49) then
count<=tmp;
end if;
if (tmp=57) then
count<=tmp;
end if;
if (tmp=65) then
count<=tmp;
end if;
if (tmp=73) then
count<=tmp;
end if;
if (tmp=81) then
count<=tmp;
end if;
if (tmp=89) then
count<=tmp;
end if;
if (tmp=97) then
count<=tmp;
end if;
if (tmp=105) then
count<=tmp;
end if;
if (tmp=113) then
count<=tmp;
end if;
if (tmp=121) then
count<=tmp;
end if;
if (tmp=129) then
count<=tmp;
end if;
if (tmp=137) then
count<=tmp;
end if;
if (tmp=138) then
Sclear<='1';
end if;
if (tmp=139) then
Sclear<='0';
end if;
end if;
end process;
end Behavioral;
----------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------- demultiplexeur --------------------------------------------------------------
entity demultiplexeur is
Port ( selectentree : in STD_LOGIC_vector(7 downto 0);
entree : in STD_LOGIC_VECTOR (7 downto 0);
a11 : out STD_LOGIC_VECTOR (7 downto 0);
a12 : out STD_LOGIC_VECTOR (7 downto 0);
a13 : out STD_LOGIC_VECTOR (7 downto 0);
a21 : out STD_LOGIC_VECTOR (7 downto 0);
a22 : out STD_LOGIC_VECTOR (7 downto 0);
a23 : out STD_LOGIC_VECTOR (7 downto 0);
a31 : out STD_LOGIC_VECTOR (7 downto 0);
a32 : out STD_LOGIC_VECTOR (7 downto 0);
a33 : out STD_LOGIC_VECTOR (7 downto 0);
b11 : out STD_LOGIC_VECTOR (7 downto 0);
b12 : out STD_LOGIC_VECTOR (7 downto 0);
b13 : out STD_LOGIC_VECTOR (7 downto 0);
b21 : out STD_LOGIC_VECTOR (7 downto 0);
b22 : out STD_LOGIC_VECTOR (7 downto 0);
b23 : out STD_LOGIC_VECTOR (7 downto 0);
b31 : out STD_LOGIC_VECTOR (7 downto 0);
b32 : out STD_LOGIC_VECTOR (7 downto 0);
b33 : out STD_LOGIC_VECTOR (7 downto 0);
sortie : out STD_LOGIC_VECTOR (7 downto 0));
end demultiplexeur;

architecture Behavioral of demultiplexeur is

begin

process(selectentree,entree) is
begin
case selectentree is
When "00000001"=>a11<=entree; --1
When "00001001"=>b11<=entree; --9
When "00010001"=>a12<=entree; --17
When "00011001"=>b12<=entree; --25
When "00100001"=>a13<=entree; --33
When "00101001"=>b13<=entree; --41
When "00110001"=>a21<=entree; --49
When "00111001"=>b21<=entree; --57
When "01000001"=>a22<=entree; --65
When "01001001"=>b22<=entree; --73
When "01010001"=>a23<=entree; --81
When "01011001"=>b23<=entree; --89
When "01100001"=>a31<=entree; --97
When "01101001"=>b31<=entree; --105
When "01110001"=>a32<=entree; --113
When "01111001"=>b32<=entree; --121
When "10000001"=>a33<=entree; --129
When "10001001"=>b33<=entree; --137
When others => sortie<=(others=>'0');
end case;
end process;
end Behavioral;
TRAVAUX DE MEMOIRE

SYNTHESE D’UNE ARCHITECTURE


SYSTOLIQUE SUR FPGA

Etudiant : Angelo BOTOLAHY

Encadreur : M.ANDRIANIVOSOA Ramamonjy

RESUME :
La machine systolique est le fusionnement d’une machine cellulaire et d’une machine vectorielle. Elle
emprunte aux machines cellulaires l’organisation générale (grille). La partie opératoire est constituée
des processeurs élémentaires PEs identiques reliés par un réseau d’interconnexion ; elle emprunte
aux machines vectorielles le mode de fonctionnement pipeline.

Ce travail exploite la théorie de la machine parallèle, de la machine cellulaire, de la machine


vectorielle.

On traite aussi la théorie de la machine systolique appliquée au produit de deux matrices, son
principe mathématique et la mise en œuvre des algorithmes d’un processeur. L’étude se poursuit à
l’architecture de la machine systolique matériellement. On a fait la synthèse sur FPGA grâce au
langage VHDL. Le projet est achevé par la simulation et la réalisation d’un logiciel nommé
« SystoRice » avec lequel on a pu effectuer une transmission de données entre l’ordinateur et la
carte FPGA.

Mot clés : Parallélisme, systolique, processeur, cellule, interconnexion, pipeline,


séquentiel, vectoriel, flux, instruction

Vous aimerez peut-être aussi