Documentation étoffée

publicité
Am2900 et Manuel d’utilisation du simulateur
Emu2900
(Version 0.2, 029-Octobre-2008)
Par Mohamed Boussamma
[email protected]
Département GEL-GIF
Faculté de sciences et génie
Université Laval
1
1-Introduction :
La famille des circuits intégrés Am2900 à été conçue par AMD (Advanced Micro Devices) en
1975, à cette époque AMD à mis sur le marché plusieurs modules basés sur la technique du
‘Bit Slice’, parmi les circuits intégrés, on cite les suivants : Am2901 (ALU 4 bits), Am2904
(Control de statut et des shifts), Am2910 (séquenceur CCU 12 bits). Ces circuits intégrés tout
ensemble constituent un système minimum complet. Il existe cependant beaucoup
d’extensions comme le Am2914 (contrôleur d’interruption) par exemple. Une bonne
technologie ?’ Ce que l’on sait, c’est que cela est à partir du PDP-10, basé sur les circuits
intégrés AM2900, que Bill Gates et Paul Allen ont lancé la révolution de l’informatique que
nous connaissons !
Pour la culture générale :
http://www.dailymotion.com/videos/relevance/search/cinglés+de%20l'informatique/1
http://youtube.com/results?search_query=pirates+of+silicon+valley
La famille Am2900 est un bon moyen d’apprentissage pour l’introduction au domaine des
microprocesseurs microprogrammés, et son apprentissage ne demandera pas beaucoup de
temps. Afin de faciliter votre apprentissage, le simulateur Emu2900 à été développé pour le
cours GIF-17456, ce simulateur reprend le fonctionnement exact d’une version légèrement
modifiée de l’ALU 2901 (8 bits au lieu de 4), du CCU Am2910, de l’Am2904 complémentée
par une mémoire programme, un Registre d’instruction (IR) et une mémoire Mapping
PROM.
Le simulateur fonctionne sous Windows XP, mais le test sur Vista n’a pas encore été
effectué, le code du simulateur est sous licence GPL (http://www.gnu.org/licenses/gpl.html)
et le code source vous sera fournis sur demande, il suffit juste de me contacter.
2
2-Architecture du système :
L’architecture de la version modifiée du système est présentée dans la figure ci-dessous
Figure 1- Architecture génerale du système
3
Lorsque l’on fait exécuter un programme, chacun des modules du simulateur entrent en
fonction. Au départ, on doit effectuer un reset général du système, qui permet
d’initialiser tous les signaux à zéro, et d’aller à la routine FETCHINSTR dans le
microprogramme.
C’est à chaque montée d’horloge, que le pipeline envoie de nouveaux signaux de contrôle
aux différents modules pour l’instruction suivante. Ces signaux se retrouvent à l’entrée
du pipeline, et sont remplacés par de nouvelles valeurs suite à la montée d’horloge. Ces
valeurs proviennent en réalité de la micromémoire, et représentent les différentes valeurs
de la série de bits qui forment une microinstruction. À chaque adresse de la
micromémoire, on retrouve une microinstruction. Les microinstructions non
programmées contiennent donc une série de bits qui ont tous la valeur zéro. Programmer
une microinstuction correspond donc à déterminer la valeur de ces différents bits.
Comme il l’a été mentionné précédemment, ce sont la valeur de ces différents bits qui
contrôlent les différents modules du simulateur. Chaque microinstruction contient donc
71 signaux de contrôles. Ces signaux de contrôles sont divisés en instructions,
dépendamment du module qu’ils contrôlent. Chaque instruction est divisée en champs,
dépendamment de quelle section du module elle contrôle. Cette division améliore la
programmation de ces signaux.
Le pipeline permet donc d’afficher les signaux de contrôle pendant un cycle d’horloge.
Cela assure donc la stabilité du système. C’est donc pendant ce cycle d’horloge que le
microséquenseur AM2910 détermine l’adresse de la prochaine microinstruction et que le
AM2901 (l’Alu), effectue les différentes opérations déterminées par les signaux de
contrôle sortant du pipeline. Toutes les opérations du microséquenseur AM2910, du
AM2901 et de la macromémoire doivent dont s’effectuer en un cycle d’horloge. Car à la
prochaine montée d’horloge, ce sont les signaux de la prochaine microinstruction qui
seront affichés à la sortie du pipeline. Normalement, l’accès à la macromémoire se fait
en plus d’un cycle d’horloge, mais pour faciliter la simulation, cet accès se fera en un
coup d’horloge. C’est pourquoi certains modules réagiront à la descente d’horloge.
Une instruction machine est composée de plusieurs microinstructions, et ces
instructions se retrouvent dans la macromémoire, avec les données nécessaires à
l’exécution du programme. Un programme contient plusieurs instructions machines.
Une table de correspondance permet de déterminer la première microinstruction d’une
instruction machine.
Dans ce qui suit on va expliquer le fonctionnement de chaque partie du système.
2-1- La macromémoire :
La macromemoire est la mémoire principale que le système utilise pour exécuter les
instructions en code machine, cette mémoire peut stocker jusqu'à 32 données de 8 bits
(32x8). La macromémoire est connectée au MAR, au MBR ainsi que le D-BUS. Les opérations
de lecture de la mémoire se fait sans aucun délai, mais l’écriture se fait à la descente de
l’horloge. Ceci est expliqué plus tard.
La lecture/écriture de mémoire est contrôlé par deux bits de contrôle RDWR (00 : aucune
opération, 01 : écrire la mémoire, 10 : lire la mémoire)
4
2-2- Le MAR:
Le MAR (Memory Address Register) est directement connecté aux lignes de sélection
d’adresse de la macromémoire, le MAR est un Latch qui mémorise l’adresse à la montée de
l’horloge, cela veut dire que le MAR sera rempli par la nouvelle donnée avant que la
donnée dans le MBR sera écrite dans l’adresse indiquée par le MAR.
Vu que la macromémoire est composée de 32 cases, seulement 5 bits du MAR sont utilisés
pour adresser cette dernière, donc les 3 bits de poids le plus haut sont sans importance.
X
X
X
A4
A3
A2
A1
A0
Figure-2- Le registre MAR
L’accès au MAR est effectué à partir de du Bus principal (D_BUS) quand le bit d’activation
(load) est à 1 sinon aucune valeur n’est inscrite, ce bit peut être codé dans le champ OFFOF
de la micromémoire (b1).
2-2- Le MBR:
Le MBR (Memory Buffer Register) est un registre qui sert d’interface avec la mémoire, le
MBR contient une entrées, une sortie et un bus bidirectionnel (entre le MBR et la
macromémoire), l’entrée provient du Bus principal (dans le cas ou on veut écrire dans la
macromémoire), le bus bidirectionnel est connecté à la macromémoire et la sortie est
connectée vers le bus principal et isolée par un buffer tri-state.
Pour écrire dans le MBR à partir du bus principal, on met le bit load à 1 (b0 du champ
OFFOF), si on veut écrire dans le MBR à partir de la macromémoire on met les bits RDWR à
10, et si on veut mettre la donnée du MBR dans le bus principal on met le champ ONTO à
001, Il est aussi possible de mettre directement la donnée de la macromémoire dans le bus
en jouant sur OFFOF et ONTO.
2-2- Le Registre d’instructions IR:
Le registre IR est un latch de 16 bits divisé en IR_MSB et IR_LSB, qui mémorise l’instruction à
exécuter qui provient de la macromémoire.
IR_MSB : l’entrée est connectée avec le D_BUS et contrôlé par b2 du champ OFFOF, la sortie
est connectée vers le MappingProm. Ce registre sert principalement à mémoriser l’opcode
de l’instruction qui sera convertie en adresse de début dans la micromémoire par
l’intermédiaire du MappingProm.
5
IR_LSB : l’entrée est connectée avec le D_BUS et contrôlé par b3 du champ OFFOF, la sortie
est connectée à la DUAL PORT RAM pour selectionner les adresses des registres à utiliser..
Généralement les opérations d’écriture du registre IR est effectué par la routine
FETCHINSTR qui est une routine de base pour le fonctionnement du microprocesseur
(explications plus tard).
2-2- Microséquenceur AM2900:
Figure 2- CCU AM2910
Le microséquenceur joue le rôle du contrôleur principal du microcontrôleur, c’est ce dernier
qui détermine les macro-instructions à exécuter et gère des différentes fonctionnalités pour
permettre d’exécuter des routines complexes (les boucles, les conditions, les
6
branchements…), la figure ci-haut montre les différentes parties du CCU qu’on expliquera
plus loin.
2-2-1- le CCU Logic:
Le CCU Logic est la partie intelligente du CCU, c’est cette dernière qui contrôle les différents
composants de l’AM2910 tel que le compteur, le pointeur de Pile…, deux choses à retenir :
le CCU contrôle un MUX 4/1, une ligne provient du pipeline qui fournir un jeu de 14
instructions pour le CCU (NAS [3 :0])
2-2-2- le MUX:
Le MUX d’adresse sélectionne la prochaine microinstruction dont les signaux de contrôle
s’afficheront à la sortie du pipeline à la montée d’horloge. Il peut sélectionner 4 sources
d’adresses, et est donc contrôlé par deux bits de sélections qui proviennent du module
CCU LOGIC.
Il est à remarquer qu’en réalité le MUX affiche à la sortie 5 sources possibles, ceci est
possible grâce à un jeu de contrôle assuré par le CCU LOGIC (MappingProm/BranchAdress).
2-2-2- L’Incrementer:
L’incrémenter est un composant logique asynchrone, il a pour rôle d’incrémenter l’adresse
d’instruction courante fournie par la sortie du MUX et la garder dans microPC afin de garder
l’avancement du microprogramme.
2-2-2- UPC register:
L’UPC register est un latch synchrone qui mémorise la micro-instruction courante
incrémenté de 1, donc au prochain coup d’horloge et si on sélectionne UPC comme entrée
du MUX, on a un saut de +1 dans l’adresse micromémoire.
2-2-3- STACK ET TOS POINTER:
Lorsque l’on veut effectuer des boucles ou faire un saut conditionnel à une sous-routine,
il faut donc sauvegarder la valeur de l’adresse de départ ou de l’adresse de retour sur la
pile. Plusieurs instructions du CCU LOGIC permettent d’empiler et de dépiler une
adresse sur la pile. LE TOS POINTER incrémente et décrémente sa valeur de sortie à la
descente de clock. Cela permet donc d’incrémenter l’adresse pointant sur la pile avant la
prochaine montée d’horloge. La STACK, par contre, mémorise à la montée d’horloge,
donc seulement à la prochaine montée d ‘horloge suivant l’instruction d’empilage. C’est ce
qui permet d’incrémenter le pointeur de pile d’abord, et d’empiler la valeur de la prochaine
adresse au prochain coup d’horloge.
Quand on décrémente une valeur, le TOS pointeur décrémente seulement à la descente
d’horloge de l’instruction. Puisque la valeur que l’on dépile doit être lue dans le MUX
d’adresse jusqu’à la prochaine montée d’horloge, la sortie de la pile ne sera donc
7
rafraîchie qu’à la prochaine montée d’horloge. C’est ce qui permet de dépiler la valeur,
puis de décrémenter le pointeur de pile tout en laissant cette valeur dépilée à l’entrée du
MUX jusqu’à la prochaine montée d’horloge.
Ces deux modules sont contrôlés par les signaux de sorties du module CCU LOGIC.
2-2-4- Counter et Zero Test :
Le Counter est un registre qui peut être utile dans les boucles, on peut le charger par une
constante provenant du pipeline et commencer à le décrémenter chaque coup d’adresse, la
sortie du Counter est monitoré par le drapeau ZeroTest, ce drapeau s’active quand la sortie
du compteur est nulle, ZeroTest nous aide alors de déterminer si on a atteint le nombre de
répétitions désiré. Le mode d’emploi sera expliqué plus tard.
2-2-5- Le REGISTER :
Le REGISTER aide principalement à mémoriser les adresses de branchement pour les
opérations conditionnelles, ce registre enregistre le Branch_Adress dans le cas des
instructions LDCT, JRP et JSRP (explications plus tard).
2-3- l’ALU AM2901:
Figure 3- ALU AM2901
L’ALU est la deuxième partie indispensable pour le fonctionnement du microcontrôleur,
c’est ce module qui s’occupe des opérations arithmétiques et logiques, il communique avec
8
le reste du système par l’intermédiaire du bus principal et il est contrôlé par des bits
provenant de la sortie du pipeline de la micro-mémoire, donc pour chaque microinstruction, une partie des bits de la micromémoire est consacrée au contrôle de l’ALU.
2-3-1 ALU LOGIC:
ALU Logic est un module déjà programmé, il est contrôlé par 3 bits de contrôle provenant de
la micromémoire, ces 3 bits fournissent un jeu de 8 instructions pour Controller le flux des
données dans l’ALU (expliqué plus tard).
2-3-1 DUAL PORT RAM:
Les 16 registres internes de l’ALU se retrouvent dans ce module et permettent de garder
en mémoire des données nécessaires aux différentes opérations de l’ALU. Les contenus
de deux registres peuvent être sélectionnés, et sont accessibles en lecture et se retrouvent
à la sortie de cette mémoire. Les deux registres nécessaires à chaque microinstruction
peuvent être fixes ou dynamiques. S’ils sont fixes, les deux numéros de registres sont
déterminés dans les microinstructions par des bits de contrôles. S’ils sont dynamiques,
pour certaines microinstructions d’une instruction, il suffit de le spécifier à l’aide des bits
de contrôle réservés à cet effet. Dans le cas ou l’adresse est dynamique, elle sera donc
spécifiée dans la section de l’opérande de l’instruction, c’est-à-dire dans les LSB du registre
IR. Les opérations de calcul de l’ALU s’exécutent à la montée d’horloge, et le résultat peut
être rechargé en mémoire, dans le contenu du registre spécifié par la deuxième adresse à la
descente d’horloge. Cependant, le contenu des deux registres apparaissant à la sortie n’est
rafraîchi qu’aux montées d’horloges, afin de ne pas déstabiliser les modules de l’alu qui
réagissent de manière asynchrone.
2-3-2 ALU DATA SOURCE SELECTOR:
Ce module est semblable à un MUX, qui a pour rôle de choisir les deux données à être
traités par le 8-Function-ALU, les entrés possibles proviennent soit du DUAL_PORT_RAM soit
du Q-Register, du D_BUS ou nulles.
2-3-3 8-FUNCTION-ALU:
C’est le module qui réalise les opérations logiques et arithmétiques, ses entrées sont les
données choisies par l’ALU DATA SOURCE SELECTOR et sa sortie peut aller dans le BUS de
sortie, rechargée dans la DUAL PORT RAM ou le Q-REGISTER. Elle est contrôlée par 3 bits de
contrôle provenant de la micromémoire, donc peut exécuter 8 opérations différentes. Des
drapeaux de statut sont aussi envoyés vers l’AM2904 à chaque opération, ces flags sont
SIGN, OVR, COUT et ZERO. Une entrée supplémentaire est le CARRY_IN qui permet d’ajouter
un 1 à l’opération courante.
2-3-4 Y OUTPUT DATA SELECTOR:
9
Ce module joue le rôle d’un accumulateur, et charge en mémoire la sortie du module 8
FUNCTION ALU, ou le contenu de l’adresse du premier registre sélectionné dans le module
DUAL PORT RAM. La valeur est sauvegardée à la descente d‘horloge dans le registre, afin
que le résultat d’une opération arithmétique soit disponible. La sortie du registre est
connectée au bus principal, et il suffit d’activer son buffer 3 états afin que sa valeur se
retrouve sur le bus. Cette valeur peut donc être le résultat obtenu suite à l’opération
arithmétique exécutée sur des données sélectionnées, ou tout simplement le contenu d’un
registre spécifique sur lequel on ne veut pas effectuer d’opérations arithmétique. Le bit qui
contrôle la sélection de cette valeur se retrouve à la sortie du module ALU LOGIC, qui est luimême contrôlé par 9 bits provenant des microinstructions.
2-3-5 RAMSHIFT:
Ce module est un registre à décalage asynchrone. C’est la valeur de sortie du module 8
FUNCTION ALU qui est connecté à l’entrée. Le décalage peut s’effectuer vers la droite
ou vers la gauche, et ne décale qu’un bit. Le résultat de l’opération arithmétique peut
donc être divisé ou multiplié par deux, avant d’être rechargé dans le contenu du registre
spécifié par la deuxième adresse, dans la DUAL PORT RAM. Des bits de contrôle
provenant du module ALU LOGIC déterminent s’il y a ou non un décalage, et
sélectionnent le sens de ce décalage. Trois autres bits de contrôle provenant directement
des microinstructions sélectionnent ce qui entre dans le registre à décalage.
2-3-6 Q-REGISTER:
Ce module constitue un autre registre de l’ALU, et permet de sauvegarder des données
décalées provenant de lui-même, ou des données provenant du résultat des opérations
arithmétiques. La sortie de ce registre est disponible à l’entrée du module ALU DATA
SOURCE SELECTOR, et peut donc être sélectionné pour effectuer des opérations
arithmétiques. Ce registre sauvegarde les données sur la descente d’horloge, et la valeur
de sa sortie n’est rafraîchie qu’aux montée d’horloges, afin d’assurer la stabilité du
système. Les bits de contrôle sélectionnant et chargeant la valeur d’entrée sont déterminés
par les bits de sortie du module ALU LOGIC.
2-3-7 Q-SHIFT:
Ce module fonctionne exactement comme le module RAMSHIFT, et permet de décaler
les données qui entrent dans le registre Q.
2-4- L’Unité de contrôle AM2904:
2-4-1 MICRO-MACRO Flags:
Ce module permet de sauvegarder la valeur des flags de l’ALU à la descente d’horloge,
après l’exécution d’une l’opération arithmétique. Les valeurs de ces flags seront utilisées
pour tester des conditions nécessaires de branchements utiles au module CCU LOGIC.
2-4-2 Conditionnal MUX:
10
Ce module sélectionne le flag devenant la condition de branchement pour les instructions
du module CCU LOGIC. Il est contrôlé par trois bit provenant directement des
microinstructions.
2-4-3 POLARITY:
Ce module détermine la polarité du flag choisi. Cela permet donc d’effectuer l’opération
NOT.
3-Le SIMULATEUR :
En pratique, l’utilisation d’un tel système se divise en deux parties, la programmation et
l’exécution, le simulateur ne fera rien si on ne lui fournit pas les fichiers programmes (qui
sont le microprogramme, le microprogramme et le MappingProm). Ainsi, avant de lancer le
simulateur on doit écrire ceux-ci. Dans les cas du MappingPROM et de la macromémoire on
écrit des fichiers textes, mais afin de faciliter l’écriture du fichier microprogramme, on
utilisera un petit compilateur qui convertira le fichier texte en un format compréhensible
par le simulateur (type texte, mais formaté d’une façon différente).
Un dossier zippé est en téléchargement sur le site web du cours, ce dossier contient les deux
exécutables : Emu2900.exe, microcompile.exe, ainsi que quelques exemples de programmes
et un petit tutoriel.
3-1 Écriture d’un programme:
Voici l’explication des champs qui servira de base de développement du programme :
AM2910: NAS et BA
Nom
Description
Instruction
NAS
CONT
La prochaine microinstruction à être exécutée sera la suivante dans la
micromémoire.
1
JMAP
Saut inconditionnel à la prochaine instruction indiquée à la sortie
du Mapping Prom.
2
CJP
*LDCT
JRP
CJS
Saut conditionnel à l’adresse spécifiée sur le pipeline (Champ
B_A). Si CC (not) est à 0, un saut vers la valeur de B_A sinon la
prochaine microinstruction sera executée.
Charge le REGISTER et le COUNTER, avec la valeur spécifiée sur le
pipeline (B_A). Cette valeur peut être utilisée pour charger une
adresse, ou une valeur à décrémenter ultérieurement.
Saut conditionnel à l’adresse du registre compteur (CC(not)=1) ou du
pipeline (CC(not)=0). Le MUX sélectionne donc B_A ou la sortie de
REGISTER
Saut conditionnel à une sous routine si CC(not) = 0. La valeur de
l’adresse de retour est empilée sur la pile, et le MUX sélectionne
B_A. Si CC (not) =1, la prochaine microinstruction sera executée.
11
3
5
6
7
JSRP
CRTN
RPCT
PUSH
RFCT
LOOP
CJPP
TWB
Saut conditionnel à une sous routine. Si CC (not)=0 le saut s’effectue
à partir de (B_A) provenant de la microinstruction. Si la
condition CC (not)=1, le saut s’effectue à partir de REGISTER
Retour conditionnel à une sous-routine. Si la condition CC (not) =0, le
MUX sélectionne la sortie de la pile, et la valeur de la
pile est dépilée. Si CC(not)=1, la prochaine microinstruction sera
exécutée
Répète une boucle dont le départ est sur le pipeline (B_A), si le
compteur n’est pas égal à zéro, et décrémente le
compteur. Si le compteur est égal à zéro, la prochaine microinstruction
sera exécutée.
La prochaine adresse va sur la pile et charge le compteur
conditionnellement. Si CC (not) =0, le compteur est chargé avec la
valeur de B_A. Si CC=1, aucune valeur n’est chargée sur la pile.
Dans les deux cas, la prochaine microinstruction sera exécutée.
Répète une boucle dont le départ est sur la pile, si le compteur n’est
pas égal à zéro et décrémente le compteur, la sortie de la pile est la
prochaine adresse. Si le compteur est égal à zéro, la prochaine
microinstruction sera exécutée et la valeur sur la pile est dépilée.
Teste la fin d’une boucle. Similaire à RFTC, à l’exception que la
condition à tester n’est pas le zéro du compteur, mais CC (not). Si le
test est réussi, on continue. Sinon, on répète la boucle dont le départ
est sur la pile.
Saut conditionnel via le pipeline, et récupère la pile (POP). Si CC
(not) = 0, Le MUX sélectionne donc B_A.
Si CC=1, microinstruction suivante dans la micromémoire qui est la
prochaine instruction. Cette instruction peut être utilisée pour sortir
d’une boucle conditionnellement, ou pour sortir d’une sous-routine en
annulant l’adresse de retour.
Saut à trois voies. Si la CC (not) =0 et le compteur =0, on continue et
on dépile. Si CC (not)=0 et le compteur n’égal pas 0, on continue, on
récupère la pile et on décrémente le compteur. Si CC (not)=1 et que le
compteur=0, on va à l’adresse sur le pipeline et on dépile. Si CC
(not)=1 et que le compteur n’égal pas zéro, on va à l’adresse sur la
pile,et on décrémente le compteur.
8
9
10
11
12
13
14
15
Tableau -1 Instructions NAS
AM2901 : AA, AB, USIERA, USIERB, NOP, CARRY, ALUSRC, A LUFN, ALUDEST
-
AA [3 :0], USIERA :
Ce champ permet de spécifier quels registres du module DUAL PORT RAM affichera
son contenu à la sortie A_OUT[7 :0].
Valeur
Description
USIERA=0
La sortie A_OUT est le contenu de l’adresse
spécifiée par le signal AA
USIERA=1
La sortie A_OUT est le contenu de l’adresse
spécifiée par la première opérande du registre IR.
(IR_LSB_OUT[7:4])
Tableau -2 Champ adresse AA
12
-
BB [3 :0], USIERB :
Ce champ permet de spécifier quels registres du module DUAL PORT RAM affichera
son contenu à la sortie B_OUT[7 :0].
Valeur
Description
USIERB=0
La sortie B_OUT est le contenu de l’adresse
spécifiée par le signal BB
USIERB=1
La sortie B_OUT est le contenu de l’adresse
spécifiée par la première opérande du registre IR.
(IR_LSB_OUT[3:0])
Tableau -3 Champ adresse BB
-
ALUSRC, NOP :
Ce champs permet de spécifier quelles valeurs s’afficheront au sorties R[7 :0] et
S[7 :0] du module ALU DATA SOURCE SELECTOR.
Si NOP=1, aucune opération ne se produit, seulement des zéro apparaissent aux
sorties R[7 :0] et S[7 :0] du module ALU DATA SOURCE SELECTOR.
Pour ALUSRC :
ALUSRC
R
S
0
D
ZERO
1
A
B
2
ZERO
Q
3
ZERO
B
4
ZERO
A
5
D
A
6
D
Q
7
A
Q
Tableau -4 Champ ALUSRC
-
ALUFN :
Valeur
Opération
0
R+S
1
S-R
13
2
R-S
3
R || S
4
R && S
5
(Not) R && S
6
R OU exclusif S
7
NON R OU exclusif S
Tableau -5 Champ ALUFN
-
ALUDEST I[8 :6] :
Tableau -6 Champ ALUDEST
-
Carry :
Ce champ permet d’incorporer un Carry dans certaines opérations arithmétique du
module 8 FUNCTION ALU. Pour mettre le carry à un, il suffit de mettre le signal
CARRY à l’état 1.
Tableau -7 Champ CARRY
-
ONTO :
14
Valeur
Opération
0
ALU_OE
1
MBR_OE
2
MICRO_OE
3
MACRO_OE
4
CONST_OE
5
IR_MSB_OE
6
IR_LSB_OE
7
pas d'opération
Tableau -8 Champ ONTO
-
OFFOF: Vu qu'on peut écrire sur plusieurs parties du processeur, le codage de est sur
4 bits [IR_LSB_LD, IR_MSB_LD, MAR_LD, MBR_LD]. Par exemple : si OFFOF est 7 ou
0111 cela veux dire qu'on écrit dans IR_MSB, MAR, MBR
AM2904 : BCS, POL, CCEN, FLAGSRC
-
BCS: Ce champ détermine le flag utilisé pour commander le branchement dans le
module CCU LOGIC. Les valeurs que peut prendre signal CC_OUT sont indiquées
dans le tableau
suivant. Il est à noter que la condition CC_OUT est la condition de branchement, et
prend la valeur inversée du flag de sortie.
Tableau -9 Champ BCS
-
POL: Ce champ détermine la polarité du signal CC_OUT. On peut réaliser des opérations
NOP. Pour inverser CC_OUT, le signal POL doit être mis à un.
15
-
CCEN : Ce champ force la condition de branchement dans le module CCU LOGIC, si
le signal CCEN est mis à l’état 1. Si CCEN est à l’état 0, le branchement est
commandé par le signal CC_OUT.
-
FLAGSRC:
Valeur
Opération
0
ALU_TO_MICRO
1
ALU_TO_MACRO
2
MICRO_TO_MACRO
3
MACRO_TO_MICRO
4
MACRO_SWITCH_MICRO
5
Aucune opération
Tableau -10 Champ FLAGSRC
ALUCONST : CONST
MEMORY : RDWR (0 : aucune opération, 1: écriture, 2: lecture)
RAMSHIFTMUX :
- RIN : Ce champ détermine ce qui entre (in0) ou (in7) dans les entrées RAM0 ou
RAM7 du module RAM_SHIFT, dépendamment de la fonction qui a été choisi dans
le champ Alu_dest de l’instruction AMD2901.
Tableau -11 Champ RIN
QSHIFTMUX :
- QIN: Ce champ détermine ce qui entre (in0) ou (in7) dans les entrées Q0 ou Q7 du .
moduleQ_SHIFT, dépendamment de la fonction qui a été choisi dans le champ
Alu_dest de l’instruction AMD2901
16
Tableau -12 Champ QIN
3-2 Syntaxe : La notation doit être en hexadécimale et tout le code doit être en majuscule,
les espaces sont permis et chaque point virgule correspond à une fin d’instruction, un mot
qui finit par deux point est considéré comme un label et ignoré dans la compilation, un
double tiret (--) met toute la ligne en commentaires.
Exemple de code (1er style) :
-- Ceci est un commentaire
#ORG 00
AM2910: NAS=0; BA=0;
AM2901: AA=2; AB=1; ……
…
--Fin du programme
Exemple de code (2eme style) :
-- Ceci est un commentaire
#ORG 00
NAS=0; BA=0;
AA=2; AB=1; ……
3-3 Compilation :
Afin de compiler votre code, vous devez lancer le programme microcompile.exe et
charger le fichier à compiler, la boîte de dialogue est montrée si dessous :
17
Figure-1 – compilateur du microprogramme
Après avoir chargé le programme, choisissez le nom de sauvegarde et cliquer sur générer, le
code machine sera généré et sauvegardé dans le même répertoire que l’exécutable
Pour les fichiers mappingPROM et macro mémoire, vous écrivez directement le code
compréhensible par le simulateur :
MappingPROM : le MappingProm est constitué de 32 cases mémoires (0 -31), la forme est
la suivante :
--Fichier mappingPROM.txt
ONE: 0 #1A;
TWO: 1 #15;
THREE: 0A #FF;
…
-- ONE, TWO et THREE sont des labels et seront ignorés dans le programme
--Fin du code
Si le fichier ne contient aucune instruction, toutes les cases mémoire seront remplies de
zéros.
18
Macromémoire: Elle se programme de la même façon que le mappingPROM.
--Fichier macromemoire.txt
ONE: 0 #1A;
TWO: 1 #15;
THREE: 1B #00;
-- ONE, TWO et THREE sont des labels et seront ignorés dans le programme
--Fin du code
3-4 Lancement du simulateur :
La fenêtre principale du simulateur est la suivante :
19
Contenu des
registres
(DualPort RAM)
Indicateurs
des Flags
Indicateurs
d’opérations
Contenu
de la pile
Contenu du
MappingPROM
Zone des
registres
Contenu de la
macromémoire
Zone de
chargement
chargement
Zone
d’exécution
20
Contenu de la
micromémoire
Zone de chargement : Permet le chargement des différents programmes.
Zone d’exécution : le bouton Run permet l’exécution pas à pas, Raz fait un reset total au système.
Contenu de la micromémoire : chaque adresse et son contenu détaillé en format hexadécimal et
binaire, pour voir les détails des champs appuyez sur « détails »
Contenu des registres (DualPort RAM) : C’est les registres de l’ALU, à remarquer que l’adresse 00h
correspond au PC
Indicateurs des Flags : Out contient les flags de l’opération qui vient d’être exécutée, micro et macro
contiennent l’état des flags déjà enregistrés.
Indicateurs d’opérations(ALU) : Contient les données R et S pour la prochaine opération, contient
aussi l’indicateur de la prochaine opération à exécuter
Indicateurs d’opérations(CCU) : Contient la dernière opération exécutée dans le CCU, la condition
de branchement avant l’exécution de la dernière opération, l’adresse de la prochaine instruction qui
sera exécutée et l’état des registres du CCU.

Operation : indique la prochaine microinstruction à exécuter.

Condition : condition CC rentrante dans le CCU

Next Adress : l’adresse de saut suivante dans la micromemoire.

UPC : l’adresse micromemoire courante incrémenté de 1
4-Mot de la fin :
Ce document ne représente qu’un guide d’utilisation du simulateur, aucun exemple n’y est inclus,
des exemples et des explications pratiques sont en téléchargement sur le site web du cours.
Le simulateur est sous licence GPL, tout le code source ainsi que le projet complet est fourni sur
demande en me contactant sur mon adresse email : [email protected]
Section programmeurs C++ (Optionnel) :
Le simulateur à été programmé sous Visual C++ 8, l’interface graphique est développée en MFC avec
l’aide énorme de www.codeproject.com avec tout les exemples et les libraires gratuites que j’ai
trouvé (ex : librairie pour l’affichage des boutons).
Beaucoup d’améliorations pourraient être apportés au simulateur :
21
-
Améliorer les compilateurs pour la gestion d’erreurs
-
Restructurer le code C++ surtout pour l’AM2901 (mauvais style)
-
On peut changer la taille de la macromémoire, On peut concevoir un gestionnaire
d’interruptions et mapper les contenus dans les adresses ajoutés, par exemple une idée
qui m’est parvenue est un afficheur simple qui affiche un nombre hexadécimal, on
pourra alors programmer des Instruction de la sorte : SCREEN Rx, IMM (inspirez vous des
parties du cours (8051 et PIC)
-
Ajouter l’effet du timing (CLOCK) avec variation de délai.
-
Enfin vos talons de conception Hardware et programmation C++ pour rendre ce projet
plus complet et plus ambitieux.
Tutoriels
Dans cette section on présentera une démonstration d’utilisation du Simulateur et quelques
exemples pour vous familiariser avec.
I- Explications à bien lire:
Avant tout, des explications importantes doivent être bien assimilées pour bien programmer la
micromemoire, quelque champs on été modifiés afin de simplifier la lecture et la programmation de
la micromemoire :


Le champ RDWR:
0
: aucune opération
1
: Écrire la mémoire
2
: Lire la mémoire
Le champ ONTO :
0
: ALU_OE
1
: MBR_OE
2
: MICRO_OE
3
: MACRO_OE
4
: CONST_OE
5
: IR_MSB_OE
6
: IR_LSB_OE
22
7

: pas d'opération
Le champ OFFOF :
Vu qu'on peut écrire sur plusieurs parties du processeur, le codage d’OFFOF est sur 4 bits :
[IR_LSB_LD, IR_MSB_LD, MAR_LD, MBR_LD]
Ex: si OFFOF est 7 ou 0111 cela veux dire qu'on écrit dans IR_MSB, MAR, MBR

Le champ FLAGSRC :
0
: ALU_TO_MICRO
1
: ALU_TO_MACRO
2
: MICRO_TO_MACRO
3
: MACRO_TO_MICRO
4
: MACRO_SWITCH_MICRO
5
: Aucune opération
Le reste des champs est similaire aux notes de cours.
II- Comment coder :
Pour bien coder vos programmes, des règles doivent être suivies, il est à remarquer que les
compilateurs de codes sont encore en 1ere version, ils sont sensibles à la mointre erreur, aucun
générateur d’erreur n’est encore intégré (Laissé en Exercice pour ceux qui veulent coder du C++ !)
En cas d’erreur tout ce que vous aller remarquer, est un fonctionnement imprévisible du Simulateur.
Remarques :
1- Les espaces sont permis, la notation est en hexadécimale pour tout vos codes.
2- Par défaut le simulateur insère des zéros dans tout les champs de mémoire, alors si vous
voulez coder une adresse il suffit d’ajouter juste son code, le reste sera gardé à zéro.
3- Les commentaires sont permis (ex : -- Je veux mettre un commentaire) mais la technique
est différente du C++, le commentaire ne peux jamais être après une instruction.
4- Afin de clarifier le code des « LABELS » peuvent être insérés au début d’une ligne, mais ne
comptez pas trop sur un appel de CALL à l’assembleur pour aller à ce LABEL (sujet à
développer pour les coders C++ aussi !)
23
5- Pour les codes mappingProm et Macromemoire, la technique est la suivante :
ADRESSE#CONTENU
6- Voir les codes dans la section CODES, des modèles sont fournis.
III- Préparer le terrain :
En général, pour un processeur, l’exécution d’une instruction se fait en 2 étapes nécessaires :
Chercher l’instruction (FETCH), et exécuter (EXECUTE), chaque fois qu’une instruction est exécutée,
le machine d’états du processeur saute vers l’état FETCH qui sera exécuté à l’infini si on ne
débranche pas la prise !
Pour notre cas, dans l’Am2900, avant de se lancer dans la conception de micro-instructions, on doit
préparer le processeur à deux choses : 1- Le SOFTWRE RESET, et le 2- FETCH INSTRUCTION.
Les fichiers correspondants à ces tutoriels sont dans la section CODES
1- SOFTWARE RESET :
Le rôle du reset software est de réaliser une mise à zéro de tout les registres système et surtout
le PC, même dans les nouveaux processeurs cette procédure est primordiale surtout pour
résoudre les blocages système (l’écran bleu de Windows fait ça!).
Pour notre cas on a réalisé un reset simple à l’adresse 0h qui fait une mise à zero du PC et
continue sur FETCH INSTRUCTION à l’adresse 01h (voir le code dans Getting Started).
2- FETSH INSTRUCTION :
Le principe de cette instruction qui est codé sur 4 adresses micromemoire est simple, le
standard Am2900 veut qu’une instruction soit codée sur 2 bytes au minimum, le FETCH cherche
ces deux bytes dans la macromemoire, les mets successivement dans le registre d’instruction
IR_MSB et IR_LSB et à la fin, fait un saut (NAS = 2) à la correspondance spécifiée par le
mappingPROM à l’adresse IR_MSB, donc il faut faire attention à mettre l’adresse du saut au tout
premier byte d’une macroinstruction.
IV- Pratiquer vous !
24
25
Téléchargement