rapport Mini-projet Vhdl Calculateur De Harvardprojet.budgie.free.fr/fichiers/Divers/bazar aux...
Transcript of rapport Mini-projet Vhdl Calculateur De Harvardprojet.budgie.free.fr/fichiers/Divers/bazar aux...
LEFEVRE Juin 2007CHALOPINELEC II
Rapport mini-projet VHDL
Calculateur de Harvard
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 1
Table des matières1.Introduction....................................................................................................................................... 42. Modèle de programmation du calculateur........................................................................................4
A. Format registre............................................................................................................................ 5B. Format immédiat......................................................................................................................... 6C. Format branchement....................................................................................................................6
3. Architecture de Harvard................................................................................................................... 7A. La mémoire de données.............................................................................................................. 8B. Le chemin de données.................................................................................................................9
B.1 Le fichier de registres......................................................................................................... 10B.2 L’unité fonctionnelle.......................................................................................................... 10B.3 Le bloc zero fill.................................................................................................................. 11B.4. Description en VHDL....................................................................................................... 11
C. L’unité de contrôle.................................................................................................................... 12C.1 Le compteur ordinal........................................................................................................... 12C.2 Le décodeur d’instructions................................................................................................. 12C.4 Le Bloc Branch control...................................................................................................... 13C.5 Description en VHDL........................................................................................................ 14
D. Le calculateur complet..............................................................................................................144.Descriptif du travail.........................................................................................................................16
4.A La Mémoire de données..........................................................................................................16Simulations et validations :....................................................................................................... 17
4.B Le Data Path............................................................................................................................194.B.1. Le banc de registre.....................................................................................................194.B.2. Les flags (indicateurs):.............................................................................................. 214.B.3. Le zero fill:................................................................................................................ 214.B.4. Les multiplexeurs:..................................................................................................... 214.B.5. L'unité fonctionnelle:.................................................................................................214.B.6. Simulations et validations:.........................................................................................22
4.C L'unité de Contrôle..................................................................................................................234.C.1 La mémoire d'instructions:.............................................................................................. 244.C.2 Le Branch Control:..........................................................................................................244.C.3 Le Bloc d'extension:........................................................................................................ 254.C.4 Extraction de l'instruction:...............................................................................................254.C.5 Le Compteur de Programme........................................................................................... 254.C.6 Décodage :.......................................................................................................................25
4.D Le calculateur Complet........................................................................................................... 26Simulations et validations:................................................................................................... 27
5. Conclusion:.....................................................................................................................................286. Annexes.......................................................................................................................................... 29
6.A Mémoire:.................................................................................................................................296.A.1 memoire.vhd....................................................................................................................296.A.1 Testmemoire.vhd.............................................................................................................326.A.3 program.txt...................................................................................................................... 356.A.4 SimuMemoire.txt............................................................................................................ 366.A.5 Chronogrammes.............................................................................................................. 37
6.B DataPath:................................................................................................................................. 386.B.1 DataPath.vhd................................................................................................................... 386.B.2 TestDataPath.vhd............................................................................................................ 42
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 2
6.B.3 initReg.txt........................................................................................................................ 456.B.4 SimuDataPath.txt.............................................................................................................466.B.5 Chronogrammes.............................................................................................................. 48
6.C Unité de Contrôle:................................................................................................................... 496.C.1 Ctrl Unit.vhd....................................................................................................................496.C.2 TestCtrl_Unit.vhd............................................................................................................536.C.3 programRom.txt.............................................................................................................. 556.C.4 SimuCtrl_Unit.txt............................................................................................................ 566.C.5 Chronogrammes:............................................................................................................. 58
6.D Le calculateur de Harvard:......................................................................................................596.D.1 HarvardCalculator.vhd.................................................................................................... 596.D.2 testHarvardCalculator.vhd.............................................................................................. 626.D.3Chronogrammes............................................................................................................... 63
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 3
Avant-propos
Le mini-projet qui vous est proposé de réaliser vise comme objectif essentiel de faire lasynthèse de toutes vos connaissances accumulées dans le module d’enseignement VHDL. Ilpermet également de parfaire des connaissances dispensées dans d’autres modules enproposant une description d’une architecture dont les principes ont pu être étudiés dans cesmodules. Enfin, ce mini-projet est destiné à vous permettre de développer une premièreexpérience pratique de la modélisation VHDL, dans des conditions proches de celles d’unfonctionnement en entreprise.
1. IntroductionLes circuits non programmables déterminent les opérations à exécuter sur la base
uniquement de ces entrées de contrôle et de bits d’états du chemin de données. Un tel circuit n’exécute donc qu’une seule opération définie (ex : multiplication par additions et décalages, affichage d’une donnée décimale, etc). Par opposition, un microprocesseur est responsable de l’extraction d’instructions depuis la mémoire et du séquencement de l’exécution de ces instructions (calcul de l’adresse suivante de l’instruction à exécuter). Dans ce type d’architecture, le microprocesseur est composé d’un chemin de données dont les opérations sont pilotées par une unité de contrôle. La tâche de cette unité de contrôle consiste à extraire, décoder et exécuter les instructions. Un calculateur bâtit sur le modèle de harvard possède la faculté de traiter l’ensemble de ces opérations en un cycle d’horloge élémentaire. La séparation physique des données et instructions dans deux composants distincts est une des conditions indispensable. L’interconnexion de ces composants au travers de signaux permettant de propager les signaux de données ainsi que signaux de contrôle permettra de définir le modèle interne du microprocesseur. L’objectif du projet est de décrire le comportement des différents composants de ce modèle interne, modèle qui sera vérifié par simulation VHDL sous ModelSim.
2. Modèle de programmation du calculateurLe programmeur d’un calculateur doit spécifier les instructions à exécuter à l’aide d’un
programme. Un programme peut donc se définir comme une liste d’instructions spécifiant les opérations (code opération) et leurs opérandes. Il peut également s’agir d’instructions de contrôle du déroulement du programme indiquant des branchements conditionnels ou inconditionnels à effectuer. Le registre compteur ordinal (PC) permet de conserver en mémoire l’adresse de la prochaine instruction à exécuter.
Les instructions sont stockées dans une mémoire d’instructions tandis que les opérandespeuvent être stockées dans différents emplacements :
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 4
� un champ de l’instruction� un registre dans un fichier de registres� un emplacement mémoire de donnéesPar conséquent, outre la nature de l’opération à exécuter, le code opération doit préciser les
modalités d’exécution de l’instruction et préciser l’emplacement des opérandes à utiliser. Onparle de format d’instruction ou encore de méthode d’adressage (Figure 1). Le format desinstructions qui nous intéresse ici est un format fixe (toutes les instructions sont codées sur un nombre de bits identique). Le format utilisé dans le cadre de notre calculateur fait apparaîtrel’utilisation de 3 champs adresse/opérande. On distingue par ailleurs 3 formatsd’instruction différents:
A. Format registre
Dans le cas d’un format registre, les 3 champs fournissent un n° de registre à utiliser comme emplacement des opérandes source A,B ou comme emplacement destinataire du résultat. Les champs étant codés sur 3 bits, on peut désigné jusqu’à 8 registres (23). Un des champs source peut s’avérer non significatif lorsque l’instruction n’a besoin que d’un seul opérande. Par exemple, l’instruction codée
0001011 011 101 XXX code machineNOT R3 R5 assembleur
définit une instruction de complément à 1 (NOT) du registre n°5 (Reg src A), résultat dans le registre n°3 (destination). La valeur des bits du champ B n’est pas significative. On notera que certaines opérations utilisent le champ B au lieu du champ A. Le champ registre destinataire peut également ne pas s’avérer significatif lorsqu’il s’agit d’un transfert vers la mémoire, un des registres stockant l’adresse mémoire pour le transfert. Par exemple, l’instruction codée
0100000 XXX 100 101 code machineST R4,R5 assembleur
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 5
définit une demande de transfert de la valeur de R5 à l’emplacement mémoire d’adressecontenue dans R4.
B. Format immédiatDans le cas d’un format immédiat, un des opérandes est implicitement stocké dans
l’instruction, dans le champ de droite en l’occurrence ici. Il s’agit donc d’une constante dontla valeur se situera dans l’intervalle 0 à 7. Par exemple,
1000010 010 111 011 code machineADI R2 R7 3 assembleur
spécifie une opération d’addition de R7 avec la constante 3, avec résultat de l’opération dansR2.
C. Format branchementPar opposition aux deux formats précédents, le dernier format d’instruction n’engendre
aucune modification de registre ou de mémoire de données. L’instruction est destinée à modifier (éventuellement sous condition) l’ordre d’extraction des instructions de la mémoire, séquentiel par défaut On parle encore d’instructions de rupture de séquence. Pour cela, le champ d’adresse est séparé en deux parties , avec les 3 bits de poids forts situés dans le champ adresse(G) et les trois bits de poids faibles situés dans le champ adresse (D). La méthode d’adressage est appelée adressage relatif au PC, les 6 bits d’adresses formant le déplacement à ajouter au PC. Ce déplacement est considéré comme signé (représentation en complément à
2). Cela permet de se déplacer dans le sens croissant ou décroissant des adresses. Par exemple,1100000 101 110 100
BRZ R6,-20
spécifie un branchement à l’adresse PC – 20(101100), si R6=0.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 6
La table de la Figure 3 liste les différentes catégories d’instruction. Une description de type transfert de registre explique le mode opératoire de chacune des instructions. La colonne de droite précise si les indicateurs N (pour négatif) et Z (pour zéro) sont affectés par les instructions.
3. Architecture de HarvardOn s’intéresse à présent à l’architecture du calculateur permettant l’exécution des
instructions définit précédemment, en un seul cycle d’horloge. Pour réduire la complexité du modèle, on se propose de décomposer le calculateur en trois entités élémentaires:
� l’unité de contrôle
� le chemin de données
� la mémoire centrale des données
Comme le montre la Figure 4, l’unité de contrôle pilote le chemin de données grâce à un mot de contrôle. Ce mot de contrôle est formé d’un ensemble de signaux de contrôle permettant de positionner le chemin de données en fonction de l’instruction à exécuter.
D’horloge.
Une constante (Opérande immédiat) permet également la récupération de valeur de l’opérande depuis la mémoire d’instructions dans le cas de l’adressage immédiat. Le chemin de données
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 7
communique avec la mémoire de données grâce à deux bus unidirectionnels, selon le sens du transfert à réaliser. Cette particularité, propre à l’architecture harvard, est l’une des particularités (avec la séparation des mémoires d’instructions et de données) autorisant l’exécution des instructions nécessitant des accès en lecture et en écriture dans le même cycle d’horloge.
A. La mémoire de donnéesLa mémoire de données est une mémoire de 216 éléments (adresses) de 16 bits chacun.
L’opération d’écriture est autorisée par le signal de commande MW (pour memory write) sur niveau haut. La valeur du mot de 16 bits correspondant à l’adresse est accessible en permanence sur le bus en lecture. L’adresse du mot en lecture et en écriture est donc commune et toute valeur inscrite dans la mémoire modifie la valeur en sortie une fois celle-ci transférée.
Son comportement sera décrit par un process manipulant une variable de type tableau, process synchrone à l’horloge clk. Le contenu devra pouvoir être initialisé pour mémoriser les données initiales avant exécution du programme(signal rst). Pour cela plusieurs solutions sont possibles avec, dans l’ordre de flexibilité:
• initialisation dans le programme VHDL au niveau de la déclaration : cette solution est la plus simple mais elle suppose une recompilation de la description pour tout changement de contenu.
• déclaration d’un paramètre générique avec initialisation du contenu sur un signal rst. Cette solution ne nécessite plus que la re-compilation de l’entité test en cas de modification du contenu. Mais, il vous faudra définir un package pour déclarer le type de ce paramètre.
• Lecture des données initiales lues à partir d’un fichier : c’est la solution la plus souple car elle ne nécessite aucune recompilation. C’est également la solution la plus proche de la réalité.Vous pouvez définir une fonction load_program, fonction réalisant le chargement de la mémoire au rst.
Vous sélectionnerez une des 3 méthodes, au choix. Le bus d’adresse sera de type unsigned, tandis que les bus de données seront de type signed (package numeric_bit de la bibliothèque ieee). La fonction de conversion to_integer vous permettra de convertir le type unsigned de l’adresse sous forme d’entier, de manière à pouvoir indicer correctement le tableau. On prendra 4 ns comme délai de propagation en lecture ou écriture.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 8
B. Le chemin de donnéesDifférents composants forment la structure du chemin de données partagé. On peut
distinguer:
� un banc de registres, mémoire rapide interne au processeur composé de 8 registres de 16 bits chacun.
� une unité fonctionnelle, circuit combinatoire réalisant des opérations arithmétiques, logiques, décalages ou simples transferts.
� quelques multiplexeurs permettant de configurer le chemin de données en fonction du mot de contrôle.
A titre d’illustration, la table ci-dessous montre quelques exemples de micro-opérationsréalisées par le chemin de données selon l’état du mot de contrôle. Pour chaque microopération,le multiplexeur MB est positionnée en mode registre ou constante. Dans le premiercas, l’opérande utilisé par l’unité fonctionnelle provient du fichier de registre.. Dans le secondcas, l’opérande provient de l’extérieur (de la mémoire d’instructions de l’unité de contrôle) etpasse de 3 à 16 bits par ajout de 13 bits à zéro en tête. Le multiplexeur MD permet d’aiguillerle résultat d’une opération ou une donnée de la mémoire de données (data in) vers un registredu fichier. Les 4 bits FS définissent la nature de l’opération à effectuer le cas échéant.Finalement, RW précise si un registre doit être modifié (1) ou non (0).
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 9
B.1 Le fichier de registresComme pour la mémoire de données, le banc de registre enregistre les données à l’adresse
DR sur un niveau haut de RW. La lecture des données s’effectue sur deux bus distincts, le bus A et le bus B. La présence des données en sortie est permanente et fonction des adresses respectives DA et DB. On notera que les écritures sont synchrones à l’horloge et sont effectuées au début du cycle d’horloge suivant la fin du traitement de l’instruction courante.
B.2 L’unité fonctionnelle
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 10
L’unité fonctionnelle est capable de réaliser différentes opérations s’étendant de la simple opération de transfert pour les mouvements de données internes au microprocesseur ou les transferts impliquant la mémoire externe de données. La table de vérité complète du composant vous est fournie Figure 7.
B.3 Le bloc zero fillComme mentionné précédemment, le microprocesseur peut utiliser une donnée
implicitement contenu dans l’instruction elle-même. L’UF utilisant des données de 16 bits, 13 bits à zéros sont ajoutés en tête de cette donnée de 3 bits pour respecter cette contrainte. Par exemple,
110 devient 0000000000000110
B.4. Description en VHDL
La description des différents composants du chemin de données s’effectuera à l’aided’instructions d’affectations concurrentes pour les différents signaux : bus D, dataout, ardout,busB, etc. On n’oubliera pas de décrire le comportement des indicateurs d’états en sortie del’UF avec comme convention:
• Z =1 si le résultat de l’opération est nul• N=1 si le résultat de l’opération est négatif.
La description des indicateurs C(carry) et V(overflow) sera facultative. Le signal rst permettrade positionner les registres dans un état initial souhaité. On retiendra les temps de propagation
• Lecture ou écriture d’un registre du fichier de registre : 3 ns• Multiplexeurs (MD ou MB) et indicateurs: 1 ns• Unité fonctionnelle : 4 ns
On notera que des conversions unsigned-signed peuvent être nécessaire lors, par exemple, dela récupération d’une adresse à partir du bus de données (par un simple « cast »).
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 11
C. L’unité de contrôleBien que traditionnellement considérée comme ne faisant pas partie de l’unité de contrôle, la
mémoire d’instructions est décrite ici par convenance. Lors de l’exécution du programme,seuls des accès en lecture vers cette mémoire sont possibles.
Outre la mémoire d’instructions (215 x 16 bits), l’unité de contrôle intègre les modulessuivants:
C.1 Le compteur ordinalLe compteur ordinal PC fournit l’adresse de l’instruction à extraire de la mémoire (16 bits).
Le compteur est mis à jour à chaque cycle d’horloge. Il peut s’agir d’une simple incrémentation, d’un chargement de la valeur en sortie du bloc extension (cas d’un branchement conditionnel) ou de l’adresse (cas d’un branchement inconditionnel). Un signal rst asynchrone (non représenté sur la figure) permet le positionnement sur la première adresse du programme à exécuter (adresse 0 généralement).
C.2 Le décodeur d’instructionsLa sortie de la mémoire est exploitée par le décodeur de l’instruction, sortie que l’on
désignera par IR (IR pour instruction register, même s’il ne s’agit pas d’un registre à proprement parlé).
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 12
16 bits des 20 bits en sortie du décodeur permettant de contrôler le fonctionnement du cheminde données forment ce qu’on appelle le mot de contrôle. La valeur de 3 bits DA, BA, AAs’obtient de manière directe à partir des champs d’adresse de l’instruction. Il est en de mêmepour les bits de sélection de l’opération de l’UF (FS) qui sont directement issus des bits depoids faible du code opération de l’instruction, sauf pour l’instruction de branchementconditionnel où les 4 bits de FS seront forcés à zéro. Cela permet l’évaluation des indicateursZ et N par rapport au contenu du registre adressé par RA. L’etat des autres bits du décodeurest fonction de l’instruction et se définit par la table de vérité ci-dessous (Figure 10). Cettetable de vérité montre les différentes catégories d’instructions.
Outre les signaux de commande du chemin de données, on trouve également la valeur dessignaux de commande interne à l’unité de contrôle et permettant la gestion du séquencement(PL, JB, BC). La table de vérité montre que PL vaut 1 lorsque le code opération spécifie uneinstruction de contrôle, JB valant 1 lorsque le branchement est inconditionnel, 0 sinon. Dansle cas d’un branchement conditionnel, BC précise l’indicateur servant de condition debranchement (0 pour Z, 1 pour N).
C.4 Le Bloc Branch controlLe rôle de ce bloc est de déterminer la valeur de LD (autorisation de branchement
conditionnel) en fonction des valeurs des bits BC,N, Z. Le comportement de ce bloc peut êtrespécifié par la table de vérité compactée ci-dessous.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 13
La table de vérité montre que la valeur de LD dépend de l’indicateur utilisé (déterminé parBC) et de la valeur de cet indicateur. Par exemple, si BC=0, il faut Z=1 pour que lebranchement soit effectué.
C.5 Description en VHDL
Comme pour le chemin de données, la description des différents composants s’effectuera à l’aide d’instructions d’affectation concurrentes. Les valeurs non significatives (X) lors du décodage seront forcées à 0. On retiendra les temps de propagation suivants :
• Incrémentation ou chargement du PC : 1 ns
• Lecture de la mémoire d’instructions : 3 ns
• Décodage : 1 ns
D. Le calculateur completLe calculateur complet (dont les entrées/sorties se limitent aux entrées clk et rst) se décrira
en assemblant 2 entités mémoire et CPU, cette dernière entité étant elle-même une entité formée des composants datapath et contrôle.
Le cycle d’horloge devra être réglé par rapport au chemin critique en cumulant les temps depropagation des composants traversés lors de l’exécution d’une instruction la plus longue.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 14
Comme le montre la Figure 16, le cumul des temps de propagation aboutit à un délai de 17 ns.La fréquence d’horloge maximale est donc de 58.8 MHZ.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 15
4.Descriptif du travailPour réaliser ce mini-projet nous avons choisi de respecter l'ordre conseillé dans les sujets.
C'est à dire que nous avons commencé par la conception de la mémoire, puis celle du Data Path et enfin l'Unité de Contrôle.
4.A La Mémoire de donnéesNous avons conçu l'entité mémoire à l'aide de paramètres génériques pour pouvoir la rendre
modulable. Néanmoins nous choisissons d'imposer la même taille pour le bus d'adresse et le bus de donnée. Le temps de propagation dans la mémoire est lui aussi générique.
generic(NbBits : natural ; tco : time);
Nous choisissons de définir notre mémoire comme tableau contenant des entiers signés. Sa taille est donc 2^ NbBits-1, nous appelons notre type mémoire MemTableau.
type MemTableau is array (0 to 2**NbBits-1) of signed(NbBits-1 downto 0);
D'après la description du cahier des charges, l’écriture dans la mémoire de donnée se fait uniquement sur un niveau haut du signal memory_write (mw). La valeur de datain alors écrite sur la sortie dataout ainsi que dans la mémoire à l’adresse adresse (adr).
En mode lecture, on transfère la donnée qui se trouve dans la mémoire à l’adresse adresse sur la sortie dataout.
Les écritures sont synchrones mais les lectures doivent pouvoir s’effectuer en permanence. Le process qui décrit le fonctionnement de cette mémoire est donc sensible aux paramètres clk (l’horloge), rst (reset) et adresse. L'entrée rst permet d'initialiser le contenu de la mémoire à partir d'un fichier.
mem:process(clk,rst,adr) -- declaration de notre memoire, tabdata represente la memoire comme -- un tableau contenant des entiers signés variable tabdata : MemTableau; begin if (rst= '1') then -- rst asynchrone actif etat bas -- première solution : initialisation dans le programme -- VHDL au niveau de la déclaration -- init_zero: for i in 0 to 2**NbBits-1 loop -- tabdata(i):= (others => std_logic'('0')); -- end loop init_zero; -- solution non retenue -- deuxième solution : Lecture des données initiales lues -- à partir d'un fichier : tabdata := load_program; -- les evenements synchrones à l'horloge elsif ( clk='1' and clk'event) then
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 16
if(Mw ='1') then --write dataout<=datain after tco; tabdata(to_integer(adr)):=datain ; end if; --write
end if; -- rst/clk --read asynchrone
dataout <= tabdata(to_integer(adr)) after tco; end process;--memend behv;
Pour initialiser la mémoire nous avons opté pour une lecture de fichier. Cela permet de pouvoir facilement changer les données d’initialisation sans recompiler tout le code VHDL. Nous avons donc créé une fonction load_program (comme c'est conseillé dans le sujet) qui lit le fichier ’program.txt’ et écrit ses valeurs dans la mémoire. Les données dans le fichier sont des entiers qui représentent respectivement l’adresse mémoire et la valeur à inscrire. Ils sont en format entier naturel dans le fichier et convertis lors de l’écriture dans la mémoire.
function load_program return MemTableau is file fd : text open READ_MODE is "program.txt"; variable ligne : line; variable data : integer; variable adr : natural; variable mem2 : MemTableau; begin while not endfile(fd) loop readline(fd,ligne); if ligne'length > 0 and ligne(1) /='-' then read(ligne,adr ); read(ligne,data); mem2(adr):=to_signed(data,NbBits); end if; end loop; return mem2;end load_program;
Simulations et validations :Pour valider le comportement de notre mémoire nous avons encore une fois fait appel à
l’utilisation d’un fichier de simulation ’SimuMemoire.txt’ dans lequel nous avons incorporé des driver de rst, mw, adr et datain. Cela permet une modification aisée des paramètres de la simulation sans recompiler tout le code . De plus la lisibilité est accrue par rapport à une affectation ‘classique’ des signaux dans le fichier VHDL de test.
Lors de l'initialisation de la mémoire ( sur le signal rst) nous choisissons de charger à partir de l'adresse 0, le programme de test est fourni dans le sujet. Voici donc le contenu du fichier ’program.txt’:
0 5120
1 8280
2 49288
3 8352
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 17
4 49296
5 2762
6 49692
7 208
8 264
9 57400
10 200
11 272
12 49304
13 1028
14 3288
15 57400
Pour valider le comportement de la mémoire nous commençons par faire un reset avec rst à l'état bas, puis on le maintient au niveau haut pour le reste de la simulation. Ensuite on vérifie que le programme a bien été chargé, en demandant des lecture à l'adresse 0 jusqu'à l'adresse 5. Les 6 premières valeurs du programme précédemment chargé doivent alors apparaître sur la sortie et respecter les temps de propagation. On demande ensuite des écritures (mw état haut) de données aléatoires à des adresses aléatoires. Puis on demande des lectures aux adresses où l'on vient d'écrire.
Dataout doit alors correspondre au précédentes entrées. Voici le contenu du fichier de test :
-- RST MW ADR DATAIN
0 0 0000000000000000 0000000000000001
1 0 0000000000000001 0000000000000001
1 0 0000000000000010 0000000000000010
1 0 0000000000000011 0000000000000011
1 0 0000000000000100 0000000000000001
1 0 0000000000000101 0000000000000001
1 0 0000000000000110 0000000110000001
1 0 0000000000000111 0000000110000101
1 0 0000000000001000 0000010000111001
1 0 0000000000001001 0000000000000001
1 0 0000000000000011 0000000000000001
1 0 0000000000000111 0000000000000001
1 0 0000000000000000 0000000000000001
1 0 0000000000000001 0000000000000001
1 0 0000000000000010 0000000000000001
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 18
1 0 0000000000000011 0000000000000001
1 0 0000000000000100 0000000000000001
1 0 0000000000000101 0000000000000001
1 1 0000001110000001 0001000100100011
1 1 0000001000100100 0010010101010101
1 1 0000000000000011 0000000000000001
1 0 0000001110000001 0000000000000001
1 0 0000001000100100 0000000000000001
Les codes VHDL de la mémoire, du test bench de la mémoire ainsi que les résultats de la simulation sont fournis en annexe.
4.B Le Data PathCe module a pour but de diriger les données et d’effectuer des opérations en fonction d’un
mot de contrôle. Le cahier des charges nous impose une description comportementale de type ‘Dataflow’ ce qui nous a posé des problèmes au moment de l’initialisation de ces registres pour effectuer la simulation finale. En effet elle nécessite que des valeurs particulières soient inscrites dans certains registres pour valider le fonctionnement.
4.B.1. Le banc de registre
Le banc de registre est de type Banc_reg. Comme pour la mémoire il est représenté par un tableau contenant des entiers signés. La taille des registres ainsi que leur nombre sont génériques afin de pouvoir facilement changer les caractéristiques du calculateur. Il en est de même pour les différents temps de propagation. Nous avons choisi de donner 8 registres par défaut car bien que ce paramètre soit générique son changement influencerait trop l'architecture du calculateur. Rajouter des registres suplémentaires serait incompatible avec le mot de contrôle (il faudrait rajouter un bit a l'adressage des registres).
type Banc_reg is array (0 to Nbreg-1) of signed(NbBits-1 downto 0);
En description Dataflow on ne peut pas affecter plusieurs fois le même signal. Or dans notre cas nous avons besoin d’initialiser des registres lors d’un reset et aussi d’affecter les registres déterminés par la valeur des bits 15 à 13 du mot de contrôle lors des variations du bus DDATA. Après validation auprès de monsieur Dekneuvel nous avons finalement décidé de réaliser un process sensible à clk (l’horloge) et rst (reset) pour pouvoir initialiser et affecter des valeurs dans les registres.
process(clk,rst)
variable initialisation : Banc_reg :=initBanc_reg;
begin
--initialisation des registres sur reset actif niveau bas
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 19
if rst='0' then
breg<=initialisation after twr_reg;
--ecriture dans les registres synchrone
elsif clk='1' and clk'event then
if ctrlword(0)='1' then
breg(to_integer(ctrlword(15 downto 13))) <= Ddata after twr_reg;
end if;
end if;
end process;
La fonction initBanc_reg permet d'initialiser les registres (sur rst à l'état bas) dans l'état qu'on souhaite grâce au fichier ‘initReg.txt’. La première colonne du fichier correspond au numéro du registre, la deuxième à son contenu lors de l'initialisation. Voici son implementation :
function initBanc_reg return Banc_reg is
file fd :text open READ_MODE is "initReg.txt";
variable breg2: Banc_reg;
variable numli:natural:=0;
variable donnee:std_logic_vector(NbBits-1 downto 0);
variable ligne:line;
begin
while not endfile(fd) loop
readline(fd,ligne);
if ligne'length>0 and ligne(1)/='-' then
read(ligne,numli);
read(ligne,donnee);
breg2(numli):=signed(to_bitvector(donnee));
end if;
end loop;
return breg2;
end initBanc_reg;
Pour gérer les entrées/sorties du banc de registre, nous créons des signaux intermédiaires et nous leur affectons les différents bits du mot de contrôle. Voici comment nous procèdons.
Adata<=breg(to_integer(ctrlword(12 downto 10))) after twr_reg;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 20
Bdata<=breg(to_integer(ctrlword(9 downto 7))) after twr_reg;
data_out<=B;
adr_out<=unsigned(Adata);
4.B.2. Les flags (indicateurs):L’unité de contrôle a besoin de savoir si la valeur F est négative ou nulle. Les signaux N et
Z sont des indicateurs permettent de renseigner l'unité de contrôle. Ces informations sont utiles lors de l’utilisation de sauts conditionnels. Voici comment ils sont gérés:
N<='1' after tuf when to_integer(F)<0 else '0' after tuf;
Z<='1' after tuf when to_integer(F)=0 else '0' after tuf;
4.B.3. Le zero fill:On affecte les bits 0, 1 et 2 puis le reste est complété par des zéros. Nous utilisons 'others'
pour ne pas être dépendant de la taille des données.
Constant_in <= (2=> cste(2),1 => cste(1),0 => cste(0),others=>'0');
Attention cette desciption du zero fill génère un warning à la compilation.
4.B.4. Les multiplexeurs:Nous avons besoins de deux multiplexeurs, un à l'entrée et l'autre à la sortie de l'unité de
l'unité fonctionelle. Le premier gère l'entrée d'un constante sur B. Et l'autre gére l'entrée d'une constante dans le banc de registre.
B<=Constant_in after tmux when ctrlword(6)='1' else Bdata after tmux;
Ddata<=data_in after tmux when ctrlword(1)='1' else F after tmux;
4.B.5. L'unité fonctionnelle:Son rôle est de réaliser les opérations sur les opérandes A et B. Son fonctionnement nous est
donné par une table de vérité. Son comportement est donc combinatoire et peut donc se définir avec un case. Mais comme on ne se trouve pas dan un process. Donc on utilise l'instruction with...select. Nous utilisons others pour les combinaisons non définies. Et lorsque cela se produit l'unité fonctionnelle renvoie '0'. Voici sont implémentation:
with ctrlword(5 downto 2) select
F<=A after tuf when "0000",
A+1 after tuf when "0001",
A+B after tuf when "0010",
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 21
A+B+1 after tuf when "0011",
A+(not B) after tuf when "0100",
A+(not B)+1 after tuf when "0101",
A-1 after tuf when "0110",
A after tuf when "0111",
A and B after tuf when "1000",
A or B after tuf when "1001",
A xor B after tuf when "1010",
(not A) after tuf when "1011",
B after tuf when "1100",
'0'&B(NbBits-1 downto 1) after tuf when "1101",--left shift
B(NbBits-2 downto 0)&'0' after tuf when "1110",--right shift
"0" after tuf when others; --renvoie zero quand le code FS n'est pas reconnu
4.B.6. Simulations et validations:Pour valider le DataPath nous utilisns toujours les fichiers, pour les mêmes raisons décrites
précédemment pour la mémoire. Nous utilisons 2 fichiers. Le premier initialise les registres, le deuxième contient les drivers des fichiers de test.Voici le contenu du fichier qui initialise les registres:
--ième registre data
0 0000000000000001
1 0000000000000101 -- 5
2 0000000000000100
3 0000000011111000 -- 248
4 0000000000010000
5 0000000000000000 -- 0
6 0000000001000000
7 0000000010000000
Le deuxième fichier va définir le comportement des signaux de test du dataPath. Lors de ce test nous effectuons divers micros opérations pour valider son comportement (addition, load etc).
Voici le contenu de ce deuxième fichier (des commentaires donnent des explications sur les opérations effectuées) :
--clk rst ctrlword dataIn cste
-- reset
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 22
0 0 0000000000000011 1111111111111111 001
1 0 0000000000000011 1111111111111111 001
-- R0<- Datain
0 1 0000000000000011 0000000100000011 001
1 1 0000000000000011 0000000100000011 001
-- R1<- Datain
0 1 0010000000000011 0000000000000001 001
1 1 0010000000000011 0000000000000001 001
-- R7<- Datain (oxCAFE!!!!!j'aime le café!)
0 1 1110000000000011 1100101011111110 001
1 1 1110000000000011 1100101011111110 001
-- R3<-R1+R0 (resulat= 0000000000000010)
0 1 0110010000001001 1100101011111110 010
1 1 0110010000001001 1100101011111110 010
-- R3<-Datain signed(-1)
0 1 0110000000000011 1111111111111111 010
1 1 0110000000000011 1111111111111111 010
-- dataout<-R7
0 1 0000001110000000 0000000000000111 010
1 1 0000001110000000 0000000000000111 010
-- R6<-R7+(cte=1) (resulat = oxCAFF Caisse Allocation Familiale Française haha!!)
0 1 1101110001001001 0000000000000111 001
1 1 1101110001001001 0000000000000111 001
-- R5<-R0+2
0 1 1010000001001001 0000000000000111 010
1 1 1010000001001001 0000000000000111 010
-- R6<- Datain (j'aime vraiment le cafe)
0 1 1100000000000011 1100101011111110 001
1 1 1100000000000011 1100101011111110 001
Les codes VHDL du DataPath, son test bench ainsi que les résultats de la simulation sont fournis en annexe.
4.C L'unité de ContrôleLe rôle de ce bloc est de fournir le mot de contrôle en fonction de la donnée chargée dans la
mémoire d’instructions. Le cahier des charges nous spécifie une description comportementale de
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 23
type dataflow.
4.C.1 La mémoire d'instructions:Comme pour l'entité mémoire nous choisissons pour la mémoire d'instruction d'utiliser un
tableau contenant des entiers mais cette fois-ci non signés:
type ROM is array(0 to 2**NbBits-1) of unsigned(NbBits-1 downto 0);
Cette mémoire est initialisée à l'aide d'un fichier qui contient le programme à exécuter. Voici la fonction qui initialise la mémoire d'instruction:
function initROM return ROM is
file fd :text open READ_MODE is "programRom.txt";
variable mem2: ROM;
variable numli:natural:=0;
variable data:std_logic_vector(NbBits-1 downto 0);
variable ligne:line;
begin
while not endfile(fd) loop
readline(fd,ligne);
if ligne'length>0 and ligne(1)/='-' then
read(ligne,data);
mem2(numli):=unsigned(to_bitvector(data));
numli:=numli+1;
end if;
end loop;
return mem2;
end initROM;
Comme cette mémoire n'est accessible seulement en lecture, nous choisissons d'utliser une constante pour représenter cette mémoire:
constant mem_instruc: ROM:=initRom;
4.C.2 Le Branch Control:Le branch Control spécifie au PC s'il faut effectuer un saut d'adresse ou charger une adresse
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 24
externe déterminée par le bloc d'extension. Le comportement du Branch Control est définie dans le cahier des charges.Voici comment nous l'avons décrit en VHDL:
Ld<=Z when (BC='0') else N when (BC='1');
4.C.3 Le Bloc d'extension:Ce bloc a pour but de définir le saut d’adresse à effectuer. Il prend en entrée la concaténation
des bits 8 à 6 et 2 à 0 de la sortie IR de la mémoire d’instruction. Il faut procéder à une extension des bits pour pouvoir faire l’addition à la valeur courante de PC. Pour cela on étend avec la valeur du bit de poids fort, c'est-à-dire IR(8). Voici comment nous avons procédé:
extension<=(5=>IR_sur_16_bits(8),4=>IR_sur_16_bits(7),3=>IR_sur_16_bits(6),
2=>IR_sur_16_bits(2),1=>IR_sur_16_bits(1),0=>IR_sur_16_bits(0),others=>IR_sur_16_bits(8));
4.C.4 Extraction de l'instruction:L'instruction est chargée à partir de la mémoire depuis l'adresse pointé par PC. Les deux bits
de poids faible de l'instruction sont renvoyés vers le bloc d'extension:
IR_sur_16_bits<=mem_instruc(to_integer(PC)) after t_r_mem;
IR<=signed(IR_sur_16_bits(2 downto 0));
4.C.5 Le Compteur de ProgrammeIl fournit en sortie la valeur de l’adresse à laquelle il faut aller chercher l’instruction dans la
mémoire d’instructions. Son comportement est défini dans la table donnée dans le cahier des charges. Son fonctionnement est synchrone à l’horloge, on a donc sur chaque front montant une nouvelle adresse en sortie de ce bloc.
PC<=(others=> '0') after t_inc_load when rst='0' else
PC+1 after t_inc_load when (PL='0' or (PL='1' and JB='0' and Ld='0')) and CLK'event and CLK='1' else
adr after t_inc_load when PL='1' and JB='1' and CLK'event and CLK='1' else
PC+extension after t_inc_load when PL='1' and JB='0' and Ld='1' and CLK'event and CLK='1';
4.C.6 Décodage :Il fournit le mot de contrôle en sortie du décodeur ainsi que la valeur des signaux MW, PL,
JB et BC. L’analyse de la table de vérité fournie dans le cahier des charges nous a permis
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 25
d'effectuer quelques simplifications (de type karnaugh) et donc de modéliser son comportement de la façon suivante :
-- DA
DA<=IR_sur_16_bits(8 downto 6) after t_dec;
-- AA
AA<=IR_sur_16_bits(5 downto 3) after t_dec;
-- BA
BA<=IR_sur_16_bits(2 downto 0) after t_dec;
-- FS
FS<="0000" after t_dec when PL='1' and JB='0' else IR_sur_16_bits(5 downto 2) after t_dec;
-- MB
MB<='1' after t_dec when IR_sur_16_bits(15 downto 13)="100" else '0' after t_dec;
-- MD
MD<='1' after t_dec when IR_sur_16_bits(15 downto 13)="001" else '0' after t_dec;
-- RW
RW<='1' after t_dec when IR_sur_16_bits(14)='0' else '0' after t_dec;
-- MW
MW<='1' after t_dec when IR_sur_16_bits(15 downto 13)="010" else '0' after t_dec;
-- PL
PL<='1' after t_dec when IR_sur_16_bits(15 downto 14)="11" else '0' after t_dec;
-- JB
JB<='1' after t_dec when IR_sur_16_bits(15 downto 13)="111" else '0' after t_dec;
-- BC
BC<='1' after t_dec when IR_sur_16_bits(15 downto 13)&IR_sur_16_bits(9)="1101" else '0' after t_dec;
Le mot de contrôle est juste la concaténation dans le bon ordre des différents signaux du décodeur d'instruction:
ctrlword<=DA&AA&BA&MB&FS&MD&RW;
4.D Le calculateur CompletLe calculateur complet est juste l'assemblage des trois composants précédemment conçus. Il
n'y a pas de réelle subtilité à décrire dans son implémentation VHDL. Comme le nombre de fils à relier est élevé, nous avons tenté de donner des noms aux signaux, qui traduisent d'où ils partent et où ils vont :
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 26
signal Mw_uc_to_mem : bit;
signal data_dp_to_mem : signed(NbBits-1 downto 0);
signal adr_out_dp_to_mem_and_uc: unsigned(NbBits-1 downto 0);
signal ctrlword_uc_to_dp : unsigned(NbBits-1 downto 0);
signal cste_uc_to_dp : signed(2 downto 0);
signal data_mem_to_dp: signed(NbBits-1 downto 0);
signal V_dp_to_uc, C_dp_to_uc, N_dp_to_uc, Z_dp_to_uc : bit;
Simulations et validations:La validation de notre Calculateur de Harvard consiste en l'exécution réussie du programme
fourni en exemple. Les seuls signaux qui doivent être drivés pendant la simulation sont la clk et le rst. Nous n'avons donc pas créé de fichier spécifiques pour cette simulation. Les codes VHDL du Calculateur de Harvard , son test bench ainsi que les résultats de la simulation sont fournis en annexes.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 27
5. Conclusion:Ce mini projet nous a permis de mettre en avant nos connaissances dans la programmation
en VHDL. Nous avons pu réaliser un calculateur de Harvard fonctionnel. Ce fut un projet intéressant dans la mesure où nous avons été confrontés à des problèmes de conceptions complexes. Le calculateur de Hardvard que nous avons décrit peut être considéré comme une ébauche de micro-processeur, ce qui est très gratifiant. Il serait maintenant intéressant de vérifier si le code que nous avons écrit est synthétisable, pour pouvoir l'implémenter dans un composant programmable de type FPGA.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 28
6. Annexes
6.A Mémoire:
6.A.1 memoire.vhdVoici le code VHDL de la mémoire:
library IEEE;
use ieee.numeric_bit.all;
--use IEEE.numeric_std.all;
use std.textio.all;--import pour gérer les fichiers
-----------------------------
-- l'entité memoire
-----------------------------
entity memoire is
generic(NbBits : natural ; tco : time);
port(datain : in signed(NbBits-1 downto 0);
Mw,rst,clk : in bit;
adr : in unsigned(NbBits-1 downto 0);
dataout : out signed(NbBits-1 downto 0));
end memoire;
architecture behv of memoire is
-- defintion de la memoire comme un tableau d'entiers signés
type MemTableau is array (0 to 2**NbBits-1) of signed(NbBits-1 downto 0);
----------
-- FONCTION : initialise la mémoire, charge le programme
----------
function load_program return MemTableau is
file inputStream : text open READ_MODE is "program.txt";
variable ligne : line;
variable data : integer;
variable adr : natural;
variable mem2 : MemTableau;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 29
begin
while not endfile(inputStream) loop
readline(inputStream,ligne);
if ligne'length > 0 and ligne(1) /='-' then
read(ligne,adr);
read(ligne,data);
mem2(adr):=to_signed(data,NbBits);
end if;
end loop;
return mem2;
end load_program;
----------
-- DESCRIPTION
----------
begin
mem:process(clk,rst,adr)
-- declaration de notre memoire, tabdata represente la memoire comme
-- un tableau contenant des entiers signés
variable tabdata : MemTableau;
begin
if (rst= '0') then -- rst asynchrone actif etat bas
-- première solution : initialisation dans le programme
-- VHDL au niveau de la déclaration
-- init_zero: for i in 0 to 2**NbBits-1 loop
-- tabdata(i):= (others => std_logic'('0'));
-- end loop init_zero;
-- solution non retenue
-- deuxième solution : Lecture des données initiales lues
-- à partir d?un fichier :
tabdata := load_program;
-- les evenements synchrones à l'horloge
elsif ( clk='1' and clk'event) then
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 30
if(Mw ='1') then
--write
dataout<=datain after tco;
tabdata(to_integer(adr)):=datain ;
end if; --write
end if; -- rst/clk
--read
dataout <= tabdata(to_integer(adr)) after tco;
end process;--mem
end behv;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 31
6.A.1 Testmemoire.vhdVoici le TestBench de la mémoire:
library IEEE;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;--import pour gérer les fichiers
entity testmem is
end entity;
architecture bench of testmem is
component memoire is
generic(NbBits : natural ;
tco : time);
port(datain : in signed(NbBits-1 downto 0);
Mw,rst,clk : in bit;
adr : in unsigned(NbBits-1 downto 0) ;
dataout : out signed(NbBits-1 downto 0));
end component;
--décalration des constantes
constant NbBits : natural := 16;
constant tco : time := 4 ns;
constant cycle : time := 10 ns;
--déclaration des signaux de test
signal datain_test : signed(NbBits-1 downto 0);
signal Mw_test : bit :='0';
signal rst_test,clk_test : bit :='1';
signal adr_test : unsigned(NbBits-1 downto 0);
signal dataout_test : signed(NbBits-1 downto 0);
file fd :text open READ_MODE is "SimuMemoire.txt";
begin
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 32
mem : memoire generic map(NbBits=>NbBits,tco=>tco)port map(datain=>datain_test,Mw=>Mw_test,rst=>rst_test,clk=>clk_test,adr=>adr_test,dataout=>dataout_test);
SIMU:process
--declaration des signaux
variable datainF: std_logic_vector(NbBits-1 downto 0);
variable MwF,rstF: bit;
variable adrF: std_logic_vector(NbBits-1 downto 0);
variable ligne:line;
begin
while not endfile(fd) loop
readline(fd,ligne);
if ligne'length>0 and ligne(1)/='-' then
read(ligne,rstF);
read(ligne,MwF);
read(ligne,adrF);
read(ligne,datainF);
--affectation des isugnaux lus dans le fichier
rst_test<=rstF;
Mw_test<=MwF;
adr_test<=unsigned(adrF);
datain_test<=signed(datainf);
clk_test<=not clk_test;
wait for cycle;
clk_test<=not clk_test;
wait for cycle;
end if;
end loop;
end process;
end bench;
--datain_test <= X"aaaa" after 25 ns, X"a0a0" after 35 ns, X"0a0a" after 45 ns, X"ffff" after 55 ns;
--Mw_test <='0' after 20 ns, '1' after 25 ns, '0' after 75 ns;
--rst_test <='1' after 10 ns, '0' after 12 ns;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 33
--clk_test <=not clk_test after 10 ns;
--adr_test <=X"0000" after 20 ns,X"0001" after 30 ns,X"0002" after 40 ns,X"0001" after 100 ns,X"0000" after 130 ns;
--end bench;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 34
6.A.3 program.txtVoici le fichier contenant le programme chargé sur le rst de la mémoire:
0 5120
1 8280
2 49288
3 8352
4 49296
5 2762
6 49692
7 208
8 264
9 57400
10 200
11 272
12 49304
13 1028
14 3288
15 57400
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 35
6.A.4 SimuMemoire.txtVoici le fichier contenant les drivers des signaux de test de la mémoire:
-- RST MW ADR DATAIN
0 0 0000000000000000 0000000000000001
1 0 0000000000000001 0000000000000001
1 0 0000000000000010 0000000000000010
1 0 0000000000000011 0000000000000011
1 0 0000000000000100 0000000000000001
1 0 0000000000000101 0000000000000001
1 0 0000000000000110 0000000110000001
1 0 0000000000000111 0000000110000101
1 0 0000000000001000 0000010000111001
1 0 0000000000001001 0000000000000001
1 0 0000000000000011 0000000000000001
1 0 0000000000000111 0000000000000001
1 0 0000000000000000 0000000000000001
1 0 0000000000000001 0000000000000001
1 0 0000000000000010 0000000000000001
1 0 0000000000000011 0000000000000001
1 0 0000000000000100 0000000000000001
1 0 0000000000000101 0000000000000001
1 1 0000001110000001 0001000100100011
1 1 0000001000100100 0010010101010101
1 1 0000000000000011 0000000000000001
1 0 0000001110000001 0000000000000001
1 0 0000001000100100 0000000000000001
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 36
6.A.5 ChronogrammesVoici le résulat de la simualtion pour la mémoire:
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 37
Sur ce chronogramme, on peut voir en premier un rst qui charge le programme dans la mémoire.En suite des lectures sont demandées, et la mémoire envoie sur la sortie les valeurs qui ont été précedemment chargées par le rst.Après quelques lectures, des écritures sont demandées. La mémoire enregistre les données aux adresses demandées. Des lectures sont effectuées sur ces même adresses. On peut voir en sortie les données précédemment entrées.Les temps de propagation sont respectés.La mémoire est donc validée.
6.B DataPath:
6.B.1 DataPath.vhdVoici le fichier source VHDL du Datapath:
library ieee;
use ieee.numeric_bit.all;
--use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity datapath is
generic(NbBits: natural;
Nbreg: natural := 8;
twr_reg : time; -- temps acces w/r du banc de registre
tmux : time; --temps multiplexeur et indicateur
tuf : time); -- temps unité fonctionnele
port(clk:in bit;
rst: in bit;
ctrlword: in unsigned(NbBits-1 downto 0);
cste: in signed(2 downto 0);
data_in: in signed(NbBits-1 downto 0);
data_out: out signed(NbBits-1 downto 0);
adr_out: out unsigned(NbBits-1 downto 0);
V,C,N,Z: out bit);
end Datapath;
architecture dflow of datapath is
--description du Banc de registre comme un tableau de
--Nbreg entier signés de NbBits bits ici 8 et 16
type Banc_reg is array (0 to Nbreg-1) of signed(NbBits-1 downto 0);
-- les signaux du datapath
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 38
signal breg: Banc_reg;
signal A,B,F,AData,Bdata,Ddata,Constant_in: signed(NbBits-1 downto 0);
----------
--fonction d'initialisation des registres
---------
function initBanc_reg return Banc_reg is
file fd :text open READ_MODE is "initReg.txt";
variable breg2: Banc_reg;
variable numli:natural:=0;
variable donnee:std_logic_vector(NbBits-1 downto 0);
variable ligne:line;
begin
while not endfile(fd) loop
readline(fd,ligne);
if ligne'length>0 and ligne(1)/='-' then
read(ligne,numli);
read(ligne,donnee);
breg2(numli):=signed(to_bitvector(donnee));
end if;
end loop;
return breg2;
end initBanc_reg;
--DESCRIPTION
begin
process(clk,rst)
variable initialisation : Banc_reg :=initBanc_reg;
begin
--initialisation des registres sur reset actif niveau bas
if rst='0' then
breg<=initialisation after twr_reg;
--ecriture dans les registres synchrone
--actif et MW niveau haut
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 39
elsif clk='1' and clk'event then
if ctrlword(0)='1' then
breg(to_integer(ctrlword(15 downto 13))) <= Ddata after twr_reg;
end if;
end if;
end process;
-- Banc de registre
Adata<=breg(to_integer(ctrlword(12 downto 10))) after twr_reg;
Bdata<=breg(to_integer(ctrlword(9 downto 7))) after twr_reg;
data_out<=B;
adr_out<=unsigned(Adata);
--les flags
N<='1' after tuf when to_integer(F)<0 else '0' after tuf;
Z<='1' after tuf when to_integer(F)=0 else '0' after tuf;
--"zero fill"
Constant_in <= (2=> cste(2),1 => cste(1),0 => cste(0),others=>'0');
--entrée de l'unite fonctionnelle
A<=Adata;
--le mux
B<=Constant_in after tmux when ctrlword(6)='1' else Bdata after tmux;
--Unité fonctionnelle
with ctrlword(5 downto 2) select
F<=A after tuf when "0000",
A+1 after tuf when "0001",
A+B after tuf when "0010",
A+B+1 after tuf when "0011",
A+(not B) after tuf when "0100",
A+(not B)+1 after tuf when "0101",
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 40
A-1 after tuf when "0110",
A after tuf when "0111",
A and B after tuf when "1000",
A or B after tuf when "1001",
A xor B after tuf when "1010",
(not A) after tuf when "1011",
B after tuf when "1100",
'0'&B(NbBits-1 downto 1) after tuf when "1101",--left shift
B(NbBits-2 downto 0)&'0' after tuf when "1110",--right shift
"0" after tuf when others; --renvoie zero quand le code FS n'est pas reconnu
--le mux D
Ddata<=data_in after tmux when ctrlword(1)='1' else F after tmux;
end dflow;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 41
6.B.2 TestDataPath.vhdVoici le testBench utlisé pour simuler et valider le DataPath:
--chargement des librairies
library ieee;
use ieee.numeric_bit.all;
use std.textio.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
entity testdatapath is
end entity;
architecture bench of testdatapath is
component datapath is
generic(NbBits: natural;
Nbreg: natural := 8;
twr_reg : time; -- temps acces w/r du banc de registre
tmux : time; --temps multiplexeur et indicateur
tuf : time); -- temps unité fonctionnele
port(clk:in bit;
rst: in bit;
ctrlword: in unsigned(NbBits-1 downto 0);
cste: in signed(2 downto 0);
data_in: in signed(NbBits-1 downto 0);
data_out: out signed(NbBits-1 downto 0);
adr_out: out unsigned(NbBits-1 downto 0);
V,C,N,Z: out bit);
end component;
--déclaration des constantes
constant NbBits : natural := 16;
constant Nbreg :natural := 8;
constant twr_reg :time := 3 ns;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 42
constant tmux :time := 1 ns;
constant tuf :time := 4 ns;
--déclaration des signaux de test
signal rst_test,V_test,C_test,N_test,Z_test: bit;
signal clk_test: bit:='1';
signal ctrlword_test: unsigned(NbBits-1 downto 0);
signal cste_test : signed(2 downto 0);
signal data_in_test,data_out_test : signed(NbBits-1 downto 0);
signal adr_out_test: unsigned (NbBits-1 downto 0);
begin
dp: datapath generic map(NbBits=>NbBits,Nbreg=>Nbreg,
twr_reg=>twr_reg,tmux=>tmux,tuf=>tuf)
port map(clk=>clk_test,rst=>rst_test,ctrlword=>ctrlword_test,cste=>cste_test,data_in=>data_in_test
,data_out=>data_out_test,adr_out=>adr_out_test,V=>V_test,C=>C_test,N=>N_test,Z=>Z_test);
--affectation des drivers des sigfnauc de test
-- à partir d'un fichier de simulation
SIMU:process
file fd :text open READ_MODE is "SimuDatapath.txt";
variable clkF,rstF,VF,CF,N,ZF:bit;
variable csteF:std_logic_vector(2 downto 0);
variable ctrlwordF,adrF,data_inF,data_outF:std_logic_vector(NbBits-1 downto 0);
variable ligne:line;
begin
while not endfile(fd) loop
readline(fd,ligne);
if ligne'length>0 and ligne(1)/='-' then
read(ligne,clkf);
read(ligne,rstF);
read(ligne,ctrlwordF);
read(ligne,data_inF);
read(ligne,csteF);
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 43
ctrlword_test<=unsigned(to_bitvector(ctrlwordF));
cste_test<=signed(to_bitvector(csteF));
clk_test<=clkF;
rst_test<=rstF;
data_in_test<=signed(to_bitvector(data_inF));
wait for 20 ns;
end if;
end loop;
end process;
end bench;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 44
6.B.3 initReg.txtVoici le fichier qui contient les initialisations des registres du datapath:
--ième registre data
0 0000000000000001
1 0000000000000101 -- 5
2 0000000000000100
3 0000000011111000 -- 248
4 0000000000010000
5 0000000000000000 -- 0
6 0000000001000000
7 0000000010000000
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 45
6.B.4 SimuDataPath.txtVoici le fichier qui contient les drivers des signaux de test du DataPath:
--clk rst ctrlword dataIn cste
-- reset
0 0 0000000000000011 1111111111111111 001
1 0 0000000000000011 1111111111111111 001
-- R0<- Datain
0 1 0000000000000011 0000000100000011 001
1 1 0000000000000011 0000000100000011 001
-- R1<- Datain
0 1 0010000000000011 0000000000000001 001
1 1 0010000000000011 0000000000000001 001
-- R7<- Datain (oxCAFE!!!!!j'aime le café!)
0 1 1110000000000011 1100101011111110 001
1 1 1110000000000011 1100101011111110 001
-- R3<-R1+R0 (resulat= 0000000000000010)
0 1 0110010000001001 1100101011111110 010
1 1 0110010000001001 1100101011111110 010
-- R3<-Datain signed(-1)
0 1 0110000000000011 1111111111111111 010
1 1 0110000000000011 1111111111111111 010
-- dataout<-R7
0 1 0000001110000000 0000000000000111 010
1 1 0000001110000000 0000000000000111 010
-- R6<-R7+(cte=1) (resulat = oxCAFF Caisse Allocation Familiale Française)
0 1 1101110001001001 0000000000000111 001
1 1 1101110001001001 0000000000000111 001
-- R5<-R0+2
0 1 1010000001001001 0000000000000111 010
1 1 1010000001001001 0000000000000111 010
-- R6<- Datain (j'aime vraiment le cafe)
0 1 1100000000000011 1100101011111110 001
1 1 1100000000000011 1100101011111110 001
-- R5<-0
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 46
0 1 1010000000101001 0000000000000111 001
1 1 1010000000101001 0000000000000111 001
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 47
6.B.5 ChronogrammesVoici le résulat de la simulation du DataPath:
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 48
Sur cette simulation on peut voir une bonne initialisation des registres.Ainsi que la bonne exécution de divers micros opérations.( add, load ...)Pour mieux lire le chronogramme, on peut se repérer avec le registre 6, qui contient oXCAFE puis oXCAFF!
6.C Unité de Contrôle:
6.C.1 Ctrl Unit.vhdVoici le source VHDL de l'unité de contrôle:
library ieee;
use ieee.numeric_bit.all;
entity Ctrl_Unit is
generic(NbBits : natural;
t_dec : time ; -- temps temps de decodage
t_r_mem : time ; --temps de lecture mem instruction
t_inc_load : time); -- temps d'incrémentation
--et chargement du PC
port(CLK,rst,V,C,N,Z: in bit;
adr: in unsigned(NbBits-1 downto 0);
Mw: out bit;
IR: out signed(2 downto 0);
ctrlword: out unsigned(NbBits-1 downto 0));
end Ctrl_Unit;
library ieee;
use ieee.numeric_bit.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
use std.textio.all;
architecture dflow of Ctrl_Unit is
----------
-- TYPE : ROM décrit une ROM comme un tableau de valeurs non signées
type ROM is array(0 to 2**NbBits-1) of unsigned(NbBits-1 downto 0);
----------
----------
-- FONCTION : initialise la ROM à l'aide du fichier programROM.txt
----------
function initROM return ROM is
file fd :text open READ_MODE is "programRom.txt";
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 49
variable mem2: ROM;
variable numli:natural:=0;
variable data:std_logic_vector(NbBits-1 downto 0);
variable ligne:line;
begin
while not endfile(fd) loop
readline(fd,ligne);
if ligne'length>0 and ligne(1)/='-' then
read(ligne,data);
mem2(numli):=unsigned(to_bitvector(data));
numli:=numli+1;
end if;
end loop;
return mem2;
end initROM;
--mémoire d'instruction
constant mem_instruc: ROM:=initRom;
-- définition de tous les signaux
signal IR_sur_16_bits : unsigned(NbBits-1 downto 0);
signal BC, JB, PL, signal_MW, RW, MD, MB, Ld : bit;
signal extension,PC: unsigned(NbBits-1 downto 0);
signal DA, AA, BA : unsigned (2 downto 0);
signal FS : unsigned (3 downto 0);
--signal decalage_sur_16_bits : std_logic_vector (15 downto 0);
begin
-- Branch Control
Ld<=Z when (BC='0') else N when (BC='1');
--extension
extension <= (5=>IR_sur_16_bits(8),4=>IR_sur_16_bits(7),3=>IR_sur_16_bits(6),2=>IR_sur_16_bits(2),
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 50
1=>IR_sur_16_bits(1),0=>IR_sur_16_bits(0),others=>IR_sur_16_bits(8));
-- Extraction d'instruction
IR_sur_16_bits<=mem_instruc(to_integer(PC)) after t_r_mem;
-- Calcul de PC rst niveau bas
PC<=(others=> '0') after t_inc_load when rst='0' else
PC+1 after t_inc_load when (PL='0' or (PL='1' and JB='0' and Ld='0')) and CLK'event and CLK='1' else
adr after t_inc_load when PL='1' and JB='1' and CLK'event and CLK='1' else
PC+extension after t_inc_load when PL='1' and JB='0' and Ld='1' and CLK'event and CLK='1';
-- Sortie Instruction register
IR<=signed(IR_sur_16_bits(2 downto 0));
-------------
-- DECODAGE
-------------
-- DA
DA<=IR_sur_16_bits(8 downto 6) after t_dec;
-- AA
AA<=IR_sur_16_bits(5 downto 3) after t_dec;
-- BA
BA<=IR_sur_16_bits(2 downto 0) after t_dec;
-- FS
FS<="0000" after t_dec when PL='1' and JB='0' else IR_sur_16_bits(5 downto 2) after t_dec;
-- MB
MB<='1' after t_dec when IR_sur_16_bits(15 downto 13)="100" else '0' after t_dec;
-- MD
MD<='1' after t_dec when IR_sur_16_bits(15 downto 13)="001" else '0' after t_dec;
-- RW
RW<='1' after t_dec when IR_sur_16_bits(14)='0' else '0' after t_dec;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 51
-- MW
MW<='1' after t_dec when IR_sur_16_bits(15 downto 13)="010" else '0' after t_dec;
-- PL
PL<='1' after t_dec when IR_sur_16_bits(15 downto 14)="11" else '0' after t_dec;
-- JB
JB<='1' after t_dec when IR_sur_16_bits(15 downto 13)="111" else '0' after t_dec;
-- BC
BC<='1' after t_dec when IR_sur_16_bits(15 downto 13)&IR_sur_16_bits(9)="1101" else '0' after t_dec;
---------
-- MOT DE CONTROLE
---------
ctrlword<=DA&AA&BA&MB&FS&MD&RW;
end dflow;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 52
6.C.2 TestCtrl_Unit.vhdVoici le source du testBench utilisé pour valider l'unité de contrôle:library ieee;use ieee.numeric_bit.all;use ieee.std_logic_1164.all;use ieee.std_logic_textio.all;use std.textio.all;
entity testUC isend entity;
architecture bench of testUC iscomponent Ctrl_Unit is-- generic(NbBits : natural := 16; generic(NbBitsAd : natural := 16; NbBitsData : natural := 16; t_dec : time := 1 ns; -- temps temps de decodage t_r_mem : time := 3 ns; --temps de lecture mem instruction t_inc_load : time := 1 ns); -- temps d'incrémentation --et chargement du PC port(CLK,rst,V,C,N,Z: in bit; adr: in unsigned(NbBitsAd-1 downto 0); Mw: out bit; IR: out signed(2 downto 0);-- decodeur_inst_in : in std_logic_vector(15 downto 0); ctrlword: out unsigned(NbBitsData-1 downto 0));end component;
-- signaux de testconstant NbBitsAd : natural := 16;constant NbBitsData : natural := 16;signal CLK_test : bit;signal rst_test : bit;signal V_test : bit;signal C_test : bit;signal N_test : bit;signal Z_test : bit;signal adr_test : unsigned(NbBitsAd-1 downto 0);signal Mw_test : bit;signal IR_test : signed(2 downto 0);signal ctrlword_test : unsigned(NbBitsData-1 downto 0);signal test_decodeur_inst_in : std_logic_vector(15 downto 0);
begin uut : Ctrl_Unit port map (CLK=>CLK_test, rst=>rst_test, V=>V_test, C=>C_test, N=>N_test, Z=>Z_test, adr=>adr_test, Mw=>Mw_test, IR=>IR_test, ctrlword=>ctrlword_test ); -- Signaux de l'environnement de test
SIM :process -- ouvre un fichier en lecture seule file fd :text open READ_MODE is "SimuUC.txt"; variable V_adr:std_logic_vector(NbBitsData-1 downto 0); variable V_CLK,V_rst,V_N,V_Z:bit; variable ligne:line;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 53
begin while not endfile(fd) loop readline(fd,ligne); if ligne'length>0 and ligne(1)/='-' then read(ligne,V_CLK); read(ligne,V_rst); read(ligne,V_N); read(ligne,V_Z); read(ligne,V_adr); CLK_test<=( not CLK_test); rst_test<=V_rst; N_test<=V_N; Z_test<=V_Z; adr_test<=unsigned(to_bitvector(V_adr)); wait for 10 ns; end if; end loop; end process;end bench;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 54
6.C.3 programRom.txtVoici le fichier qui contient le programme à charger dans la mémoire d'instruction et qui sera exécuté:
0001010000000000
0010000001011000
0100000010001000
1000000010100000
1100000010010000
1100001011001010
1110001000011100
0000000011010000
1110000100001000
1110000000111000
0000000011001000
0000000100010000
1100000010011000
0000010000000100
0000110011011000
1110000000111000
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 55
6.C.4 SimuCtrl_Unit.txtVoici le fichier qui contient les drivers des signaux de test de l'unité de contrôle:
--CLK RST N Z ADR
1 1 0 1 0000000000000010
-- 1
0 0 0 0 0000000000001000
1 0 0 0 0000000010000000
-- 2
0 1 0 0 0000000000000000
1 1 0 0 0000000000000000
-- 3
0 1 0 0 0000000000000001
1 1 0 0 0000000000000001
-- 4
0 1 0 0 0000000000000001
1 1 0 0 0000000000000001
-- 5
0 1 0 0 0000000000000010
1 1 0 0 0000000000000010
-- 6
0 1 0 0 0000000000000011
1 1 0 0 0000000000000011
-- 7
0 1 0 0 0000000000000100
1 1 0 0 0000000000000100
-- 8
0 1 0 0 0000000000000101
1 1 0 0 0000000000000101
-- 9
0 1 0 0 0000000000000110
1 1 0 0 0000000000000110
-- 10
0 1 0 0 0000000000000111
1 1 0 0 0000000000000111
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 56
-- 11
0 1 0 0 0000000000001000
1 1 0 0 0000000000001000
-- 12
0 1 0 0 0000000000000100
1 1 0 0 0000000000010000
-- 13
0 1 1 0 0000000000000100
1 1 1 0 0000000000010000
-- 14
0 1 0 0 0000000000000100
1 1 0 0 0000000000010000
-- 15
0 1 0 0 0000000000000100
1 1 0 0 0000000000010000
-- 16
0 1 0 0 0000000000000100
1 1 0 0 0000000000010000
-- 17
0 1 0 0 0000000000000100
1 1 0 0 0000000000010000
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 57
6.C.5 Chronogrammes:Voici les résultats de la simulation de l'unité de contrôle:
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 58
Sur ce chronogramme on peut voir PC évoluer de la manière attendue.
6.D Le calculateur de Harvard:
6.D.1 HarvardCalculator.vhdVoici le source VHDL du calculateur de Harvard:
library ieee;
use ieee.numeric_bit.all;
entity CalculateurHarvard is
generic (NbBits : natural );
port(CLK,rst:in bit);
end CalculateurHarvard;
architecture struct of CalculateurHarvard is
component memoire is
generic(NbBits : natural ; tco : time := 4 ns);
port(datain : in signed(NbBits-1 downto 0);
Mw,rst,clk : in bit;
adr : in unsigned(NbBits-1 downto 0);
dataout : out signed(NbBits-1 downto 0));
end component;
component datapath is
generic(NbBits: natural;
Nbreg: natural := 8;
twr_reg : time; -- temps acces w/r du banc de registre
tmux : time; --temps multiplexeur et indicateur
tuf : time); -- temps unité fonctionnele
port(clk:in bit;
rst: in bit;
ctrlword: in unsigned(NbBits-1 downto 0);
cste: in signed(2 downto 0);
data_in: in signed(NbBits-1 downto 0);
data_out: out signed(NbBits-1 downto 0);
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 59
adr_out: out unsigned(NbBits-1 downto 0);
V,C,N,Z: out bit);
end component;
component Ctrl_Unit is
generic(NbBits : natural;
t_dec : time; -- temps temps de decodage
t_r_mem : time; --temps de lecture mem instruction
t_inc_load : time); -- temps d'incrémentation
--et chargement du PC
port(CLK,rst,V,C,N,Z: in bit;
adr: in unsigned(NbBits-1 downto 0);
Mw: out bit;
IR: out signed(2 downto 0);
ctrlword: out unsigned(NbBits-1 downto 0));
end component;
--declaration des constantes
constant Nbreg: natural := 8;
constant tco : time := 4 ns;
constant twr_reg : time := 3 ns; -- temps acces w/r du banc de registre
constant tmux : time := 1 ns; --temps multiplexeur et indicateur
constant tuf : time := 4 ns; -- temps unité fonctionnele
constant t_dec : time := 1 ns; -- temps temps de decodage
constant t_r_mem : time := 3 ns; --temps de lecture mem instruction
constant t_inc_load : time := 1 ns; -- temps d'incrémentation
signal Mw_uc_to_mem : bit;
signal data_dp_to_mem : signed(NbBits-1 downto 0);
signal adr_out_dp_to_mem_and_uc: unsigned(NbBits-1 downto 0);
signal ctrlword_uc_to_dp : unsigned(NbBits-1 downto 0);
signal cste_uc_to_dp : signed(2 downto 0);
signal data_mem_to_dp: signed(NbBits-1 downto 0);
signal V_dp_to_uc, C_dp_to_uc, N_dp_to_uc, Z_dp_to_uc : bit;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 60
begin
mem : memoire generic map(NbBits=>NbBits,tco=>tco)port map(clk=>clk, rst=>rst, Mw=>Mw_uc_to_mem ,
datain=>data_dp_to_mem,adr=>adr_out_dp_to_mem_and_uc);
dp : datapath generic map(NbBits=>NbBits,Nbreg=>Nbreg,
twr_reg=>twr_reg,tmux=>tmux,tuf=>tuf)
port map (clk=>clk, rst=>rst, V=>V_dp_to_uc, C=>C_dp_to_uc,
N=>N_dp_to_uc, Z=>Z_dp_to_uc, ctrlword=>ctrlword_uc_to_dp, cste=>cste_uc_to_dp,
data_in=>data_mem_to_dp, data_out=>data_dp_to_mem,
adr_out=>adr_out_dp_to_mem_and_uc);
uc : Ctrl_Unit generic map(NbBits=>NbBits,t_dec=>t_dec,
t_r_mem=>t_r_mem,t_inc_load=>t_inc_load)
port map (CLK=>clk, rst=>rst, V=>V_dp_to_uc, C=>C_dp_to_uc,
N=>N_dp_to_uc, Z=>Z_dp_to_uc, adr=>adr_out_dp_to_mem_and_uc,
Mw=>Mw_uc_to_mem, IR=>cste_uc_to_dp, ctrlword=>ctrlword_uc_to_dp);
end struct;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 61
6.D.2 testHarvardCalculator.vhdVoici le source VHDL du TestBench du calculateur:
entity test_Calculateur is
end test_Calculateur;
architecture bench of test_Calculateur is
----------
-- COMPOSANT : Calculateur
----------
component CalculateurHarvard is
generic (NbBits : natural );
port(CLK,rst:in bit);
end component;
--declaration des constantes
constant NbBits : natural := 16;
--declaration des signaux de test
signal CLK_test,rst_test:bit;
----------
-- DESCRIPTION
----------
begin
calc: CalculateurHarvard generic map (NbBits=>NbBits)port map(CLK=>CLK_test,rst=>rst_test);
process
begin
CLK_test<=not CLK_test;
wait for 10 ns;
end process;
rst_test<='0' after 2 ns, '1' after 13 ns;
end bench;
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 62
6.D.3ChronogrammesVoici les résultats de la simulation:
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 63
Sur ce chronogramme on peut voir l'exécution du programme de test fourni dans le sujet.On peut clairement voir l'algorithme évoluer dans les différents registres du banc de registre.Notamment les registres 1,2 et 3.
LEFEVRE CHALOPIN Calculateur de Harvard Juin 2007 64