% objectif % * utilisation de l'outil % -> exploration architecturale % -> sur 2 composants, parler du compromit performance/surface. \begin{abstract} \end{abstract} %=================================================================================== \Section{Introduction} L'approche actuelle pour dévelloper des systèmes embarquées est fondée sur le secret. Les composants matériels et/ou logicielle sont fermés. Les concepteurs utilisant ces Intellectual Proprity (IP) ne sont pas assuré d'absence de chevaux de troie, de la pérénité de ce composant (arrêt de la production ou changement de protocole de communication). La nouvelle approche se base sur l'utilisation de composant ouvert. Ceci engendre la disponibilité du code source et rendre plus facile l'intégration sur FPGA. Ceci permet d'avoir des systèmes sur puces (SOC). De telle systèmes ont des contraintes varié en terme de la performance nécessaire à l'application et à la surface disponible pour la plate-forme matérielle. Pour cela, le processeur doit exploiter tout les formes de parallélisme disponible. Une implémentation superscalaire permet d'exploiter le parallélisme des instructions en lançant et exécutant plusieurs instructions indépendantes simultanément. Pour cela, il faut que le processeur puisse charger depuis la mémoire plusieurs instructions, les décoder simultanément, détecter les dépendances (de données et de ressources) et les lancer vers les unités d'exécutions disponibles. Les ressources matérielles internes de ce type d'architecture sont complexes (\cite{1997_palacharla}). Cette complexité rend difficile l'implantation sur FPGA ({\it Field-Programmable Gate Array}) d'un processeur sueprscalaire. Sur un tel support technologique, le processeur va être placé dans les ressources prédéterminées du FPGA. Les ressources mémoires sont limitées par leur nombre et par leur accès, de même pour les blocs logiques qui sont limités par le nombre d'entrées pour les fonctions booléennes implémentées. La difficulté pour un concepteur de système intégré est de bien dimensionner sa plateforme matérielle pour les applications logicielles. Pour les applications qui ont besoin de performance, le concepteur ne peut pas sélectionner un softcore libre. Ces derniers n'exploitent pas le parallélisme d'instruction (Instruction Level Parallelism (ILP)). \TODO{citer OPENRISC, LEON, OPENSPARC ...} Le concepteur devra choisir entre une solution multiprocesseurs et paralléliser les applications, par exemple l'architecture Piranha (\cite{2000_barroso}) qui consiste en 8 processeurs alpha scalaire in-order, ou encore l'architecture de l'Hydra (\cite{2000_hammond}) qui instancie 4 processeurs de type mips scalaire. Une autre solution pour le concepteur est d'utiliser des processeurs exploitant l'ILP mais dont le composant est fermé. Disposer d'un processeur exploitant l'ILP et synthétisable sur FPGA permet d'augmenter le nombre de solutions disponibles pour le concepteur de systèmes intégrés. L'exploration architecturale va indiquer au concepteur le nombre de processeurs, le déploiement de l'application et les ressources internes nécessaires pour satisfaire les contraintes de performances du système. De plus, durant la phase exploratoire, le concepteur va définir ces impératifs de performance en suivant les contraintes de surface. Dans cette article nous allons montrer une partie du processeur MORPHEO. Ce composant à pour vocation de fournir un modèle haut niveau (systemC CABA) et bas niveau (VHDL RTL) d'un processeur haute performance. La partie examinée est la boucle d'exécution. Dans la section suivante, nous expliquons ce qu'est la boucle d'exécution et des difficultés pour l'implémenter sur FPGA. Dans la section \ref{section_3}, nous allons analyser la complexité de 3 blocs fonctionnelles : le banc de registres, l'unité mémoire et la station de réservation. Ensuite dans la section \ref{section_4}, nous allons poser nos hypothèses de simulations, les résultats seront discuter dans la section suivante. Enfin nous finirons par une conclusion et quelques perspectives. %=================================================================================== \Section{Boucle d'exécution}\label{section_2} Un processeur à exécution désordonnée peut être décomposé en 3 parties logiques : \begin{description} \item [Front end : ] Cette première partie consiste à charger depuis la mémoire des paquets d'instructions. Une unité de prédiction va calculer l'adresse du prochain paquet. Ensuite chaque instruction du paquet va être décodé et placer dans une file d'attente. \item [Out Of Order Engine : ] Cette unité s'occupe de dés-ordonnancer et de réordonnancer les instructions. Pour cela les registres vont être renommés et les instructions vont être stockées dans une file de ré-ordonnancement. Le numéro d'entrée de cette file permettra d'accéder à la bonne case une fois que l'instruction aura été exécutée. Les instructions sont enlevées de cette file dans l'ordre du programme. C'est ce composant qui vérifie les exceptions ou les erreurs de spéculations. \item [Execution Loop : ] La boucle d'exécution s'occuper de lire les opérandes cibles, exécuter l'opération et écrire le résultats dans le bancs de registres. C'est également dans cette partie que les accès à la mémoire de données vont être effectués. Si l'instruction n'a pas toute ces opérandes sources, alors elle les attendra dans la station de réservation. \end{description} Dans ce document, nous nous centrons sur la boucle d'exécution. Celle-ci contient des structures associatives : les stations de réservation, des bancs de registres multi ports et de la logique de routage : entre les stations de réservations et les unités d'exécutions. Ces types de structures se retrouvent dans les autres parties du processeur : structure associative pour le buffer de reordonnancement, les bancs de registres multi-ports pour le renommage de registres (en particulier le Register Address Translation (RAT)). \printgraph{MORPHEO_micro_architecture-execute_loop}{0.5}{MORPHEO : Execution loop} \TODO{refaire le graphe avec un schéma plus explicite} Comme le montre le graphe \cite{MORPHEO_micro_architecture-execute_loop}, notre modèle de la boucle d'exécution est décomposé en 4 parties : l'unité de lecture, l'unité d'exécution, l'unité d'écriture et enfin le banc de registres. \TODO{parler maintenant des implémentations de la boucle d'execution ou alors dans chaque partie séparée ?} %=================================================================================== \Section{Complexité}\label{section_3} %----------------------------------------------------------------------------------- \subSection{Banc de registres} A chaque cycle plusieurs instructions doivent accèder au banc de registres afin de soit lire leurs opérandes, soit écrire leurs résultats. Le banc de registres doit être multi-accès. Dans le mips R10000 (\cite{1996_yeager}), le banc de registres entier possède 7 ports de lectures et 3 ports d'écritures. Alors que l'itanium 2 (\cite{2003_mcnairy} possède un banc de registres à 12 ports de lectures et 8 ports d'écritures. Si tout les ports de lecture et d'écriture peuvent accèder à tous registres, alors le banc de registre à une implémentation monolithique. La surface et le temps d'accès aux registres augmentent avec le nombre ports. Pour diminuer le nombre de ports, le banc de registres peut être composer de plusieurs bancs ayant localement moins de ports que nécessaire. Dans l'alpha 21264 (\cite{1999_kessler}), les unités entières sont placées dans l'un des deux clusters, et dans chaque cluster il y a une copie de banc de registres. Une autre méthode consiste à réaliser un cache de banc de registres : le cache de niveau 1 contient peu de registres et avec beaucoup de registres alors que le niveau 2 contient peu de port (voir être mono port) et contient une copie de tout les registres. Cette méthode est décrite dans \cite{2000_cruz}. ................. %----------------------------------------------------------------------------------- \subSection{Unité mémoire} L'unité mémoire a pour but de réaliser les accès mémoires. Cette unité doit aussi ordonner les accès mémoires suivant le modèle de consistance mémoires. Dans un modèle relâché, les lectures peuvent être lancées dans n'importe quel ordre. Toutefois, l'unité mémoire doit garder la mémoire cohérente. C'est à dire que les écritures mémoire ne peuvent être exécuter que quand celle-ci ne sont plus spéculative et que toute instructions précèdent ne font pas d'exception. Un accès mémoire arrivant en tête du buffer de ré ordonnancement satisfait ces contraintes. Afin d'accélérer les accès en lecture, l'unité peut faire de la spéculation : faire des accès en lecture à la mémoire instruction et écrire la donnée lut dans le banc de registres avant même d'avoir vérifier que cette lecture n'a pas une dépendance d'adresse avec une écriture antérieure. Dans \cite{1998_chrysos}, Chrysos et Emer ajoute de la spéculation pour détecter les accès en écriture qui sont susceptible d'avoir des dépendances avec des accès en lecture ``proche''. L'implémentation de l'unité mémoire ce fait par l'intermédiaire de deux files circulaires : la store\_queue contient tout les écritures en attentes ainsi que la load\_queue contenant quant à elle les lectures en attente d'accès au cache et en attente d'arrivé de la réponse. Les pointeurs d'écritures de ces deux files sont gérés dans l'étage de renommage. C'est dans ce même étage que les instructions sont placées dans le buffer de réordonnancement. Si les files sont pleines alors le pipeline est arrété. %----------------------------------------------------------------------------------- \subSection{Station de réservation} La station de réservation est une structure associative (CAM). Après que les instructions ont accédées au banc de registres, elles sont placées dans les stations de réservations. Une instruction doit avoir la totalité de ces opérandes pour pouvoir être éxecutée. Toute destination d'une instruction peut être la source d'autres instructions. Pour cela toute les écritures dans le banc de registres doit être propagées vers chaque opérande de chaque entrée de chaque station de réservations. %=================================================================================== \Section{Simulations}\label{section_4} Les simulations sont réalisée avec les benchmarks SPECINT 2000. %=================================================================================== \Section{Résultats}\label{section_5} %=================================================================================== \Section{Conclusion}\label{section_6} \bibliography{\dircommon/bibliographie}