Université Grenoble Alpes L3 Informatique Année 2016-2017 Architectures logicielles et matérielles TD 10 (TP1) Nous commençons ici la prise en mains de l'outil qui nous permettra de simuler un processeur avec un jeu d'instructions du style de celui étudié au TD 8. Au préalable, lire attentivement les sections 3.2.2 et 3.2.3 du document joint ("Procesim: étude d'un processeur simple en PC/PO"), qui expliquent l'architecture de ce processeur jouet (cf. également cours p.183). Identifier les différents éléments sur le dessin ci-dessous : Le tableau au début de la section 1 du document récapitule l'usage des différents registres. Le registre PC est sur 8 bits, un programme en langage machine peut contenir jusqu'à 256 instructions. Les instructions sont sur 16 bits. Les registres étant sur 8 bits, une instruction devra être stockée dans 2 registres : le registre IR (poids forts) et le registre mk2 (poids faibles). Attention, il faudra donc 2 lectures successives en mémoire pour récupérer une instruction. La partie contrôle de ce processeur contient un séquenceur microprogrammé. Question 1. Noter sur le dessin du processeur ci-dessus où se trouvent les éléments de sa partie contrôle, de sa partie opérative, et la mémoire qui contiendra les instructions machine du programme utilisateur à exécuter. Question de cours : que se passe-t-il lors de l'exécution d'une instruction machine, globalement à l'échelle du processeur, et plus spécifiquement au niveau de la partie contrôle ? Quelle est l'utilité de sa ROM ? Où est-elle sur le dessin ? Lire les sections 3.2.4 à 3.2.11 du document, qui décrivent les formats des micro-instructions implémentées. Il y a essentiellement 3 types de micro-instructions : - les micro-instructions de calcul (sections 3.2.5 et 3.2.9) - les micro-instructions de séquencement (sections 3.2.6 et 3.2.10) les micro-instructions read et write pour les accès à la mémoire. En résumé, en langage microcode, les micro-instructions de calcul se présentent sous la forme : destination = shl (sourceA operation source B) ou destination = shr (sourceA operation source B) ou destination = sourceA operation source B ou destination = sourceA operation source B majflag, pour mettre à jour ZNC ou destination = sourceA operation source B ema, pour charger la valeur de BusB dans MA NB. Les identifiants spécifiques suivants peuvent également être utilisés pour les opérandes : labus, pour le registre dont le numéro est dans les 4 bits de poids forts de mk2, lbbus, pour le registre dont le numéro est dans les 4 bits de poids faibles de mk1, et lcbus, pour le registre dont le numéro est dans les 4 bits de poids forts de mk1. Par ailleurs, lual peut être utilisé pour désigner l'opération à effectuer dans l'UAL dont le code est dans les bits 1 et 2 de mk2 (en effet, les deux bits de choix de l’opération réalisée dans l’UAL peuvent être fournis soit par les deux bits ual dans le codage de la micro-instruction – voir plus bas, soit par ces deux bits du registre mk2). En résumé, en langage microcode, les micro-instructions de séquencement se présentent sous la forme : j0, j1,...j7, pour saut si (0ème, 1er, .., 7ème) bit de IR est à 1 ou jp, pour un saut inconditionnel ou jz, pour saut si microZ = 1 ou jn, pour saut si microN = 1 ou jc, pour saut si microC = 1 ou ji, pour saut si bit I du registre F est à 1 ou jq, pour saut si interruption externe Toutes ces instructions sont sur 38 bits. Le bit de poids fort permet de discriminer leur type : - micro-instructions de calcul et d'accès mémoire : bit de poids fort à 0 - micro-instructions de séquencement : bit de poids fort à 1. Nous résumons ci-dessous, de façon schématisée, les détails du codage de ces microinstructions. Pour les micro-instructions de calcul et d'accès mémoire : 1"""""""4""""""""""2""""""""1"""""""1"""""1"""""1""""""1"""""1""""1"""1"""""2"""""1"""""""""4"""""""""""""4""""""""""""4"""""""""""""4"""""""""1""""""1""""""""1"""""""1" 0""""""""""""""dec"""mx""mb""rd""wr""ma""si""ci""f"""ual"""c""""""sc"""""""""sb"""""""""sa""""""""""""""""""BU"""BC"""BB"""BA" 00"="add,"01"="entrée"gauche,"11"="xor"bit"à"bit,"10"="and"bit"à"bit" meAre"à"jour"les"flags"(Z,"N,"C)"dans"le"registre"F" clear"bit"i"du"registre"F" set"bit"i"du"registre"F" 00"="pas"décal.,"01"="décal."sorKe"UAL"à"droite,"10"="décal."sorKe"UAL"à"gauche,"11"non"uKlisée" 1"M>"(gUAL"<M"Bus_A),"0"M>"(gUAL"<M"Bus_B)" MA"<M"Bus_B" MB"<M"sorKe"du"décaleur" lecture"mémoire":"MB"<M"Mem[MA]" écriture"mémoire":"Mem[MA]"<M"MB" numéro"du"registre"transmis"sur"Bus_A" numéro"du"registre"transmis"sur"Bus_B" numéro"du"registre"qui"sera"chargé" registre"de"numéro"donné"par"sc"<M"Bus_C" uKliser"valeur"de"sa"ou"4"bits" de"poids"fort"de"mk2" uKliser"valeur"de"sb"ou"4"bits" de"poids"faible"de"mk1" uKliser"valeur"de"sc"ou"4"bits" de"poids"fort"de"mk1" uKliser"valeur"de"ual"ou"bits"1"et"2"de"mk2" Et pour celles de séquencement : 1"bit"""""""""4"bits""""""""""""""""""""""""""""""""""""""""""""""""""25"bits""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""8"bits" 1""""""condi(on"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""@"micro,instr"suivante" NB 1. Une lecture en mémoire nécessite 2 cycles d'horloge (2 micro-instructions read) et une écriture nécessite 3 cycles d'horloge (3 micro-instructions write). NB 2. On notera aussi l'existence des instructions spéciales seti et clri, pour la mise à 1 et la mise à 0 du bit I du registre F. Question 2. Sur cette machine, la séquence de fetch se traduira de la façon suivante : pc = 0 +pc ema read read pc = pc +1 ir = mb pc = 0 +pc ema read read pc = pc +1 mk2 = mb Expliquer ce que signifient ces lignes, et pourquoi elles correspondent à un fetch. Question 3. Sur mandelbrot, lancer le simulateur par la commande "procesim". Les fenêtres qui s'ouvrent alors sont les suivantes : La fenêtre principale montre la vue du processeur, la fenêtre "Mémoire" montre le contenu de la RAM (programme utilisateur), et la fenêtre "Micro-actions" montre le contenu de la ROM (toutes deux vides à l'origine). (1) Génération du microcode à placer en ROM. Le microprogramme qui vous est fourni est donné dans le fichier microcode.muc (à récupérer sur mandelbrot dans le répertoire /home/p/pierrlau/ALM/TP_Procesim). La commande : masm microcode.muc vous permet de produire le microcode associé. Attention, le fichier produit s'appelle sortie.mob, renommez-le en microcode.mob. (2) Chargement des codes en mémoires. Par un click sur l'icône de disquette à côté de la ROM, charger dans la ROM le code qui a été placé dans microcode.mob. Par un click sur l'icône de disquette à côté de la RAM, charger dans la RAM le petit programme exemple qui vous est fourni dans le fichier exemple_noit.ob (également à récupérer sur mandelbrot dans le répertoire /home/p/pierrlau/ALM/TP_Procesim). Vérifier que les contenus des mémoires ont bien été mis à jour. (3) Observation et analyse de la simulation. Chaque click sur le bouton Horloge simule un top d'horloge. A chaque étape, vous pouvez suivre à la fois les déplacements en mémoires, et les mouvements réalisés dans le processeur (voir la coloration verte des chemins activés). Cliquer sur le bouton Horloge jusqu'à ce que la valeur contenue dans PC soit 0x40. Quelle est la micro-instruction exécutée au top d'horloge suivant ? Lors de la micro-instruction suivante (read), où se trouve-t-on dans la RAM ? Pourquoi ? Quelle est l'instruction concernée ? Suivre toute la phase de fetch et noter précisément, pour chaque micro-instruction, les actions réalisées dans le processeur : quels bits de la micro-instruction en cours sont utiles à son interprétation et pourquoi, quels registres et bus sont utilisés, quels registres sont chargés, avec quelles valeurs, quelles opérations de l'UAL sont réalisées,… A la fin de la phase de fetch, quels sont les contenus des registres IR et mk2 ? Quel est donc le code de l'instruction qui va maintenant s'exécuter ? Expliquer ce code, par rapport aux formats d'instructions vus au TD8. NB. Noter que vous pouvez recommencer à tout moment si nécessaire, grâce au bouton Reset. Question 4. Faites avancer l'exécution jusqu'à la fin de cette instruction. Combien de micro-instructions nécessite-t-elle ? Quelle est la dernière étiquette à laquelle nous nous sommes branchés dans le microcode ? Quelle est la dernière micro-instruction qui y est exécutée avant de retourner à l'étape de fetch de l'instruction suivante ? A quoi sert cette micro-instruction ? Quel résultat observez-vous ? Quelle est l'adresse de l'instruction suivante ? Quel est le code de cette instruction ? Où et quand le voit-on apparaître ? Faites avancer l'exécution jusqu'à la fin de cette instruction. Combien de micro-instructions nécessite-t-elle ? Quelle est la dernière étiquette à laquelle nous nous sommes branchés dans le microcode ? Quelle est la dernière micro-instruction qui y est exécutée avant de retourner à l'étape de fetch de l'instruction suivante ? A quoi sert cette micro-instruction ? Quel résultat observez-vous ? Quelle est l'adresse de l'instruction suivante ?