Step #4 : Le jeu d`instructions Objectif de l`étape 3 : en terme de

publicité
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Step #4 : Le jeu d'instructions
Objectif de l'étape 3 : en terme de compétences
Outils :
–
Rien de plus que vous ne sachiez déjà
Concepts de SFO :
–
–
–
–
–
Déterminer un jeu d'instructions minimal
Comprendre les formats de codage et le codage d'instructions
Mettre en œuvre l'opération de décodage d'instructions
Mettre en œuvre les instructions conditionnelles
Mettre en place un contrôleur de bus (pour le multi-cœur ou la DMA...)
Jeu d'instructions minimal ou étendu ?
La machine que vous venez de réaliser est capable d'exécuter des programmes
composés uniquement de l'instruction de saut « Branch ». Ce jeu d'instructions ne permet
pas beaucoup d'applications voire aucune. Dans la suite vous allez identifier le jeu
d'instructions minimal permettant de réaliser le programme du TD 1 d'assembleur (voir
page suivante). Vous pourrez ensuite ajouter des instructions étendues ( push/pop, BL,
etc.) qui sont réalisables à partir du jeu minimal mais qui permettront soit d'accélérer le
temps d'exécution, soit de réduire la taille du code...
Step_4_jeu_v2011a.odt
1/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
#define IN 0x8 // input with pulldown
#define OUT 0x2 // output 2MHz with push/pull
#define CR ((volatile unsigned int *) 0x40010C00) // pointeur to CRL of GPIOB (STM32f10x)
#define IDR ((volatile unsigned int *) 0x40010C08) // IDR
#define ODR ((volatile unsigned int *) 0x40010C0C) // ODR
unsigned char Boutons_Lus; // mÈmorise la valeur des boutons lu sur IDR (bit .3 et .0)
void Wait(int);
// mouline un peu pour temporiser
int main(void)
{
unsigned char Pas_Appuye ;
// boulÈen pour stopper l'attente de l'appuis
// configure |PORT.3
|PORT.2
|PORT.1
|PORT.0
// as
|In
|Out
|Out
|In
//___________|____________|_____________|_____________|___________
// for
|Player1
|Player1
|Player 2
|Player 2
//
|Button
|Led
|Led
|Button
unsigned int mask;
mask =
(IN<<(3*4)) +(OUT<<(2*4)) +(OUT<<(1*4)) +(IN<<(0*4));
*CR = mask;
while(1) // LE jeu ne fini jamais
{
Pas_Appuye = 'R'; // "Run" car les joueurs n'ont pas encore appuyÈ sur une touche
// Fait clignoter les LEDs en attendants que les players appuient
while (Pas_Appuye) // rappel : 0=> false ; tout le reste (et donc 'R') => true
{
// Teste si au moins un bouton est appuyÈ : on teste donc si IDR.0 (bouton player 1)
// ou IDR.3 (bouton player 2 ) est ‡ 1 gr‡ce au masque binaire 2_00001001 = 0x9
Boutons_Lus = *IDR & 0x9 ; // mets tous les bits ‡ 0 sauf les bits .0 et .3
// Boutons_Lus vaut 0 (!False) si aucun bouton appuyÈ et true sinon
if (Boutons_Lus) Pas_Appuye =0;
}
// Change Ètat des diodes avec un XOR bit ‡ bit du masque 2_00000110
*ODR ^= 0x6 ;
//éteindre les diodes
*ODR &= ~(6); //~ est l'inversion de chaque bits
// affiche le vainqueur ou ex-aequo
if (Boutons_Lus & (1<<0)) *ODR |= (1<<1);
if (Boutons_Lus & (1<<3)) *ODR |= (1<<2);
// attends qu'ils aient vu le resultat
Wait(1000000) ;
//etteinds les diodes
*ODR &= ~(6); //~ est l'inversion de chaque bits
}//Main
// les joueurs attendent le signal pour appuyer
Wait(3000000) ;
}// while Toujours
// Boucle de temporisation
void Wait( int N)
{
volatile int cpt ;
}
cpt=0;
for (cpt=0;cpt<N;cpt++);
Step_4_jeu_v2011a.odt
2/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Codage et format d'instruction
Nous allons voir dans la suite comment l'instruction de saut peut être réalisée en utilisant
les 3 formats de codage prévus par le chemin des données :
•
format court immédiat : 8 bits de poids forts de code opération et 8 bits de poids
faibles de donnée immédiate ;
•
format court par registre : les 8 bits de poids faibles sont utilisés pour indiquer les
registres opérandes et l'éventuelle indirection ;
•
format long 32 bits (avec un demi-mot de 16 bits supplémentaire) : les 8 bits de
pf sont inutilisés ou indiquent un registre et 16 bits sont ajoutés à la suite pour
coder la donnée immédiate.
L'instruction de saut « Branch » de mnémonique « B » a été codée dans un format long,
nous vous montrons comment la réaliser selon les deux autres formats.
Format long 32 bits :
Le format long est constitué par deux demi-mots de 16 bits avec :
– bits 15..12
COP : le code opération (identifie une famille d'instruction)
– bits 11..8
SCO : le sous-code opération (identifie l'élément de la famille)
– bits 7..0
???? : inutilisés ou registre Ra et Rb (voir le format court par registre)
L'instruction « B imm16 » que vous avez réalisée et testée est codée sur 32 bits par
« 0xBEEF » suivi de « imm16 ». Le COP « 0xB » peut être celui de la famille des
instructions de saut et le sous-code opération 0xE identifie l'instruction notée « B imm16 ».
Le 0xEF n'est pas utilisé dans cette instruction.
Une instruction de format long doit lors de son exécution corriger la valeur PC calculée
lors du fetch (PC ← PC + 2 pointe sur imm16 et non sur l'instruction suivante) de manière
à positionner le PC sur la prochaine instruction.
Format court immédiat :
Le format court immédiat est constitué de 16 bits avec :
– bits 15..12
COP : le code opération (identifie une famille d'instruction)
– bits 11..8
SCO : le sous-code opération (identifie l'élément de la famille)
– bits 7..0
imm8 : donnée immédiate entière signée en complément à 28
Pour utiliser les bits « imm8 » de ce format, le chemin des données doit transmettre la
donnée du RI immédiatement vers l'ALU (ce qui explique le terme adressage immédiat en
assembleur) comme le montre la figure 1.
Comme 8 bits ne suffisent pas à coder une adresse absolue (du moins pas toutes) on peut
effectuer un saut relatif « BR imm8 » où la donnée immédiate est ajoutée à PC pour
effectuer le saut : PC ← PC + ExS(imm8). Afin de permettre des sauts à des adresse
inférieures (pour faire des boucles en assembleur) la donnée immédiate est étendue à 16
bits en convention signée de manière à pouvoir ajouter une valeur négative.
Step_4_jeu_v2011a.odt
3/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Figure 1: L'adressage immédiat utilisé pour faire un saut relatif de type "PC ← PC +
ExS(imm8)" où ExS désigne l'extension signée
Ainsi un saut relatif « BR -6 » codé à l'adresse 0x12 permet de remonter à l'adresse 0xE
(comme PC vaut 0x14 lors de l'exécute de BR, on saute à l'adresse 0x14 – 6 = 0xE). Il est
codé par 0xBDFA sur 16 bits où B indique la famille des sauts, D précise le saut relatif BR,
et la donnée immédiate 8 bits FA code la valeur -6 en complément à 28 . La figure
montre comment le chemin des données permet d'extraire imm8 du RI, de l'étendre et de
l'ajouter à PC pour exécuter le saut.
Step_4_jeu_v2011a.odt
4/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Format court par registres :
Le format court par registre est constitué de 16 bits avec :
– bits 15..12
COP : le code opération (identifie une famille d'instruction)
– bits 11..8
SCO : le sous-code opération (identifie l'élément de la famille)
– bits 7
indA: indirection ou non sur Ra. Transfert sur Ra ou [Ra].
– Bits 6..4
Ra : numéro de registre de l'opérande A sur 3 bits ! R0 à R7...
– bits 3
indB: indirection sur RB
– Bits 2..0
Rb : registre de l'opérande B sur 3 bits.
Ce format permet de coder des instructions entre deux opérandes A et B qui peuvent être
chacune un registre Rx ou un accès indirect avec ce registre [Rx]. On peut donc coder des
instructions de type LD [Ra],[Rb], LDR Ra,[Rb] et MOV Ra,Rb. L'instruction LD [Ra],[Rb]
n'existe pas sur le cortex-M3 car son architecture load/store n'autorise qu'un accès
mémoire par instruction. Notre architecture l'autorise en consommant deux bits IndA et
IndB dans le codage. Cela limite à 3 bits le codage des registres Ra et Rb rendant les
registres R8 à R15 invisible au programmeur !
Grâce à ce format, le µ-programmeur peut faire un seul µ-programme générique pour une
instruction de type MOV Ra,Rb par exemple. Cela évite de faire 8x8=64 µprogrammes
légèrement différents pour coder les combinaisons du types MOV R1,R4 ; MOV R1,R5,
etc.
Ce format permet de coder un saut à l'adresse contenue dans un registre de type
« Branch Register » notée « BX Ra » signifiant PC ← Ra. Ainsi un saut à l'adresse R1
pourrait être codé par « BC01 » où B indique la famille des sauts, C précise le saut de
type BX, 0 est inutilisé et 1 (Rb) indique qu'il s'agit de BX R1. La figure 2 montre comment
le champ Rb permet de sélectionner le registre R1 dans la banque de registre.
Step_4_jeu_v2011a.odt
5/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Figure 2: Le champ Rb utilisé pour sélectionner un registre de la banque. Le champ
IndB est relié au séquenceur et lui permet de "µ-sauter" l'indirection du µprogramme
Step_4_jeu_v2011a.odt
6/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Le transcodage
Lorsque vous allez ajouter des instructions votre séquence de µ-adresses 0-1-2-3-[4-10]
va devoir s'adapter à l'instruction chargée : en effet comme jusqu'alors seule l'instruction
BEEF était chargée dans l'IR lors du fetch (µ@ 4) on sautait systématiquement vers la
µ@10 où se trouvait la phase execute de l'instruction « B imm16 » codée en 32 bits par
0xBEEF + imm16. Il est alors nécessaire d'effectuer un décodage d'instruction chargé
d'identifier la µ@ où sauter pour faire l'exécution de l'instruction en fonction de son COP et
SCO contenu dans le RI.
Pour cela on utilise une ROM, dite « ROM de transcodage », qui prend en entrée du bus
d'adresse la valeur de COP et SCO issu du RI et envoi en sortie la µ@ du µ-programme
correspondant vers le séquenceur. La figure 3 illustre le transcodage de l'instruction « BR
#imm8 ».
Figure 3: L'instruction "BR -6" codée par "FD#imm8" est µ-programmée à la µ@7. Lors du
fetch, la valeur 0xBD des champs COP et SCO du RI est reliée à la ROM de transcodage.
La ROM de transcodage lue à l'adresse 0xBD fournit la valeur 7 en entrée externe du
séquenceur. Le séquenceur peut ainsi sauter à la µ@7 pour exécuter la bonne instruction.
Step_4_jeu_v2011a.odt
7/8
SFO 2010-2011
Étape #4 : Le jeu d'instructions
Déroulement
Vous enrichirez le jeu d'instructions de votre machine au fur et à mesure. Ainsi vous
traduirez petit à petit le programme C en assembleur de votre machine. Pour chaque
instruction d'assembleur du programme, vous déterminerez son format de code machine,
vous ajouterez ce code machine dans la ROM, vous remplirez la ROM de transcodage et
µ-programmerez cette instruction.
Les tests s'effectueront avec le simulateur LILAS (puisque vos périphériques ont été
intégrés lors de l'étape 3). Vous effectuerez un test final avec vos périphériques sur FPGA
et pourrez ainsi tester vos réflexes !
Q1
Fabriquez votre machine et faites fonctionner le programme de jeu de réflexe
sur votre machine avec vos périphériques. Vous êtes totalement libre quand aux
instructions d'assembleur à réaliser, le format de codage etc.
Q2
Innovez selon votre humeur et le temps qu'il vous reste. Prenez en compte
l'interruption BussError, ajoutez des périphériques et des interruptions.
Step_4_jeu_v2011a.odt
8/8
Téléchargement