4 Transcription du modèle de performance en VHDL Le modèle de performance de MCSE décrit dans le chapitre 4 représente un investissement de plus de 5 ans de la part de l équipe MCSE. L objectif de l équipe était d aboutir à un modèle de performance intégré à la méthodologie de conception complète MCSE et à une technique d évaluation de ce modèle pour analyser des architectures de systèmes tout au long du cycle de développement. Pour l évaluation du modèle de performance, plusieurs approches ont été envisagées: une évaluation analytique, le développement d un simulateur spécifique et la transcription du modèle en un langage simulable. L évaluation analytique qui nécessite la transcription du modèle en un modèle analytique (réseaux de Petri stochastiques ou de files d attentes par exemple) n a pas été retenue car nous pensons qu elle est mal adaptée à la complexité des systèmes considérés dans cette étude. La seconde solution est également en cours d expérimentation. Elle repose sur la transcription du modèle de performance en un programme multi-tâches C++ et sur l utilisation du noyau multi-tâches de Windows95/NT pour son exécution. La solution basée sur l emploi d un langage simulable est celle décrite dans ce chapitre. Le langage de simulation retenu ici est VHDL. Aussi, l objectif précis de ce chapitre est de détailler les règles de traduction développées pour aboutir à un modèle VHDL simulable capable de produire les résultats de performances souhaités. Le résultat de ce chapitre est important car il sert ensuite de base pour l intégration des règles de traduction dans l outil de génération VHDL présenté dans le chapitre 6. Nous commençons par décrire la technique retenue pour l évaluation de performances. Nous justifions ensuite le choix du langage VHDL. Certaines propriétés intrinsèques du langage VHDL (parallélisme inhérent, instanciation multiple, paramètres génériques, etc.) facilitent la transcription et la simulation de notre modèle de performance. Mais, le langage VHDL pour la M.C.S.E 85
Chapitre 4 simulation de notre modèle de performance souffre également de quelques restrictions. Ces restrictions et notamment l absence de mécanisme de suspension de process, nous ont amenés à définir un modèle de simulation qui modélise un processeur logiciel sous la forme d un composant ordonnanceur chargé de gérer les différentes tâches (fonctions) allouées au processeur. La description des règles de transcription se poursuit avec la définition des règles concernant la transcription de la composante structurelle du modèle de performance. Un composant actif (fonction, processeur) est transcrit sous la forme d une entité ou d un block, ce qui permet de préserver la hiérarchie du modèle MCSE source, la trace des entrées/sorties d un composant actif (port map) et la généricité (generic map). Un élément de relation est transcrit par une entité générique qui est instanciée sous la forme d un composant. Le couplage entre un composant actif et un élément de relation est effectué avec un protocole de communication en 4 phases. Ce protocole est implanté sous la forme d un signal bidirectionnel et d une fonction de résolution. Pour la transcription de la composante comportementale du modèle de performance, le comportement de chaque fonction est modélisé comme un ensemble de process synchronisés et coopérants. Nous décrivons alors le mécanisme de synchronisation de process concurrents et les principes de transcription de toutes les autres constructions du modèle de comportement: la séquence, l alternative, la répétition, l activation conditionnelle, l achèvement forcé d activités, les conditions d activations et les actions. La construction la plus complexe à traduire est l achèvement forcé d activité qui est à rapprocher des EI Arcs (Exit Immediately) d un SpecChart [GAJSKI-93]. Parmi les restrictions du langage VHDL pour la simulation de notre modèle de performance, la plus contraignante est le manque de généricité pour la déclaration des types. Cette restriction a deux implications: - sur la déclaration des primitives d accès aux éléments de relation. Il faut regrouper tous les types des éléments de relation en un seul type (record) ou définir autant de primitives d accès qu il y a de types différents (surcharge de procédure), - sur la déclaration des signaux connectant l entité ou le block d un élément actif au composant d un élément de relation. Un lien de connexion entre un composant actif et un élément de relation est traduit sous la forme d un vecteur uni-dimensionnel ou bi-dimensionnel dont il faut gérer les indices et la répartition (utilisation alias). Lors de la simulation du programme VHDL, des informations pertinentes doivent être extraites pour analyser les résultats de performance. La technique d extraction d informations retenue repose sur l utilisation d une librairie de composants de monitoring qui génèrent des fichiers exploitables par le logiciel GnuPlot ou sur la génération d une trace d événements qui est utilisée par l outil d analyse des performances développé par l équipe MCSE [CALVEZ-95c] [CALVEZ-98a]. L utilisateur peut également rajouter au code VHDL généré des instructions de captures spécifiques et utiliser les possibilités d observations offertes par le simulateur VHDL utilisé. Les règles de transcription ont été validées en autres sur l exemple simplifié du serveur vidéo dont le modèle de performance a été présenté dans le chapitre 3. Nous présentons donc dans ce chapitre à titre d illustration les résultats de performance obtenus pour l exemple. Le 86 M.C.S.E
Transcription du modèle de performance en VHDL chapitre 7 détaille aussi 2 autres exemples qui ont permis de valider et d enrichir les concepts du modèle de performance et la technique d évaluation associée. 4.1 TECHNIQUE POUR L EVALUATION DE PERFORMANCE Après avoir défini le modèle de performance, la phase suivante porte sur le développement d une méthode permettant l évaluation des performances souhaitées par le concepteur. En effet, rappelons que la procédure itérative à suivre par les concepteurs se décompose en 3 phases: - modélisation incrémentale du système ou de l'application, - évaluation des performances souhaitées, - visualisation des résultats, interprétations et prise de décision. La troisième phase conduit généralement à un retour sur la première phase pour modifier, améliorer, poursuivre la décomposition du modèle, ou à un retour sur la deuxième phase pour modifier la sélection des résultats demandés ou des paramètres de l'évaluation. A noter que la deuxième phase se doit d'être la plus transparente et la plus efficace possible pour l utilisateur, l objectif de ce dernier étant de permettre d itérer rapidement entre les phases 3 et 1. Le choix d'une méthode spécifique pour l évaluation passe par une analyse des possibilités. D'une manière générale, l'observation des propriétés d'un système peut résulter de 3 techniques différentes: - l'évaluation analytique (ou mathématique), - la simulation, - l'observation et la mesure. L'évaluation analytique est appropriée pour un modèle dont tous les éléments sont décrits d'une manière analytique, et si en plus il existe une méthode globale directe ou itérative permettant de déduire les propriétés globales du modèle à partir de ses constituants. Nous pensons que le modèle de performance retenu est beaucoup trop structurel et dynamique pour que cette méthode puisse être appliquée. L'observation et la mesure ne s'appliquent que sur un système réel que l'on place en fonctionnement. Ceci suppose que toute la conception soit achevée et qu'un prototype existe. La simulation est une technique appropriée pour un modèle dynamique. Ainsi, nous pensons que seule cette technique est utilisable durant la spécification et la conception des systèmes matériels/logiciels. Deux techniques de simulation sont possibles: l utilisation d un simulateur spécifique pour le modèle ou la transcription du modèle en un langage pour lequel un simulateur existe. Les deux techniques sont simultanément envisagées par l équipe: emploi du langage VHDL et un simulateur, emploi du langage C++ et exécution du programme dans un environnement multi-tâches. Cette étude concerne par la solution par simulation VHDL. M.C.S.E 87
Chapitre 4 La technique en développement est représentée par la figure 4.1. Modèle système Saisie graphique du modèle Méthode en développement Modèle graphique Transcription en VHDL Programme VHDL simulable Simulation en VHDL Interprétation des résultats Définition des attributs Règles de transcription Paramètres, workload -Figure 4.1- Démarche et outil pour l évaluation des performances. Le modèle du système à simuler est saisi par un outil graphique. Les attributs sont aussi ajoutés. Cette description sauvée sous forme textuelle est ensuite transcrite en un programme VHDL conformément à des règles de traduction que nous détaillons dans ce chapitre. Le programme VHDL est instrumenté puis simulé pour obtenir les observations souhaitées. La transcription du modèle concerne le modèle de structure (fonctionnel et exécutif) et le modèle de comportement. La partie délicate concerne la prise en compte de l élément processeur qui conduit à restreindre le degré de parallélisme des fonctions qu il supporte, mais c est cette particularité qui permet la co-simulation. Pour la compréhension de la méthode globale, nous commençons par indiquer le modèle de simulation retenu pour la transcription d un constituant actif à degré de parallélisme limité. Au préalable, nous justifions le choix du langage VHDL. 4.2 CHOIX DU LANGAGE VHDL A première vue, le choix du langage VHDL conduit à disposer d une excellente plate-forme pour l évaluation des performances aussi bien pour la simulation que pour l extraction et l analyse des résultats. Pour la simulation, les propriétés et certaines constructions du langage VHDL autorisent ou facilitent la simulation de notre modèle de performance, à savoir: - Parallélisme inhérent. La notion de process permet de simuler des tâches concurrentes dont le comportement de chacune est purement séquentiel. VHDL possède donc une propriété qui est aussi intéressante pour le co-design [ECKER-93]. En effet, une simulation VHDL peut très bien permettre d étudier un partitionnement logiciel/ matériel donné. Les descriptions concurrentes représentent alors les différents processeurs matériels et logiciels et pour chaque processeur logiciel la partie logicielle est représentée par une description séquentielle. Pour la description logicielle, il existe dans le domaine public des outils de conversion de VHDL vers C et réciproquement. Evidemment, cette conversion ne concerne que certaines constructions des "sequential statements" du langage VHDL. - Instanciation multiple (instruction Generate) qui permet la création multiple (uniquement statique) de composants, de blocs ou de process. Pour l extraction de résultats, on peut facilement définir une librairie de composants permettant d extraire par exemple le taux d occupation d une ressource ou le débit sur un port de communication. L utilisation des possibilités de "debugging" et d analyse du simulateur 88 M.C.S.E
Transcription du modèle de performance en VHDL utilisé (sortie sous forme de chronogrammes) permet aussi de visualiser en détail des résultats de simulation. L analyse faite dans le chapitre 2 a montré qu il existe un certain nombre d outils commerciaux ou universitaires pour l analyse des performances d un système. Certains tels que Adept de l université de Virginie (modèle UVa) et Cosmos de Omniview utilisent VHDL pour simuler leurs modèles et extraire des informations. Les autres parmi lesquelles on peut citer en autres SES/WorkBench, RDD100 et BOnes ont un formalisme, un simulateur et des possibilités d analyse des résultats qui leur sont propres. Par rapport à cette seconde catégorie d outils spécifiques, l emploi de VHDL offre un certain nombre d avantages tels que: - laportabilité. C est un langage standard et normalement indépendant de tout vendeur. Les modèles générés en VHDL peuvent s échanger plus facilement entre différents groupes de travail. L emploi d un langage unique élimine aussi tout risque d erreurs ou d approximations de transcription. - la lisibilité et la compréhensibilité. L emploi de VHDL pour l évaluation des performances est intéressant pour avoir un meilleur impact sur la communauté des concepteurs d architectures matérielles habitués à utiliser VHDL. A cet égard, il est indispensable que le code VHDL généré automatiquement à partir du modèle de performance soit le plus lisible et compréhensible possible. - lacomplétude. La vérification de la complétude et de la consistance du modèle généré est assuré automatiquement par le compilateur/simulateur VHDL utilisé. - la traçabilité. VHDL permet de décrire plusieurs niveaux d abstraction du système, plusieurs architectures pour un même composant et peut être utilisé durant tout le cycle de développement d un système. - la disponibilité des outils. Il y a aujourd hui de nombreux outils basés sur VHDL disponibles sur la marché. L utilisation conjointe de ces différents outils permet de couvrir la plupart des phases de conception de la spécification à la réalisation. Sous certaines conditions, des outils de synthèse haut-niveau (Behavioral Compiler de Synopsys, SpecSyn de l UCI, AMICAL de l équipe Tima, GAUT du Lasti-Lester, etc.) permettent même de transformer une description VHDL comportementale en une description VHDL au niveau RTL. Cette description résultante est ensuite transformée par synthèse logique en une netlist de portes et de bistables pour une implantation dans un circuit. Les propriétés intrinsèques du langage VHDL satisfont aussi certains critères de qualité d un modèle énoncés dans le chapitre 3: - modèle hiérarchique. Les notions d entité, de block et de composant permettent de décomposer la description du système. On peut également définir plusieurs solutions d architecture pour une même entité et choisir l architecture retenue uniquement au moment de son instanciation (mécanisme de configuration). La notion de composant est très importante car elle permet la réutilisation de modèle. - modèle paramétrable. VHDL permet l utilisation de paramètres génériques. - modèle d interdépendance. Très proche syntaxiquement du langage ADA, VHDL se distingue des langages de programmation par le concept de signal. M.C.S.E 89
Chapitre 4 Mais, l utilisation de VHDL pour la simulation de notre modèle de performance souffre de quelques restrictions: - manque de généricité pour la déclaration des types. Par exemple, il n est pas possible de déclarer un type non contraint d un type non-contraint ou de déclarer un type non contraint dans un record. - pas d instanciation dynamique possible (uniquement statique). - pas de mécanismes de suspension de process. - l utilisation d un simulateur VHDL nécessite aussi des ressources de simulation importantes (puissance de calcul, mémoire). Les temps de simulation relativement importants même pour un modèle macroscopique et non interprété ne permettent pas de parcourir très rapidement l espace des solutions possibles. Dans le projet RASSP, la modélisation de performance repose également sur l utilisation du langage VHDL et regroupe principalement l Université de Virginie (modèle UVa/Adept), Honeywell Technology Center, Lockheed Martin Advanced Technology Laboratories [HEIN-95] et Omniview. L outil Cosmos est par exemple le fruit de cette association et de ce travail de recherche. 4.3 MODELE DE SIMULATION RETENU POUR L EMPLOI DE VHDL La transcription du modèle de performance en VHDL repose tout d abord sur un bon choix de solution d implantation. La solution à retenir ici est très dépendante à la fois du modèle à traduire et du langage cible. En effet VHDL possède un certain nombre de propriétés intéressantes en particulier le parallélisme inhérent au langage qui permet aisément la description et la simulation de systèmes décrits par du parallélisme. Les particularités essentielles du modèle de performance qui ont servies au choix du modèle de simulation sont les suivantes: - instanciations multiples de fonctions, d activités, d opérations, d éléments de relation, - degré de parallélisme de chaque fonction (ou processeur) définissable, ce qui implique une limitation du degré de partage d une ressource, - création dynamique d activités, - paramétrage complet du modèle par des attributs: attributs prédéfinis, attributs définis par l utilisateur. Pour satisfaire ces exigences, le modèle de simulation retenu pour le modèle de structure est représenté par la figure 4.2. La partie supérieure (au dessus du pointillé) montre un exemple de structure fonctionnelle représentant la décomposition de la fonction F en les fonctions F1 et F2[1:m] et la relation par V[1:m]. Chaque fonction est définie par les attributs: Concurrency, Power, Policy, Priority, Deadline. Les attributs des 3 types de relations EV, Port et V[1:m] sont aussi rappelés sur la figure. Les temps Write, Read, Use sur les liens peuvent venir surcharger les attributs de l objet de relation. 90 M.C.S.E
Transcription du modèle de performance en VHDL F EV Read Policy Concurrency Write Read F1 Concurrency Power Policy Priority Deadline OverHead state Write Read V[1:m] Policy Concurrency Capacity Write Read Use Cons F2[1:m] state Write Port Capacity Concurrency Write Read States(F1) States(F2[1:m]) Scheduler state States(F) Concurrency Power Policy Priority Deadline OverHead TYPE DefUState IS RECORD TaskState : DefTaskState priority : NATURAL; deadline : TIME; power : REAL; END RECORD; -Figure 4.2- Modèle de simulation retenu pour la transcription en VHDL. Pour la fonction F, le problème important à résoudre consiste à obtenir une exécution de toutes ses fonctions internes avec les échanges par relations conformément à ses attributs. L attribut Power de la fonction F implique simplement la modification des temps d exécution de tous les constituants internes en utilisant Power comme facteur multiplicatif (<1 implique un ralentissement, > 1 implique une accélération). L attribut Concurrency de F est le plus spécifique. S il est à une valeur infinie (0 choisie comme valeur représentative), il n y a pas de particularité. Si sa valeur est inférieure au nombre de fonctions internes à évolution potentiellement parallèle (incluant toute la décomposition interne jusqu aux opérations), il faut assurer un ordonnancement des fonctions selon une politique ( Policy) et avec l attribut approprié ( Priority ou Deadline). Il s agit là d un moyen pour simuler l influence d un support exécutif représenté par F avec un degré d exécution limité. Ceci implique la possibilité de préemption du processeur ou de la ressource d exécution pour une fonction ou une activité interne. Ce point précis est une difficulté en VHDL car il est impossible de suspendre et ensuite de relancer un process de l extérieur. La solution retenue pour la simulation est l ajout de la partie basse de la figure 4.2. Chaque unité de comportement, c est-à-dire fonction, activité ou opération, est transcrite comme une tâche. Une variable State est associée à chaque tâche. Cette variable va être modifiée par l ordonnanceur Scheduler pour indiquer les états actifs et suspendus de la tâche. M.C.S.E 91
Chapitre 4 Ce modèle de solution satisfait la condition de description hiérarchique. En effet, chaque fonction possède la variable State en entrée. Ceci est le cas pour F mais aussi pour F1 et F2. Chaque fonction est donc dépendante de sa fonction englobante. 3 procédures sont à la disposition des fonctions pour gérer la ressource d exécution, ce qui se traduit par la modification de sa variable State (qui correspond à States[i] à l extérieur): - InactiveTask(state: DefState); qui rend la tâche inactive avec libération de la ressource d exécution, - BlockingTask(state: DefState); qui indique une mise en attente sur une condition d activation avec libération de la ressource d exécution, - ingtask(state:defstate); qui assure une demande de la ressource, en sortie de la procédure la ressource a été obtenue. 4.4 IMPLANTATION DE LA FONCTION D ORDONNANCEMENT La limitation du parallélisme de la ressource d exécution est assurée par une fonction Scheduler ajoutée en interne de chaque fonction. Scheduler est transcrite comme un composant (entité) VHDL. Comme entrées/sorties, il utilise d une part sa variable State par laquelle son environnement (le niveau hiérarchique supérieur) lui indique la disponibilité de la ressource d exécution, d autre part la variable States qui regroupe l état de toutes les fonctions internes à exécuter. Une variable States(i) pour la fonction i comprend: - la variable TaskState représentant l état de la fonction avec les états: Inactive, Blocked, ing, Active, - la variable Power transmettant ainsi le paramètre à la fonction i pour la modification des temps d exécution, - les variables Priority et Deadline définissant son urgence pour l ordonnancement (une seule utilisée à la fois par le scheduler compte-tenu de son attribut Policy), Les états d une fonction et les transitions entre eux sont représentés par la figure 4.3. Début exécution (ingtask) Condition satisfaite Ressource allouée par le scheduler Ressource préemptée (BlockingTask) Inactive Blocked ing end Active (ingtask) attente condition (BlockingTask) Fin exécution (InactiveTask) -Figure 4.3- Etats d une fonction et conditions de transition. L état ing est spécifique de l emploi d une ressource limitée. Pour que tous les temps d exécution n évoluent que durant l état Active, ils sont tous simulés par une procédure DELAY qui permet ainsi de gérer un point de préemption par la ressource d exécution. Bien entendu, pour cela on interdit l emploi de l instruction VHDL " for Time". Le comportement de la procédure DELAY est décrit ci-dessous. 92 M.C.S.E
Transcription du modèle de performance en VHDL PROCEDURE Delay( CONSTANT Time : IN TIME; SIGNAL TaskState : IN DefState) IS VARIABLE GlobalTime,RemainTime: TIME := NullTime; GlobalTime:=now; IF (TaskState.power/=0.0) THEN RemainTime:=Time/TaskState.power; ELSE RemainTime:=Time; LOOP WAIT UNTIL (TaskState.state/=Active) FOR RemainTime; IF (TaskState.state=Active) THEN exit; ELSE RemainTime:=RemainTime-(now-GlobalTime); WAIT UNTIL (TaskState.state=Active); GlobalTime:=now; END LOOP; END Delay; On constate bien que l évolution du temps est bloquée lorsque la fonction utilisant la procédure DELAY n est plus active. L attribut Power dans l argument TaskState est utilisé pour modifier le temps d exécution fourni comme argument. La description VHDL de la fonction Scheduler est donnée ci-après. Son comportement se rapproche de celui d un ordonnanceur d exécutif temps-réel. Seule la politique d ordonnancement selon la priorité est actuellement implantée. Il est évident que d autres politiques sont aisément implantables par extension algorithmique en utilisant la valeur de l attribut Policy. La fonction est décrite sous la forme d une entité générique. Elle exploite une fonction de résolution strictement nécessaire pour gérer la variable partagée state. -- ########################################################### -- # Types et fonction de resolution pour l'etat d'une tache # -- ########################################################### TYPE DefTaskState IS (Nodriver,Inactive,Blocked,ing,Active); TYPE DefTaskStateTable IS ARRAY(DefTaskState,DefTaskState) OF DefTaskState; CONSTANT ResolutionTaskState : DefTaskStateTable :=( -- ----------- ---------- ----------- --------- -------- -- Nodriver Inactive Blocked ing Active -- ----------- ---------- ----------- --------- -------- --------------- ( Nodriver, Inactive, Blocked, ing, Active), -- Nodriver ( Inactive, Inactive, Inactive, ing, Inactive), -- Inactive ( Blocked, Inactive, Blocked, ing, Blocked), -- Blocked ( ing, ing, ing, ing, Active), -- ing ( Active, Inactive, Blocked, Active, Active) -- Active ); TYPE DefUState IS RECORD state : DefTaskState; priority : NATURAL; deadline : TIME; power : REAL; END RECORD; TYPE DefUStateVector IS ARRAY (NATURAL RANGE <>) OF DefUState; FUNCTION ResolState (Input : DefUStateVector) RETURN DefUState; SUBTYPE DefState IS ResolState DefUState; TYPE DefStateVector IS ARRAY (NATURAL RANGE <>) OF DefState; ENTITY Processor IS GENERIC ( Concurrency : NATURAL := 1; Power : REAL := 1.0; OverHead : TIME := NullTime;); PORT (SIGNAL StateVector : INOUT DefStateVector; SIGNAL ProcessorState : INOUT NATURAL); END Processor; ARCHITECTURE behavioral OF Processor IS Scheduling : PROCESS M.C.S.E 93
Chapitre 4 VARIABLE CurrentConcurrency,i, highestingfunction, lowestactivefunction : NATURAL; VARIABLE TaskIsing : BOOLEAN; InactiveTask(ProcessorState); InitStates(StateVector, power*processorstate.power); LOOP ingtask(processorstate); LOOP WAIT UNTIL StateVector EVENT or ProcessorState EVENT; CASE ProcessorState IS WHEN Inactive => TaskIsing:=FALSE; FOR i IN StateVector RANGE LOOP IF StateVector(i).state=waiting THEN TaskIsing:=TRUE; EXIT; IF TaskIsing THEN ingtask(processorstate); WHEN Active=> -- Scheduling according to a static priority InfoFunctions(StateVector,CurrentConcurrency, lowestactivefunction,highestingfunction); IF ((CurrentConcurrency<Concurrency) AND (highestingfunction/=0)) THEN ActiveFunction(StateVector,highestingFunction, OverHeadProcessor,ProcessorState); ELSIF ((highestingfunction/=0) AND (lowestactivefunction/=0) AND (StateVector(lowestActiveFunction).priority< StateVector(highestingFunction).priority)) THEN -- processor preemption Preemption(StateVector,lowestActiveFunction, highestingfunction, OverHeadProcessor,ProcessorState); ELSIF (CurrentConcurrency=0) THEN -- pas de fonction active ou en attente InactiveTask(ProcessorState); WHEN OTHERS=> -- Blocked, ing, ExitNow, NoDriver FOR i IN StateVector RANGE LOOP IF StateVector(i).state=Active THEN StateVector(i).state<=waiting; END LOOP; ingtask(processorstate); END CASE; END LOOP; END LOOP; END PROCESS Scheduling; END behavioral; L ordonnanceur ne peut rendre actif une fonction qu il contrôle que lorsqu il est lui-même dans l état actif. Les primitives ActiveFunction et Préemption tiennent compte de l attribut Overhead (temps de commutation) et de l état du processeur (possibilité d une suspension de processeur). Le fonction Scheduler se charge aussi de mettre à disposition de chaque fonction qu elle gère la puissance d exécution à exploiter (Power d une fonction = Power de cette fonction * Power de la fonction englobante). 94 M.C.S.E
Transcription du modèle de performance en VHDL 4.5 TRANSCRIPTION DU MODELE STRUCTUREL Le modèle structurel permet de représenter la solution d une application selon un ensemble de fonctions et de relations entre celles-ci. Les relations entre fonctions sont de 3 types: - relation de synchronisation pour exprimer une dépendance temporelle, - relation de partage de données ou de ressources, - relation de transfert d information et de communication ce qui sous-entend une dépendance temporelle avec échange. Dans la suite, on s intéresse successivement à la transcription d une fonction, d un port, d un événement et d une variable partagée. Il faut garder à l esprit que toute fonction, activité ou opération reste implantée conformément au modèle précédent. Ceci n est bien sûr à faire que lorsqu il y a limitation de la ressource d exécution. 4.5.1 Transcription d une fonction Dans le cas général, une fonction sera transcrite sous la forme d une entité. Ceci permet: - de garder la hiérarchie du modèle, - de garder la trace des entrées/sorties d une fonction (port map), - d exploiter la généricité (generic map), - d exploiter la réplication et la notion de modèle de fonctions (une entité peut être instanciée sous forme de composant ou même directement avec VHDL 93), - d utiliser l instanciation multiple, - d associer plusieurs modèles à une même entité (plusieurs descriptions d architectures, l une choisie par configuration). Lorsque certaines propriétés de l entité n ont pas à être exploitées, particulièrement l intérêt de plusieurs modèles, il est possible d utiliser une notion relativement proche: le block. Si le block ne permet pas de traduire la notion de réplication/modèle de fonctions, il offre, contrairement aux entités, la possibilité d accéder à des variables globales (Shared variable de VHDL 93), ce qui est très utile dans certains cas. Il faut noter que pour un block la partie Generic Map et Port Map est optionnelle et purement déclarative: un oubli d une entrée/sortie ou d un paramètre générique n entraînera pas forcément d erreur de compilation (passage par effet de bord). Aussi il faut faire très attention pour préserver la lisibilité du programme. L exemple ci-dessous montre la possibilité d exploiter simultanément les concepts d entité et de block. Les fonctions décrites ci-après ne possèdent pas la variable State en entrée car nous avons supposé qu il n y a pas de limitation de ressource d exécution. Pour la compréhension, l entité modélise l environnement de l exemple simplifié du serveur vidéo dont la structure fonctionnelle est représentée par la figure 3.14 du chapitre 3. ENTITY EnvironnementVideoServer IS GENERIC (n : INTEGER := 1); PORT (Cmd : INOUT DefPortInVector(1 TO n); BlockIn : INOUT DefPortIn; BlockOut : INOUT DefPortOutVector(1 TO n)); END EnvironnementVideoServer; ARCHITECTURE behavioral OF EnvironnementVideoServer IS -- variable partagee pour la generation de nombres aleatoires SHARED VARIABLE rnd : REAL; M.C.S.E 95
Chapitre 4 -- modelisation de l'environnement du systeme etudie -- entite Users Users : BLOCK PORT (Cmd : INOUT DefPortInVector(1 TO n)); PORT MAP (Cmd=>Cmd); MultipleInstanciation: FOR i IN 1 TO n generate User : BLOCK PORT (Cmd : INOUT DefPortIn); PORT MAP (Cmd=>Cmd(i)); CONSTANT me : INTEGER := i; UserBehavior : PROCESS.; END PROCESS UserBehavior; END BLOCK User; END GENERATE MultipleInstanciation; END BLOCK Users; -- entite source source : BLOCK PORT (BlockIn : INOUT DefPortIn); PORT MAP (BlockIn=>BlockIn); EmissionBehavior : PROCESS.; END PROCESS EmissionBehavior; END BLOCK source; -- entite TVSet TVSet : BLOCK PORT (BlockOut : INOUT DefPortOutVector(1 TO n)); PORT MAP (BlockOut=>BlockOut); CONSTANT TconsTime : TIME := 10 us; MultipleInstanciation: FOR i IN 1 TO n generate TV : BLOCK PORT (BlockOut : INOUT DefPortOut); PORT MAP (BlockOut=>BlockOut(i)); ReceptionBehavior : PROCESS.; END PROCESS ReceptionBehavior; END BLOCK TV; END GENERATE MultipleInstanciation; END BLOCK TVSet; END behavioral; La description sous forme d entité ou de block permet de garder la hiérarchie du modèle MCSE, la trace des entrées/sorties des composants actifs (port map) et la généricité (generic map). Dans l exemple, le paramètre générique n est utilisé pour dimensionner des éléments internes (dimension des éléments de relation Cmd et BlockOut et des fonctions User et TVSet). L utilisation d un block à la place d un entité offre plusieurs avantages: - un block est instanciable directement, ce qui en contre partie ne permet pas la réplication (pas de déclaration de composant). La construction VHDL Generate est utilisée pour l instanciation multiple des fonctions User et TVSet. L attribut me Index est alors traduit sous la forme d une constante (constante me). - un block permet d accéder à des variables partagées (Shared Variable de VHDL 93) telle que la variable rnd qui est utilisée par un générateur de nombre pseudo-aléatoire. 96 M.C.S.E
Transcription du modèle de performance en VHDL 4.5.2 Transcription d un port La transcription d un port nécessite de tenir compte du comportement systématique de tout port (c est-à-dire la gestion des messages reçus et délivrés) et de tous les attributs qui particularisent son comportement. Un protocole de communication est développé pour le couplage d un élément de relation avec une fonction. Notons que le principe de traduction consiste à considérer que l élément de relation est un élément passif. -A- Caractéristiques et transcription d un élément de transfert d information L'objet Port pour le couplage est assimilable à un tampon caractérisé par sa capacité en nombre de messages ( Capacity) et son degré de partage pour des accès multiples ( Concurrency). Deux grandeurs temporelles Write et Read sont aussi à considérer pour son utilisation ceci dans le cas de place disponible pour le dépôt, ou d une information disponible pour le retrait. Deux politiques d ordonnancement des messages sont prévues: selon la date de dépôt et donc Fifo, selon la priorité fixée par le demandeur. Concernant le comportement du port, rappelons qu un producteur doit se bloquer s il n y a plus de place pour le dépôt et qu un consommateur doit se bloquer en l absence de messages dans la file du port. Le port est décrit comme une entité instanciée sous la forme de composant. Les attributs associés au port sont les paramètres génériques de l entité (attributs statiques) et/ou font partie des entrées/sorties de l entité (attributs dynamiques). -B- Protocole de communication multi-points De nombreux modèles ne permettent que la communication point à point, ce qui réduit considérablement les possibilités de topologie d un système. La relation considérée dans le modèle MCSE est générale. Il s agit de coupler m producteurs et n consommateurs sur le même port. L échange de donnée entre un port et un ou plusieurs producteurs nécessite un protocole de communication: le producteur doit demander l accès au port et doit maintenir cette demande jusqu à ce que le port soit prêt. Alors un retour (feedback) doit exister entre le port et le producteur pour indiquer que le port a satisfait la requête de l utilisateur et que la demande d accès peut être inhibée. Pour ce type de protocole, deux signaux de contrôle sont habituellement utilisés (request, acknowledge), mais pour la transcription en VHDL, surtout dans le cas de plusieurs producteurs pour un même port, il est préférable d utiliser un signal bidirectionnel (Status) associé à une fonction de résolution (ResolProtocol). Le code VHDL correspondant à l implantation du protocole de communication est le suivant: TYPE DefHandshake IS (InactiveAck,,InactiveReq,ActiveReq); TYPE DefHandshakeTable IS ARRAY (DefHandshake,DefHandshake) OF DefHandshake; CONSTANT ResolutionHandshake : DefHandshakeTable :=( -- ------------- ------------- ------------- ----------- -------------- -- InactiveAck InactiveReq ActiveReq TaskBlocked -- ------------- ------------- ------------- ----------- -------------- ------------------ ( InactiveAck,, InactiveReq, ActiveReq, InactiveAck), -- InactiveAck (,, InactiveReq,, ), -- ( InactiveReq, InactiveReq, InactiveReq, InactiveReq, InactiveReq), -- InactiveReq ( ActiveReq,, InactiveReq, ActiveReq, TaskBlocked), -- ActiveReq ( InactiveAck,, InactiveReq, TaskBlocked, TaskBlocked) -- TaskBlocked ); TYPE DefProtocol IS RECORD priority : NATURAL; date : TIME; status : DefHandshake; M.C.S.E 97
Chapitre 4 END RECORD; TYPE DefUPortIn IS RECORD information : DefInformation; WriteTime : TIME; protocol : DefProtocol; END RECORD; TYPE DefUPortOut IS RECORD information : DefInformation; ReadTime : TIME; protocol : DefProtocol; END RECORD; TYPE DefUPortInVector IS ARRAY (NATURAL RANGE <>) OF DefUPortIn; TYPE DefUPortOutVector IS ARRAY (NATURAL RANGE <>) OF DefUPortOut; FUNCTION ResolProtocol (Input: DefUPortInVector) return DefUPortIn; FUNCTION ResolProtocol (Input: DefUPortOutVector) return DefUPortOut; SUBTYPE DefPortIn IS ResolProtocol DefUPortIn; SUBTYPE DefPortOut IS ResolProtocol DefUPortOut; TYPE DefPortInVector IS ARRAY (NATURAL RANGE <>) OF DefPortIn; TYPE DefPortOutVector IS ARRAY (NATURAL RANGE <>) OF DefPortOut; Cette implantation est à rapprocher de celle du jeton du modèle UVa qui a également inspirée le mécanisme de communication utilisé dans le modèle de performance du projet RASSP (Cosmos). Le protocole est tout d abord expliqué pour le couplage d un producteur avec le port. Le signal Status permet le handshake entre un producteur et un port à l aide des 4 valeurs possibles: InactiveAck,, InactiveReq, ActiveReq. 1- Initialement, le producteur assigne la valeur InactiveAck au signal Status, pendant que le port lui assigne la valeur InactiveAck. La fonction de résolution associée à ce "multiplesignaldriven" lui donne la valeur InactiveAck. 2- Quand le producteur veut faire un accès au port, il assigne la valeur ActiveReq au signal Status et se bloque ce qui libère sa ressource d exécution et comme le port continue à lui assigner la valeur InactiveAck, la fonction de résolution lui donne la valeur provenant du producteur (ActiveReq est équivalent à demande d allocation). 3- Le port voit maintenant la valeur ActiveReq assignée au signal Status. Dès qu il en est capable, il satisfait la requête du producteur et positionne le signal Status à (la fonction copiant le signal Status provenant du port égal à ). 4- En observant Status=, le producteur déduit que sa requête a été acceptée par le port et par conséquent, il demande la ressource d exécution par ing, puis après un délai d utilisation, il positionne avec la complicité de la fonction de résolution le signal Status à InactiveReq (libération du port). 5- Quand le port voit Status=InactiveReq, le port se prépare à un nouvel accès en positionnant Status à InactiveAck. En plus du champ Status, l élément de base de communication possède deux autres champs Priority et Date. Lorsque le nombre d accès simultanés dépasse le degré de partage (attribut Concurrency) de l élément de relation, deux politiques d ordonnancement des accès ont été prévues: selon la date de dépôt ou selon la priorité fixée par le demandeur. Par défaut, le champ Date est fixé avec la date courante de simulation mais il peut être modifié pour appliquer par exemple une politique d ordonnancement au plus tard (voir exemple du serveur vidéo dans le chapitre 7). Le jeton utilisé comme élément de communication de base dans le modèle de performance de Cosmos contient également un champ Size utile pour calculer le débit sur le port et les champs StartTime et Destination utiles pour calculer le temps de latence des messages. Nous ne sommes pas obligés de définir ces champs au niveau du record DefProtocol. La définition 98 M.C.S.E
Transcription du modèle de performance en VHDL et l exploitation de ces attributs peuvent être laissées au libre arbitre de l utilisateur du modèle. Si ils sont utilisés, ces attributs seront alors définis dans le message lui-même au niveau du record DefInformation comme nous le verrons plus loin. Le temps d accès à l élément de relation est simulé du coté producteur et non du coté port. L entité gérant le port est ainsi passive. Lors d une exécution sur un processeur de degré de concurrence limité, l entité n a pas besoin de tenir compte de l état (active, inactive, bloquée ou en attente) de la fonction (tâche) producteur. Cependant, le protocole de communication indique à la tâche producteur qu elle doit passer à l état bloqué (Status égal à TaskBlocked) si le port ne peut satisfaire le requête du producteur. -C- Implantation Le principe d implantation d un port est schématisé par la figure 4.4. La figure 4.4-a représente la structure fonctionnelle constituée des fonctions Prod et Cons reliées par le port de communication nommé Port. L attribut Write sur le lien entre Prod et Port surcharge l attribut Write de Port. La structure de l implantation en VHDL est décrite par la figure 4.4-b. Les fonctions Prod et Cons sont implantées sous la forme d une entité ou d un block dont les entrées/sorties sont composées du signal States (ressource d exécution limitée) et du signal PortIn (respectivement PortOut) pour le transfert de données. Le port de communication est modélisé par un composant. Les paramètres génériques de ce composant sont les attributs associés habituellement à un port de communication ( Capacity, Write, Read, Concurrency). La description interne de l entité associée au composant Port contient une fifo (buff) qui sert à stocker et restituer (primitives Put et Get) les messages transmis. L implantation distingue le port du type rendez-vous ( Capacity=0) des ports à N places (N>0) ou fugace. Le comportement de l entité Port est constitué de deux automates pour un port à N places ou fugace (figure 4.4-c) et d un seul automate pour un port du type Rendez-Vous (figure 4.4-d). De plus, pour un port fugace, il n y a mémorisation du message que s il y a un consommateur en attente. Sur la figure 4.4-c, lorsqu un producteur désire déposer un message, il fait appel à la procédure Send (à gauche de la figure). Cette procédure signale son état actif au port par ActiveReq. Si le port est en mesure de recevoir le message, il répond immédiatement par. La condition d acceptation d un message comprend: la demande ActiveReq, la disponibilité d une place, le degré de concurrence non atteint (NbUse). Si le port n est pas libre, il y a alors libération de la ressource d exécution par la procédure Blocking définissant TaskState=blocked. Après acquittement du port de communication, la fonction passe alors le temps d écriture nécessaire réalisé par la procédure DELAY. Durant cette attente, le ressource d exécution peut être préemptée par une tâche plus prioritaire. Le protocole se termine ensuite par InactiveReq puis l état de repos InactiveAck qui sert aussi à la fin de la procédure Send. Pour un consommateur la procédure Receive (à droite de la figure) est identique mais avec l indication d une attente de message par ActiveReq. M.C.S.E 99
Chapitre 4 a) b) Prod[1:m] Write Port Capacity Write Read Concurrency Cons[1:n] Prod[1:m] Send InStatus[1:m] InValue[1:m] PortIn States(Prod[1:m]) PORT Capacity Write Read Concurrency buff: fifo; OutStatus[1:n] OutValue[1:n] PortOut Receive States(Cons[1:n]) Cons[1:n] Send ( InValue, Port) utilisé dans Prod[i] InValue /ActiveReq Taskblocked c) PORT à N places pour une concurrence NbUse:=0;NbFreeSpace:=Capacity;MnMess:=0; ActiveReq and (NbFreeSpace>0 or NbUse >= Concurrency) TaskBlocked ActiveReq and (NbMess=0 or NbUse >= Concurrency) TaskBlocked Receive (Port, OutValue) utilisé dans Cons[i] Taskblocked / ActiveReq DELAY (writetime) TaskBlocked Blocked ing (ActiveReq or TaskBlocked) and NbFreeSpace>0 and NbUse < Concurrency NbUse++; NbFreeSpace--; Send wait end InAccess Receive wait end OutAccess (ActiveReq or TaskBlocked) and NbMess>0 and NbUse < Concurrency NbUse++; NbMess--; TaskBlocked Blocked ing DELAY (ReadTime) InactiveAck End DELAY InactiveReq InactiveReq NbUse--; NbMess++; Put(buff, InValue); InactiveAck InactiveReq NbUse--; NbFreeSpace++; Get(buff, OutValue); InactiveAck End DELAY InactiveReq InactiveReq InactiveAck buff : fifo pour la mémorisation des messages InactiveAck OutValue d) PORT du type Rendez-Vous pour une concurrence Taskblocked Input/ActiveReq InputTaskBlocked Blocked Input ing NbUse:=0; InputActiveReq and not(consready) and NbUse >= Concurrency) InputTaskBlocked Rendez Vous ProdReady and ConsReady and NbUse < Concurrency NbUse++; Input OutputInactiveReq Start * astuce pour que le Rendez consommateur ne soit Vous pas pris pour un autre producteur 1 OutputActiveReq and not(prodready) and NbUse >= Concurrency) OutputTaskBlocked /OuputActiveReq OutputTaskBlocked Blocked Output ing Taskblocked DELAY (writetime) InactiveAck End DELAY InputInactiveReq Blocked InputInactiveAck ing Write Delay InputInactiveReq Output end OutAccess OutputInactiveReq NbUse--; InputInactiveAck OutputInactiveAck End DELAY OutputInactiveReq OutputInactiveAck DELAY (ReadTime) InactiveReq OutValue ConsReady := OutputActiveReq or OutputTaskBlocked; PropReady := InputActiveReq or InputTaskBlocked; -Figure 4.4- Solution pour l implantation d un transfert de messages par un port. 100 M.C.S.E
Transcription du modèle de performance en VHDL Pour un port du type rendez-vous, il y a gestion de couples Producteur/Consommateur. Le degré de concurrence (attribut Concurrency) représente alors le nombre de couples simultanés et non pas le nombre d accès simultanés autorisés (Port à N places). Un consommateur en attente est bloqué tant qu un producteur n a pas déposé de message et le producteur n est libéré que lorsque le consommateur a retiré le message. La durée de transfert d un message est donc au minimum la somme des temps des attributs Write et Read. La fonction de résolution et sa table de transition (utilisation de l état InactiveReq de poids plus fort que ActiveReq) sont utilisées à profit pour marquer les éléments d un couple. Les primitives Send et Receive décrites en VHDL sont données ci-dessous. PROCEDURE receive( SIGNAL message : INOUT DefPortOut; information : OUT DefInformation; LinkReadTime : IN TIME; priority : IN NATURAL; date : IN TIME; --SIGNAL TaskState : INOUT DefState; RendezVous : IN BOOLEAN) IS VARIABLE TmpPortAccess : DefUPortOut; IF ((TaskState.state/=ExitNow) AND (message.protocol.status/=)) THEN TmpPortAccess.protocol:=DefProtocol'(priority,date,ActiveReq); message<=tmpportaccess; --IF RendezVous THEN BlockingTask(TaskState); -- WAIT UNTIL (message.protocol.status=) OR (TaskState.state=ExitNow) OR (message.protocol.status=taskblocked); IF ((message.protocol.status=taskblocked) AND (TaskState.state/=ExitNow)) THEN --IF NOT(RendezVous) THEN BlockingTask(TaskState); -- WAIT UNTIL (message.protocol.status=) OR (TaskState.state=ExitNow); IF (message.protocol.status=) THEN TmpPortAccess:=message; IF (LinkReadTime/=NullTime) THEN TmpPortAccess.ReadTime:=LinkReadTime; --ingtask(taskstate); IF (TmpPortAccess.ReadTime/=NullTime) THEN Delay(TmpPortAccess.ReadTime)--,TaskState); TmpPortAccess.protocol.status:=InactiveReq; message<=tmpportaccess; WAIT UNTIL message.protocol.status=inactivereq; TmpPortAccess:=message; TmpPortAccess.protocol.status:=InactiveAck; message<=tmpportaccess; WAIT UNTIL message.protocol.status=inactiveack; TmpPortAccess:=message; information:=tmpportaccess.information; ELSE message.protocol.status<=inactiveack; END receive; -- PROCEDURE send(information : IN DefInformation; SIGNAL message : INOUT DefPortIn; LinkWriteTime : IN TIME; priority : IN NATURAL; date : IN TIME; --SIGNAL TaskState : INOUT DefState; M.C.S.E 101
Chapitre 4 RendezVous : IN BOOLEAN) IS VARIABLE TmpPortAccess : DefUPortIn; IF (TaskState.state/=ExitNow) THEN TmpPortAccess.protocol:=DefProtocol'(priority,date,ActiveReq); message<=tmpportaccess; WAIT UNTIL (message.protocol.status=) OR (message.protocol.status=taskblocked) OR (TaskState.state=ExitNow); IF ((message.protocol.status=taskblocked) AND (TaskState.state/=ExitNow)) THEN --BlockingTask(TaskState); WAIT UNTIL (message.protocol.status=) OR (TaskState.state=ExitNow); IF (message.protocol.status=) THEN TmpPortAccess:=message; IF (LinkWriteTime/=NullTime) THEN TmpPortAccess.WriteTime:=LinkWriteTime; --ingtask(taskstate); IF (TmpPortAccess.WriteTime/=NullTime) THEN Delay(TmpPortAccess.WriteTime)--,TaskState); TmpPortAccess.information:=information; TmpPortAccess.protocol.status:=InactiveReq; message<=tmpportaccess; WAIT UNTIL message.protocol.status=inactivereq; --IF RendezVous THEN BlockingTask(TaskState); -- message.protocol.status<=inactiveack; WAIT UNTIL message.protocol.status=inactiveack; --IF RendezVous THEN ingtask(taskstate); -- END send; NOTA: les lignes indiquées en commentaires sont à considérer dans le cas du partage d une ressource limitée pour plusieurs fonctions. -D- Utilisation L emploi des procédures Send et Receive diffère selon qu il s agit d un accès 1->1, N->1 ou N-> M. Dans le premier cas, le signal assurant le protocole est utilisé comme nom du port. Dans le deuxième cas, comme n producteurs ou consommateurs peuvent accéder au même port, le signal assurant le protocole est un vecteur non contraint. L appelant doit alors donner son identité sous la forme de son indice dans le vecteur. La surcharge de procédure permet de disposer que d un seul nom de procédure Send ou Receive mais avec un nombre d arguments différent. Dans le troisième cas, comme les n producteurs peuvent accéder aux m éléments du vecteur de port, le signal assurant le protocole est un vecteur de vecteur. L appelant doit alors donner son identité et l indice du destinataire du message dans le vecteur de port. Comme VHDL ne permet pas de définir un vecteur non contraint d un vecteur non contraint et ne permet pas de définir des paramètres génériques au niveau d un package, la primitive d accès ne peut être défini qu au niveau de l entité. Ceci complique sérieusement la génération du modèle VHDL et sa lisibilité. En effet, la taille des vecteurs sera généralement définie avec un paramètre générique permettant de modifier facilement la dimension et la topologie du système. VHDL ne permet pas aussi de définir des types dynamiques ou record variant sur des signaux. Pour contourner cette limitation, deux solutions sont possibles: 102 M.C.S.E
Transcription du modèle de performance en VHDL - définir un type spécifique pour chaque type d élément de communication (solution (a) de la figure 4.5). Ceci oblige malheureusement à redéfinir les primitives d accès et l entité gérant l élément de relation pour chaque type d élément de relation. Cette solution a donc un impact négatif sur la complexité et le temps de génération du code. - regrouper en un seul record (solution (b) de la figure 4.5) les informations nécessaires (attributs) pour les transferts de tous les types de messages du système. Cette solution facilite la génération de code mais a probablement un impact négatif sur la durée de simulation. Les deux solutions sont expliquées par la figure ci-après. Prod[1:m] Send Port1 Receive Exec Send Port2[1:n] Receive Cons[1:n] Info1 Info2 Solution a TYPE DefInfo1 IS RECORD Size : Integer; Speed: Integer; END RECORD; TYPE DefUPortIn_Info1 IS RECORD Information: DefInfo1; WriteTime: TIME; Protocol: DefProtocol; END RECORD; TYPE DefUPortOut_Info1 IS RECORD Information: DefInfo1; ReadTime: TIME; Protocol: DefProtocol; END RECORD; PROCEDURE Send (Info1: IN DefInfo1; SIGNAL LinkIn: INOUT DefPortIn_Info1; LinkWriteTime: TIME); PROCEDURE Receive ( SIGNAL LinkOut: INOUT DefPortOut_Info1; Info1: OUT DefInfo1; LinkReadTime: TIME); TYPE DefInfo2 IS RECORD Id : Integer; Priority: Integer; END RECORD; TYPE DefUPortOut_Info2 IS RECORD Information: DefInfo2; ReadTime: TIME; Protocol: DefProtocol; END RECORD; TYPE DefUPortIn_Info2 IS RECORD Information: DefInfo2; WriteTime: TIME; Protocol: DefProtocol; END RECORD; PROCEDURE Send (Info2: IN DefInfo2; SIGNAL LinkIn: INOUT DefPortIn_Info2; LinkWriteTime: TIME); PROCEDURE Receive ( SIGNAL LinkOut: INOUT DefPortOut_Info2; Info2: OUT DefInfo2; LinkReadTime: TIME); Solution b Type DefInformation IS RECORD Size : Integer; Speed: Integer; Id : Integer; Priority: Integer; END RECORD; TYPE DefUPortOut IS RECORD Information: DefInformation; ReadTime: TIME; Protocol: DefProtocol; END RECORD; TYPE DefUPortIn IS RECORD Information: DefInformation; WriteTime: TIME; Protocol: DefProtocol; END RECORD; PROCEDURE Send (Info: IN DefInformation; SIGNAL LinkIn: INOUT DefPortIn; LinkWriteTime: TIME); PROCEDURE Receive ( SIGNAL LinkOut: INOUT DefPortOut; Info: OUT DefInformation; LinkReadTime: TIME); -Figure 4.5- Techniques de transfert d information par les procédures Send et Receive. M.C.S.E 103
Chapitre 4 Dans la solution a, un type est déclaré pour chaque type de messages transmis. Les types associés aux informations transmises sont ensuite englobés dans la déclaration d un record regroupant le type de l information, un champ utile pour surcharger les attributs temporels du port et le signal utilisé pour le protocole de communication. La séparation des types nécessite de déclarer une primitive d accès pour chaque type d information. Dans la solution b, tous les types (attributs) associés aux ports de communication du système sont regroupés dans un seul record (DefInformation). Ainsi, la déclaration des types des signaux de connexion entre les éléments de relation et les composants actifs et celle des primitives d accès ne dépendent plus directement du type de l information transmise et sont uniques. Le générateur de code VHDL se contente alors simplement de mettre à jour le contenu du record DefInformation. 4.5.3 Transcription d un événement Une relation de transfert d'information sous-entend une dépendance temporelle avec échange de donnée. Comme une relation de synchronisation (événement, signal) exprime une dépendance temporelle sans échange de donnée, la transcription d une synchronisation est à rapprocher de celle d un transfert d information mais sans le champ information. L attribut Policy permet de choisir plusieurs modes de synchronisation: booléen et donc avec mémorisation, comptage d événement, fugitif et donc sans mémorisation. Cependant contrairement au port, pour les fonctions en attente sur un événement, c est le principe de la diffusion (et non la gestion des accès selon une priorité) qui a été retenu. Ceci signifie par exemple pour un événement du type Counter que la valeur du compteur correspond au nombre d activation des fonctions en attente et non pas au nombre de fonctions en attente activables (l événement du type Counter de MCSE n a pas la même signification que la notion de sémaphore rencontrée dans les exécutifs temps-réels). Pour un événement du type fugace, il n y a exploitation de l événement que s il y a au moins un récepteur de l événement en attente. L implantation en VHDL ne pose aucune difficulté et découle directement de ce qui a été fait pour les ports. Le principe d implantation d un événement est schématisé par la figure 4.6. La figure 4.6-a représente la structure fonctionnelle constituée des fonctions Prod et User reliées par l événement Ev. Les attributs Write et Read sur les liens entre les fonctions et l événement surchargent dynamiquement les attributs Write et Read de Ev. La structure de l implantation en VHDL est décrite par la figure 4.6-b. Les fonctions Prod et User sont implantées sous la forme d une entité dont les entrées/sorties sont composées du signal States (ressource d exécution limitée) et du signal EvIn (respectivement EvOut) pour la synchronisation. Les signaux EvIn et EvOut ne sont composés que du champ Status utilisé pour le protocole de communication en 4 phases. L événement est modélisé par un composant. Les paramètres génériques de ce composant sont les attributs associés habituellement à un événement ( Policy, Write, Read, Concurrency). Le comportement de l entité Ev qui est passive par rapport à la ressource d exécution est décrit par deux automates (figure 4.6-c). Lorsqu un producteur désire émettre un événement, il fait appel à la procédure SignalEv (à gauche de la figure). Cette procédure signale son état actif au port par ActiveReq. Si l événement est en mesure de mémoriser l occurrence d un événement (degré de concurrence non atteint), il répond immédiatement par, sinon la fonction Prod (tâche) passe à l état Blocked et la ressource d exécution devient disponible 104 M.C.S.E
Transcription du modèle de performance en VHDL pour une autre tâche (fonction ou activité). Après acquittement par l événement, la fonction passe alors le temps d écriture nécessaire réalisé par la procédure DELAY. Durant cette attente, la ressource d exécution peut être préemptée par une tâche plus prioritaire. Le protocole se termine ensuite par InactiveReq puis l état de repos InactiveAck qui sert aussi à la fin de la procédure SignalEv. Pour un consommateur la procédure Ev (à droite de la figure) est identique mais avec l indication d une attente d événement par ActiveReq. Read a) b) InStatus[1:m] Ev OutStatus[1:n] Prod[1:m] Write Ev User[1:n] Prod[1:m] SignalEv Policy Write Read Concurrency Ev User[1:n] Policy Write Read Concurrency InStatus[i] EvIn States(Prod[1:m]) OutStatus[i] EvOut States(User[1:n]) SignalEv (Ev) utilisé dans Prod[i] /ActiveReq Taskblocked c) NbUse:=0;Ev=0; ActiveReq and NbUse >= Concurrency TaskBlocked EV ActiveReq and (Ev = 0) and NbUse >= Concurrency TaskBlocked Ev (Ev) utilisé dans User[i] Taskblocked / ActiveReq TaskBlocked Blocked ing Send wait (ActiveReq or TaskBlocked) and NbUse < Concurrency NbUse++; Receive wait (ActiveReq or TaskBlocked) and (Ev>0) and NbUse < Concurrency NbUse++; TaskBlocked Blocked ing DELAY (writetime) end InAccess end OutAccess DELAY (ReadTime) InactiveAck End DELAY InactiveReq InactiveReq NbUse--; *Add(Ev); InactiveAck InactiveReq NbUse--; *Sub(EV); InactiveAck End DELAY InactiveReq InactiveReq InactiveAck *Add(Ev); => si Policy=Counter alors Ev:=Ev+1; si Policy=Boolean alors Ev:=1; si Policy=fugitive alors Ev:=1 si il existe au moins un Users[i] en attente sur l événement -Figure 4.6- Solution pour l implantation d une synchronisation par événement. 4.5.4 Transcription d une variable partagée InactiveAck *Sub(Ev); => Ev:=Ev-1 si Users[i] est le dernier des utilisateurs activés par l événement OutValue La transcription d une variable partagée nécessite de tenir compte du comportement systématique de toute variable (c est-à-dire la gestion cohérente des données) et de tous les attributs qui particularisent son exploitation. Un protocole de communication est aussi utilisé pour le couplage d un élément de relation avec chaque fonction. Notons que le principe de traduction consiste à nouveau à considérer que l élément de relation est un élément passif. -A- Caractéristiques et transcription d un élément partagé L'objet SharVar est une zone de mémorisation ou une ressource commune définie par l attribut Policy, par un grandeur statique définissant sa taille ( Capacity), son degré de partage pour des accès multiples ( Concurrency) et accessoirement par sa valeur ( Value). Trois grandeurs temporelles Write, Read et Use sont aussi à considérer pour son utilisation. M.C.S.E 105
Chapitre 4 L élément partagé est transcrit en VHDL comme une entité instanciée sous la forme de composant. Ses attributs associés sont les paramètres génériques de l entité (attributs statiques) et/ou font partie des entrées/sorties de l entité (attributs dynamiques). -B- Protocole de communication La technique utilisée est similaire à celle employée pour le port. Use Read a) Write b) Writer[1:m] Capacity Policy Concurrency Write Read Use /ActiveReq Reader[1:n] WriteSharVar ( Value, V) utilisé dans Writer[i] Value V Status[i] NbUse:=0;; c) Writer[1:m] WriteSharVar Access SharVar pour une concurrence Status[1:m] Value[1:m] States(Writer[1:m]) V SharVar Policy Concurrency Capacity Write Read Use Status[1:n] Value[1:n] Access ReadSharVar States(Reader[1:n]) Reader[1:n] ReadSharVar (V, Value) utilisé dans Reader[j] Status[j] / ActiveReq Taskblocked ActiveReq and NbUse >= Concurrency TaskBlocked ActiveReq and NbUse >= Concurrency TaskBlocked Taskblocked TaskBlocked Blocked ing Write wait (ActiveReq or TaskBlocked) and NbUse < Concurrency NbUse++; Read wait (ActiveReq or TaskBlocked) and NbUse < Concurrency NbUse++; TaskBlocked Blocked ing DELAY (writetime) end InAccess end OutAccess DELAY (ReadTime) InactiveAck End DELAY InactiveReq InactiveAck Writer[i] est la fonction écrivain de plus forte urgence InactiveReq MValue:=Value; InactiveAck t:=0; UseTime (passive) t>=usetime NbUse--; UseTime (passive) InactiveReq Value:=MValue; InactiveAck t:=0 t>=usetime NbUse--; End DELAY InactiveReq InactiveAck InactiveReq Reader[j] est la fonction lectrice de plus forte urgence -Figure 4.7- Solution pour l implantation d un échange par donnée partagée. Le principe d implantation d une variable partagée est schématisé par la figure 4.7. La figure 4.7-a représente la structure fonctionnelle constituée des fonctions Writer et Reader reliées par la variable V. Les attributs Write, Read et Use sur les liens entre les fonctions et la variable surchargent les attributs Write, Read et Use de V. La structure de l implantation en VHDL est décrite par la figure 4.7-b. La relation est générale puisqu il s agit de coupler m écrivains et n lecteurs sur la même variable. Que ce soit en entrée ou en sortie, le champ Status du signal Access implémente le protocole et le champ Value est le support de la donnée. En effet, comme un lien d accès à une variable partagée peut être bidirectionnel, pour simplifier la description et l implantation, un seul signal sous la forme d un vecteur est utilisé pour l accès. La différenciation - lecture ou écriture - est faite par un champ direction dans la définition de Access (champ direction). Value 106 M.C.S.E
Transcription du modèle de performance en VHDL Très proche de ceux du port à N places ou de l événement, l automate modélisant le comportement (figure 4.7-c) d une variable partagée se distingue cependant par un état supplémentaire UseTime. Cet état représente un temps d utilisation de la variable partagée qui est passif par rapport à la ressource d exécution des fonctions accédant à cette variable. Il correspond par exemple aux temps d accès d un disque modélisé par une variable partagée. Le protocole est modifié dans le cas d une ressource. La figure suivante montre ce protocole. Pour éviter la confusion, les noms des primitives s appellent Alloc et Release. La différence vient du fait que le temps Use n a pas de signification et que la ressource est considérée occupée entre le Alloc et Release. Alloc( V) c) Ressource pour une concurrence Release( V) InValue /ActiveReq NbUse:=0;; / ActiveReq Taskblocked ActiveReq and NbUse >= Concurrency TaskBlocked ActiveReq and NbUse >= Concurrency TaskBlocked Taskblocked TaskBlocked Blocked ing (ActiveReq or TaskBlocked) and NbUse < Concurrency NbUse++; Alloc wait Release wait (ActiveReq or TaskBlocked) and NbUse < Concurrency TaskBlocked Blocked ing DELAY (writetime) end InAccess end OutAccess DELAY (ReadTime) InactiveAck End DELAY InactiveReq InactiveReq InactiveAck InactiveReq NbUse--; InactiveAck End DELAY InactiveReq InactiveReq InactiveAck InactiveAck OutValue -Figure 4.8- Solution pour l implantation d une ressource commune. -C- Implantation La communication entre une fonction et une variable partagée ou une ressource est implantée par un signal DefDataAccess regroupant Status et Value. Le signal est géré par une fonction de résolution décrite ci-dessous. TYPE DefDirection IS (read,write); TYPE DefUDataAccess IS RECORD data : DefBlock; direction : DefDirection; ReadTime : TIME; WriteTime : TIME; UseTime : TIME; protocol : DefProtocol; END RECORD; TYPE DefUDataAccessVector IS ARRAY (NATURAL RANGE <>) OF DefUDataAccess; FUNCTION ResolProtocol (Input: DefUDataAccessVector) return DefUDataAccess; SUBTYPE DefDataAccess IS ResolProtocol DefUDataAccess; TYPE DefDataAccessVector IS ARRAY (NATURAL RANGE <>) OF DefDataAccess; TYPE DefDataPolicy IS (DataFifo,DataPriority, ResourceFifo,ResourcePriority); M.C.S.E 107
Chapitre 4 L implantation VHDL pour une variable partagée pose le problème de la transcription des temps UseTime (état UseTime) et de la décrémentation de la variable NbUse après ce temps. En effet, comme la concurrence peut-être multiple, il ne faut pas que l attente sur UseTime bloque le process (l instruction For est donc à proscrire). L instruction After n est également pas utilisable puisqu à chaque nouvelle affection toutes les modifications ayant une date d occurrence supérieure à celle de l affectation en cours sont perdues. Nous avons utilisé une fifo où l on mémorise par ordre croissant la date de la prochaine décrémentation de NbUse et le process est asservi sur une modification des protocoles des liens sur la variable et sur la prochaine décrémentation de NbUse. Comme les actions ne se font que sur transition au lieu d utiliser une variable d état pour transcrire les automates, nous avons simplement utilisé l instruction IfElseEnd If en réduisant les automates à deux états. L implantation VHDL d une ressource commune est plus simple si l on associe à chaque lien sur la ressource un booléen pour savoir s il y a déjà une allocation de la ressource avec ce lien: ceci permet d avoir une approche en ne considérant que les liens sur la ressource. 4.5.5 Bilan sur la transcription du modèle structurel La partie délicate de la transcription a concerné la prise en compte d un processeur logiciel qui conduit à restreindre le degré de parallélisme des fonctions qu il supporte. Comme VHDL ne dispose pas de mécanisme de suspension de process, nous avons dû décrire explicitement un composant ordonnanceur. Cet ordonnanceur est chargé de gérer les différentes tâches (fonctions) allouées au processeur en fonction de la politique d ordonnancement choisie (attribut Policy) et des priorités respectives de tâches (attribut Priority). Le signal State mémorisant l état d une tâche est modifié à la fois par la tâche et l ordonnanceur. La valeur courante de ce signal est donc gérée par une fonction de résolution basée sur une table de transition. De plus, pour que tous les temps d exécution n évoluent que durant l état "Active" de la tâche concernée, ils sont tous simulés avec une procédure spécifique (procédure DELAY) qui permet ainsi de gérer un point de préemption par la ressource d exécution. Une fonction est transcrite sous la forme d une entité ou d un block, ce qui permet de respecter la hiérarchie du modèle MCSE et de garder la trace des entrées/sorties (port map) et la généricité (generic map). Le block ne permet pas de traduire la notion de réplication/modèle de fonctions, mais il offre, contrairement aux entités, la possibilité d accéder à des variables globales (Shared Variable de VHDL 93) utiles par exemple pour le partage d un générateur de nombres aléatoires. Un élément de relation est transcrit par une entité dont les paramètres génériques correspondent aux attributs de l élément de relation. Cette entité est instanciée sous la forme d un composant et les attributs définis à ce stade sont statiques. L entité gérant l élément de relation est passive par rapport à la ressource d exécution car les temps d accès à l élément de relation sont simulés du coté producteur/consommateur. Ainsi, elle n a pas besoin de tenir compte de l état (active, inactive, bloquée ou en attente) de la fonction (tâche) productrice ou consommatrice de l information échangée. Le couplage entre une fonction et un élément de relation est effectué avec un protocole de communication en 4 phases implanté sous la forme d un signal bidirectionnel et d une fonction de résolution. Ce protocole de communication permet de faire de la communication point à point ou de la diffusion. Il ne limite donc pas les possibilités de topologie d un système. Il permet également de surcharger dynamiquement les attributs (temps d accès en lecture et 108 M.C.S.E
Transcription du modèle de performance en VHDL écriture) de l élément de relation. Cette possibilité de surcharge est utilisée pour tenir compte du coût de la communication inter-processeurs ou par exemple pour faire varier les temps d accès en fonction de la longueur des messages transmis. Du coté fonction, le protocole de communication est implanté sous forme de procédures (primitives d accès). Le manque de généricité pour la déclaration des types VHDL est alors une limitation sérieuse. Pour faciliter la génération du modèle VHDL et sa lisibilité, nous avons décidé de regrouper tous les types d éléments de relation dans un seul record. Une autre solution consistait à définir tous les types séparément et à déclarer autant de primitives d accès aux éléments de relation (surcharge de procédures). 4.6 TRANSCRIPTION DU MODELE COMPORTEMENTAL Le comportement de chaque fonction est modélisé comme un ensemble de process synchronisés et coopérants. La simultanéité et les instances multiples sont possibles. Les règles de transcription sont relativement similaires à celles utilisées pour la transcription du SpecChart en VHDL [GAJSKI-93]. Quand une fonction ou une activité est séquentielle, il s agit d une tâche pour la ressource d exécution et ainsi elle se traduit en un process VHDL. Dans le cas de la simultanéité, un process est associé pour chaque partie séquentielle. Des éléments de synchronisation sont alors ajoutés. La transcription doit aussi satisfaire les particularités de l activation conditionnelle et de l achèvement forcé. En plus, les conditions d activation peuvent être composées (Ordre strict, Et sans ordre, l un, sélection). Il en est de même pour les actions en sortie d opérations et d activités. Ce paragraphe décrit les solutions de transcription retenues pour ces problèmes. Nous commençons tout d abord par le cas du modèle séquentiel. Les paramètres et attributs de chaque fonction, activité, opération sont des paramètres génériques des blocks et des entités. La procédure DELAY est à nouveau utilisée pour la simulation de tous les temps d exécution. 4.6.1 Transcription d un modèle de comportement séquentiel La transcription d un modèle de comportement séquentiel ne pose pas de problème particulier. Un process est utilisé pour cela. Si ce modèle est la description d une fonction, alors le process est encapsulé dans une entité ou dans un block. La figure 4.9 donne un exemple de transcription sous la forme d un block. Le choix du block se justifie par l emploi de la variable partagée rnd au niveau du tirage aléatoire de l alternative. Chaque opération est remplacée par la procédure DELAY qui simule le temps d exécution. Cette procédure prend en compte la grandeur State (ici SupervisionState) pour connaître l état actif de la ressource d exécution (champ TaskState) et la puissance de cette ressource (champ Power) (voir le modèle de simulation présenté dans le paragraphe 4.3). Cette transcription répond aux cas de constructions: séquence, alternative, répétition. On remarque aussi sur l exemple la condition d évolution sur la réception de Cmd ce qui se traduit par l appel de la procédure Receive, et les actions de transmission des messages OrderRec et OrderRead[:] traduites par la procédure Send. Pour le dernier cas, la fonction de sélection du destinataire est implantée très simplement par un argument de plus dans l appel de Send et qui indique l indice du port concerné (ici CmdUser.Id). Ceci se justifie par le fait qu en VHDL, on ne peut pas écrire Send(CmdUser, OrderRead(CmdUser.Id), SupervisionState) car l indice d un vecteur lors d un appel procédural doit être une expression statique. M.C.S.E 109
Chapitre 4 * Supervision Cmd OpRead Time = 1 ms; OpRec Time = 1 ms; Proba OR Else OpRec OpRead Path= Id; OrderRec S OrderRead[:] Size=Cmd Size; Speed=Cmd Speed; Id=Cmd Id; Size=Cmd Size; Speed=Cmd Speed; Supervision : BLOCK PORT (Cmd : INOUT DefPortOut; OrderRec : INOUT DefPortIn; OrderRead : INOUT DefPortInVector(1 TO n); SupervisionState : INOUT DefState); PORT MAP (Cmd=>Cmd, OrderRec=>SupervisionOrderRec, OrderRead=>SupervisionOrderRead, SupervisionState=>SupervisionState); SupervisionBehavior : PROCESS VARIABLE j : INTEGER; VARIABLE CmdUser : DefCmdUser; LOOP receive(cmd,cmduser,supervisionstate); Uniform(rnd); IF rnd <= Proba THEN Delay(OpRecTime,SupervisionState); send(cmduser,orderrec,supervisionstate); ELSE Delay(OpReadTime,SupervisionState); send(cmduser,orderread,cmduser.id,supervisionstate); END LOOP; END PROCESS SupervisionBehavior; END BLOCK Supervision; -Figure 4.9- Ecriture d un modèle comportemental séquentiel. 4.6.2 Transcription pour un parallélisme Il s agit de transcrire les 2 situations représentées par la figure 4.10. La transcription systématique consiste à considérer que le modèle active 2 ou plus de 2 process sur la divergence ET et se met en attente d achèvement de tous ces process pour assurer la convergence ET. La divergence ET est un Fork, la convergence ET est un Join. Un protocole basé sur une variable à trois états est utilisé pour les synchronisations. Il est implanté par une fonction de résolution et les procédures Fork, Fork, Join et Join. 110 M.C.S.E
Transcription du modèle de performance en VHDL La description est donnée pour l exemple de gauche. Simultanéité & Parallélisme multiple & Op1 Op2 Op Op1 Op2 Op[1:n] OP: PROCESS..;. Fork(OpStatus); BlockingTask(OpState); Join(OpStatus); ingtask(opstate).; END PROCESS Op; Op1: PROCESS..; InactiveTask(Op1State); LOOP Fork(OpStatus); ingtask(op1state);..; InactiveTask(Op1State); Join(OpStatus); END LOOP; END PROCESS Op1; -Figure 4.10- Représentation pour un parallélisme et transcription. Sur l exemple de gauche, le processus père OP indique le début de l activité parallèle par la primitive Fork et libère la ressource d exécution (BlockingTask). Tous les process (Op1 et Op2) associés aux branches parallèles qui étaient en attente de la synchronisation (Fork) se mettent alors en attente du processeur (ingtask). Le plus prioritaire s exécute puis indique sa complétude par les primitives InactiveTask et Join. Lorsque toutes les branches parallèles ont été exécutées, le processus père reprend la main (primitive Join et ingtask). Pour l exemple de droite, tous les process OP[i] sont instanciés par une boucle (instruction Generate) avec mise en attente sur le signal OpStatus. Fork active tous les process et Join attend que tous les process soient achevés. L implantation du protocole est donné ci-après. FUNCTION ResolForkJoin (Input : STD_ULOGIC_VECTOR) RETURN STD_ULOGIC; SUBTYPE DefForkJoinStatus IS ResolForkJoin STD_ULOGIC; TYPE DefForkJoinStatusVector IS ARRAY (NATURAL RANGE <>) OF DefForkJoinStatus; -- fonction de resolution pour l'implantation d'un Fork ou d'un Join FUNCTION ResolForkJoin (Input : STD_ULOGIC_VECTOR) RETURN STD_ULOGIC IS VARIABLE i : INTEGER; VARIABLE result : STD_ULOGIC; -- pour un fork il y a synchronisation des activations de toutes les branches -- pour un Join toutes les branches doivent indiquer leur fin d'execution result := Input(input'LOW); IF (Input'LENGTH>1) THEN FOR i IN Input'LOW+1 TO Input'HIGH LOOP IF result/=input(i) THEN -- tous les elements du vecteur ne sont pas identiques result:='z'; EXIT; END LOOP; RETURN result; END ResolForkJoin; M.C.S.E 111
Chapitre 4 FUNCTION InitForkJoinStatus RETURN DefForkJoinStatus IS RETURN '0'; END; -- PROCEDURE Fork(SIGNAL ForkStatus : INOUT DefForkJoinStatus) IS ForkStatus<='1'; WAIT UNTIL ForkStatus='1'; END Fork; -- PROCEDURE Fork(SIGNAL ForkStatus : INOUT DefForkJoinStatus) IS ForkStatus<='1'; WAIT UNTIL ForkStatus='1'; END Fork; -- PROCEDURE Join(SIGNAL JoinStatus : INOUT DefForkJoinStatus) IS JoinStatus<='0'; WAIT UNTIL JoinStatus='0'; END Join; -- PROCEDURE Join(SIGNAL JoinStatus : INOUT DefForkJoinStatus) IS JoinStatus<='0'; WAIT UNTIL JoinStatus='0'; END Join; 4.6.3 Transcription d une activité raffinée Pour conserver la lisibilité, la transcription d une activité raffinée se fera de la même manière que pour le parallélisme. L activité est décrite comme un process qui sera activé par un Fork. Lorsqu une activité est générique et donc déclarée comme une partie autonome instanciable dans d autres comportements, l activité est alors décrite comme un block avec ses arguments d entrée et de sortie définissant son lien avec son environnement. 4.6.4 Transcription pour l activation conditionnelle Il s agit de permettre l exécution d une séquence d opérations ou activités parmi un ensemble dépendante d une condition d activation. La figure ci-après donne une exemple caractéristique. Op ConditionalActivation E1 E2 Op&[(?E1&A1) (?E2&A2)] ou Op&[?E1&A1?E2&A2] A1 A2 -Figure 4.11- Représentation d une évolution alternative. 112 M.C.S.E
Transcription du modèle de performance en VHDL Après l opération Op, il y a mise en attente sur les 2 conditions E1 et E2. La première satisfaite implique l exécution de l opération associée. L attente doit alors être supprimée sur l autre branche. La traduction utilise à nouveau le protocole en 4 phases pour l attente sur un port, une variable partagée ou un événement. Chaque attente est signalée par ActiveReq; c est l objectif de la procédure InitConditionalActivation. Une fonction procédure ConditionalActivation est utilisée pour l attente multiple. L argument de sortie BranchNumber sert à s orienter vers l exécution de la branche rendue active. Les différentes séquences sont décrites comme branches d un case. Un reset est nécessaire pour annuler les demandes d attente; c est le rôle de la procédure ResetConditionalActivation. La description d un exemple est donnée ci-après. Il faut noter une difficulté rencontrée avec VHDL ou avec le simulateur ModelTech qui nous a contraint d utiliser une instruction d assignation concurrente. En effet le simulateur n est pas capable de faire correctement le lien entre les paramètres formels et les signaux concernés lors d un appel procédural si les signaux concernés ont plusieurs niveaux d imbrication de records. Sans cette difficulté, on aurait pu regrouper les procédures InitConditionalActivation, ConditionalActivation et ResetConditionalActivation en une seule procédure. Le programme ci-dessous est la traduction de l attente conditionnelle utilisée dans la description du comportement de la fonction SupervisonUsager de l exemple du serveur vidéo présenté dans le chapitre 7. Pour la compréhension, le comportement est modélisé par la figure 7.3. TYPE DefProtocol IS RECORD priority : NATURAL; date : TIME; status : DefHandshake; END RECORD; TYPE DefProtocolVector IS ARRAY (NATURAL RANGE <>) OF DefProtocol; ------------------------------------------------------------------ SIGNAL ProtocolVector : DefProtocolVector(1 TO 2); -- assignation concurrente pour l'attente conditionnelle ProtocolVector<=CmdUsager.protocol&RepCanal.protocol; SupervisionUsagerBhv : PROCESS VARIABLE CmdUser : DefCmdUser; VARIABLE rep : DefRepCanal; VARIABLE BranchNumber : NATURAL; ingtask(state); LOOP InitConditionalActivation(CmdUsager.protocol,1,now); InitConditionalActivation(RepCanal.protocol,1,now); ConditionalActivation(ProtocolVector, BranchNumber, state); ResetConditionalActivation(CmdUsager.protocol); ResetConditionalActivation(RepCanal.protocol); CASE BranchNumber IS WHEN 1 => Receive(CmdUsager,CmdUser,State);.; WHEN 2 => Receive(RepCanal,rep,state);.; WHEN OTHERS => REPORT "Chercher la bug" SEVERITY FAILURE; END CASE; END LOOP; END PROCESS SupervisionUsagerBhv; M.C.S.E 113
Chapitre 4 Les procédures sont décrites ci-après. PROCEDURE InitConditionalActivation(SIGNAL protocol : INOUT DefProtocol; priority : IN NATURAL; date : IN TIME) IS protocol<=defprotocol'(priority,date,activereq); END InitConditionalActivation; -- PROCEDURE ConditionalActivation(SIGNAL ProtocolVector:IN DefProtocolVector; BranchNumber : OUT NATURAL; SIGNAL TaskState : INOUT DefState) IS VARIABLE i : INTEGER; VARIABLE activation,taskblocking : BOOLEAN := FALSE; activation:=false; WHILE NOT(activation) AND (TaskState.state/=ExitNow) LOOP TaskBlocking:=TRUE; FOR i IN ProtocolVector'RANGE LOOP activation:=activation OR (ProtocolVector(i).status=); TaskBlocking:=TaskBlocking AND (ProtocolVector(i).status=TaskBlocked); IF activation THEN BranchNumber:=i; EXIT; END LOOP; IF NOT(activation) THEN IF (TaskBlocking AND (TaskState.state/=Blocked)) THEN BlockingTask(TaskState);--procedure blocante; WAIT UNTIL (ProtocolVector'EVENT) OR (TaskState.state=ExitNow); END LOOP; END ConditionnalActivation; PROCEDURE ResetConditionnalActivation(SIGNAL Protocol:INOUT DefProtocol) IS Protocol<=InitProtocol; END ResetConditionnalActivation; Les primitives d accès aux éléments de relation doivent maintenant tenir compte du fait que le protocole en 4 phases peut être déjà commencé avant l appel procédural. 4.6.5 Achèvement forcé d activités L achèvement forcé d une activité ou opération permet de modéliser certaines circonstances particulières telles que des durées maximale d exécution, l apparition d exceptions, etc. Le problème de la transcription d un achèvement forcé d activités (symbol Exit) est à rapprocher de celui de la transcription des EI Arcs (Exit Immediatly) d un SpecChart: Il faut avoir la possibilité de terminer l exécution d un process immédiatement. Pour cela, comme l instruction "goto" n existe pas en VHDL, une solution consiste à englober le code dans une boucle et on utilise la construction VHDL Exit pour sortir de cette boucle. 114 M.C.S.E
Transcription du modèle de performance en VHDL La figure 4.12 représente un exemple d achèvement forcé d activité et son principe de transcription. a) Exemple d activité b) solution d implantation Op1 A1 A1State Stop Op2 A11 (A10) A11State Process A1 A1Status A10 & Block A11 A12 Lt:DefLt Op3 Cmd TaskKiller A111State Process A11 A11Status A112State Op4 Op5 Process A111 Process A112 A111 A112 -Figure 4.12- Raffinement d une activité avec achèvement forcé, principe de transcription. Par rapport au SpecChart, comme notre modèle est non-interprété, il n est pas nécessaire d ajouter une boucle supplémentaire puisqu en modifiant la procédure Delay, on peut terminer l exécution d une activité en temps nul. La nouvelle procédure Delay est donc: PROCEDURE Delay( CONSTANT Time : IN TIME; SIGNAL TaskState : IN DefState) IS VARIABLE GlobalTime,RemainTime: TIME := NullTime; GlobalTime:=now; IF (TaskState.power/=0.0) THEN RemainTime:=Time/TaskState.power; ELSE RemainTime:=Time; LOOP IF (TaskState.state=Active) THEN WAIT UNTIL (TaskState.state/=Active) FOR RemainTime; IF ((TaskState.state=Active) OR (TaskState.state=ExitNow)) THEN exit; ELSE RemainTime:=RemainTime-(now-GlobalTime); WAIT UNTIL (TaskState.state=Active); GlobalTime:=now; END LOOP; END Delay; Le fait d avoir placé la gestion des temps concernant l accès à un élément de relation au niveau des primitives et non de l entité gérant la relation est ici un avantage indiscutable. M.C.S.E 115
Chapitre 4 Nous sommes aussi obligés de rajouter l état ActivityState=ExitNow (et non pas utiliser l état ActivityState=Inactive) pour pouvoir sortir de l état ActivityState=ing lors d une fin d activité forcée. Début exécution Ressource préemptée Condition satisfaite Ressource allouée Inactive Blocked ing end Active Exit attente condition Fin exécution Fin exécution Exit Exit ExitNow -Figure 4.13- Etats d une fonction et conditions de transition pour la condition Exit. Les déclarations concernant l état d une activité sont donc modifiées de la manière suivante: TYPE DefUTaskState IS (Nodriver,Inactive,Blocked,ing,Active,ExitNow); TYPE DefUTaskStateTable IS ARRAY(DefUTaskState,DefUTaskState) OF DefUTaskState; CONSTANT ResolutionTaskState : DefUTaskStateTable :=( -- ----------- ---------- ----------- --------- --------- ---------- -- Nodriver Inactive Blocked ing Active ExitNow -- ----------- ---------- ----------- --------- --------- ---------- ( Nodriver, Inactive, Blocked, ing, Active, ExitNow), -- Nodriver ( Inactive, Inactive, Inactive, ing, Inactive, Inactive), -- Inactive ( Blocked, Inactive, Blocked, ing, Blocked, ExitNow), -- Blocked ( ing, ing, ing, ing, Active, ExitNow), -- ing ( ExitNow, Inactive, ExitNow, ExitNow, ExitNow, ExitNow) -- ExitNow ); TYPE DefUState IS RECORD state : DefUTaskState; priority : NATURAL; deadline : TIME; power : REAL; END RECORD; TYPE DefUStateVector IS ARRAY (NATURAL RANGE <>) OF DefUState; FUNCTION ResolState (Input : DefUStateVector) RETURN DefUState; SUBTYPE DefState IS ResolState DefUState; TYPE DefStateVector IS ARRAY (NATURAL RANGE <>) OF DefState; TYPE DefUTaskStateVector IS ARRAY (NATURAL RANGE<>) OF DefUTaskState; FUNCTION ResolTaskState (Input : DefUTaslStateVector) RETURN DefUTaskState; SUBTYPE DefTaskState IS ResolTaskState DefUTaskState; TYPE DefTaskStateVector IS ARRAY (NATURAL RANGE <>) OF DefTaskState; Evidemment, si une activité est désactivée et que l on continue l exécution de son code même en temps nul, il ne faut pas exécuter des actions sur les éléments de relations. Les primitives gérant les éléments de relation devront donc être aussi modifiées pour tenir compte de l état ActivityState=ExitNow. 116 M.C.S.E
Transcription du modèle de performance en VHDL Cependant, pour un élément de relation, si le protocole en 4 phases a déjà été commencé, il est préférable de terminer l accès à cet élément avant de terminer l exécution du code de l activité pour ne pas perdre un degré de concurrence. Dans ce cas on générera une action mais en temps nul. En supposant dans l exemple de la figure 4.12 que Cmd est un événement et que l activité A11 est implantée sur un processeur, la nouvelle primitive SignalEv est: PROCEDURE SignalEv( SIGNAL eve : INOUT DefSignalIn; LinkWriteTime : IN TIME; priority : IN INTEGER; date : IN TIME; SIGNAL TaskState : INOUT DefState) IS VARIABLE TmpEve : DefUSignalIn; IF (TaskState.state/=ExitNow) THEN eve<=defusignalin'(nulltime,defprotocol'(priority,date,activereq)); WAIT UNTIL (eve.protocol.status=) OR (TaskState.state=ExitNow) OR (eve.protocol.status=taskblocked); IF ((eve.protocol.status=taskblocked) AND (TaskState.state/=ExitNow)) THEN --BlockingTask(TaskState); WAIT UNTIL (eve.protocol.status=) OR (TaskState.state=ExitNow); IF (eve.protocol.status=) THEN TmpEve:=eve; IF (LinkWriteTime/=NullTime) THEN TmpEve.WriteTime:=LinkWriteTime; --ingtask(taskstate); IF (TmpEve.WriteTime/=NullTime) THEN Delay(TmpEve.WriteTime);--,TaskState); TmpEve.protocol.status:=InactiveReq; eve<=tmpeve; WAIT UNTIL eve.protocol.status=inactivereq; eve.protocol.status<=inactiveack; END SignalEv; Si l activité est implantée sur un processeur, il nous faut enfin également modifier les primitives BlockingTask et ingtask pour ne pas rester bloqué dans ces primitives lors d une fin d exécution forcée. Les nouvelles procédures sont les suivantes: PROCEDURE BlockingTask(SIGNAL TaskState : INOUT DefState) IS VARIABLE TmpTaskState : DefUState; IF (TaskState.state=ing) THEN -- attente du C.P.U. ou d'une fin d'execution forcee WAIT UNTIL (TaskState.state=Active) OR (TaskState.state=ExitNow); IF (TaskState.state=Active) OR (TaskState.state=Nodriver) THEN TmpTaskState:=TaskState; IF TmpTaskState.priority=NATURAL'LOW THEN TmpTaskState.priority:=1; TmpTaskState.state:=Blocked; TaskState<=TmpTaskState; WAIT UNTIL (TaskState.state=Blocked) OR (TaskState.state=ExitNow); TmpTaskState:=TaskState; IF TmpTaskState.priority=NATURAL'LOW THEN TmpTaskState.priority:=1; M.C.S.E 117
Chapitre 4 TmpTaskState.state:=Nodriver; TaskState<=TmpTaskState; END BlockingTask; PROCEDURE ingtask(signal TaskState : INOUT DefState) IS VARIABLE TmpTaskState : DefUState; IF ((TaskState.state/=Active) AND (TaskState.state/=ExitNow)) THEN IF (TaskState.state/=ing) THEN TmpTaskState:=TaskState; TmpTaskState.state:=ing; IF TmpTaskState.priority=NATURAL'LOW THEN TmpTaskState.priority:=1; TaskState<=TmpTaskState; WAIT UNTIL (TaskState.state=ing) OR (TaskState.state=ExitNow); TmpTaskState:=TaskState; IF TmpTaskState.priority=NATURAL'LOW THEN TmpTaskState.priority:=1; TmpTaskState.state:=Nodriver; TaskState<=TmpTaskState; -- attente du C.P.U. ou d'une fin d'execution forcee WAIT UNTIL (TaskState.state=Active) OR (TaskState.state=ExitNow); END ingtask; Si l activité A11 n est pas implantée sur un processeur, alors la primitive Delay est: PROCEDURE Delay (CONSTANT Time : IN TIME; SIGNAL TaskState : IN DefTaskState) IS IF (TaskState/=ExitNow) THEN WAIT UNTIL (TaskState=ExitNow) FOR Time; END Delay; Les règles de transcription précédentes permettent relativement aisément l écriture du modèle VHDL. La partie délicate est l implantation du carré noir qui implique la fin immédiate de l activité. L exemple se transcrit sous la forme de 2 blocks et de 5 process (figure 4.12-b). Les variables State de chaque process sont utilisées pour, d une part activer les process A1, A11, A111, A112, d autre part pour observer l état de fin (Exit) correspondant à l un des carrés ce qui entraîne la fin de A1, l arrêt de tous les process fils c est-à-dire A11, A112 et A111 (s obtient par State=ExitNow) et le retour en position initiale de tous les process pour la prochaine activation. Les variables Status sont utilisées pour synchroniser les différentes branches d un parallélisme. Il est bon de noter qu une condition d achèvement se traduit implicitement par un parallélisme où une branche est en attente de la condition d arrêt et l autre branche exécute l activité avec achèvement forcé. La procédure concurrente TaskKiller a la charge de désactiver tous les process d une activité en fonction de l état de l activité mère. PROCEDURE TaskKiller (SIGNAL MotherTaskState : INOUT DefState; SIGNAL TaskStateVector : INOUT DefStateVector) IS VARIABLE i : NATURAL; LOOP WAIT UNTIL MotherTaskState EVENT; IF (MotherTaskState.state=ExitNow) THEN 118 M.C.S.E
Transcription du modèle de performance en VHDL FOR i IN TaskStateVector RANGE LOOP KillingTask(TaskStateVector(i)); END LOOP; END LOOP; END TaskKiller; Elle utilise pour cela la primitive KillingTask décrite ci-dessous. PROCEDURE KillingTask (SIGNAL TaskState : INOUT DefState) IS VARIABLE TmpState : DefUState; TmpState:=TaskState; TmpState.state:=ExitNow; TaskState<=TmpState; WAIT UNTIL (TaskState.state=ExitNow) OR (TaskState.state=Inactive); TaskState.state<=NoDriver; END KillingTask; La transcription en VHDL de l exemple est alors la suivante: library VideoServerLibrary; use VideoServerLibrary.VideoServerDeclaration.all; ENTITY ProblemExit IS END ProblemExit; ARCHITECTURE behavioral OF ProblemExit IS FOR all : EveObject use entity VideoServerLibrary.EveObject(behavioral); SIGNAL StopIn,CmdIn : DefSignalIn; SIGNAL StopOut,CmdOut : DefSignalOut; Stop : EveObject GENERIC MAP (NbUsersInput=>1,NbUsersOutput=>1, policy=>booleen,concurrency=>1, InitValueSema=>0,WriteTime=>NullTime, ReadTime=>NullTime) PORT MAP (InputAccesses(1)=>StopIn, OutputAccesses(1)=>StopOut); Cmd : EveObject GENERIC MAP (NbUsersInput=>1,NbUsersOutput=>1, policy=>booleen,concurrency=>1, InitValueSema=>0,WriteTime=>NullTime, ReadTime=>NullTime) PORT MAP (InputAccesses(1)=>CmdIn, OutputAccesses(1)=>CmdOut); source : BLOCK PORT (Stop : INOUT DefSignalIn); PORT MAP (Stop=>StopIn); SourceBehavior : PROCESS CONSTANT TSourceTime : TIME := 2 ms; LOOP Delay(TSourceTime); SignalEv(Stop,NullTime); END LOOP; END PROCESS SourceBehavior; END BLOCK source; destination : BLOCK PORT (Cmd : INOUT DefSignalOut); PORT MAP (Cmd=>CmdOut); DestinationBehavior : PROCESS CONSTANT TDestinationTime : TIME := 2 ms; LOOP Ev(Cmd,NullTime); Delay(TDestinationTime); END LOOP; M.C.S.E 119
Chapitre 4 END PROCESS DestinationBehavior; END BLOCK destination; ExitExample : BLOCK PORT (Stop : INOUT DefSignalOut; Cmd : INOUT DefSignalIn); PORT MAP (Stop=>StopOut, Cmd=>CmdIn); Signal A1State : DefTaskState; A1 : BLOCK PORT(Stop : INOUT DefSignalOut; A1State : INOUT DefTaskState); PORT MAP(Stop=>Stop, A1State=>A1State); SIGNAL A1Status : DefForkJoinStatus := InitForkJoinStatus; SIGNAL A11State : DefTaskState; CONSTANT A111Time : TIME := 10 ms; CONSTANT Op1Time : TIME :=1 ms; CONSTANT Op2Time : TIME := 2 ms; CONSTANT Op3Time : TIME := 3 ms; CONSTANT Op4Time : TIME := 1 ms; CONSTANT Op5Time : TIME := 2 ms; -- procedure concurrente ReleaseSignaldriver(TaskStateVector(1)=>A1State, TaskStateVector(2)=>A11State); A1Behavior : PROCESS InactiveTask(A1State); LOOP ingtask(a1state); Delay(Op1Time,A1State); Fork(A1Status); Ev(Stop,NullTime,A1State); KillingTask(A1State); KillingTask(A11State); Join(A1Status); InactiveTasK(A1State); END LOOP; END PROCESS A1Behavior; A11 : BLOCK PORT(Cmd : INOUT DefSignalIn; A1Status : INOUT DefForkJoinStatus; A11State : INOUT DefTaskState); PORT MAP(Cmd=>Cmd, A1Status=>A1Status, A11State=>A11State); SIGNAL A11Status : DefForkJoinStatus := InitForkJoinStatus; SIGNAL LtIn : DefSignalIn; SIGNAL LtOut : DefSignalOut; SIGNAL A111State,A112State : DefTaskState; ReleaseSignaldriver(TaskStateVector(1)=>A11State, TaskStateVector(2)=>A111State TaskStateVector(3)=>A112State); TaskKiller(MotherTaskState=>A11State, TaskStateVector(1)=>A111State, TaskStateVector(2)=>A112State); Lt : EveObject GENERIC MAP (NbUsersInput=>1,NbUsersOutput=>1, policy=>booleen,concurrency=>1, InitValueSema=>0,WriteTime=>NullTime, ReadTime=>NullTime) PORT MAP (InputAccesses(1)=>LtIn, OutputAccesses(1)=>LtOut); A11Behavior : PROCESS InactiveTask(A11State); 120 M.C.S.E
Transcription du modèle de performance en VHDL LOOP Fork(A1Status); ingtask(a11state); Delay(Op2Time,A11State); IF (A11State/=ExitNow) THEN Fork(A11Status); Join(A11Status); InactiveTask(A11State); Join(A1Status); END LOOP; END PROCESS A11Behavior; A111Behavior: PROCESS InactiveTask(A111State); LOOP Fork(A11Status); ingtask(a111state); Delay(A111Time,A111State); SignalEv(LtIn,NullTime,A111State); Delay(Op4Time,A111State); InactiveTask(A111State); Join(A11Status); END LOOP; END PROCESS A111Behavior; A112Behavior: PROCESS InactiveTask(A112State); LOOP Fork(A11Status); ingtask(a112state); Delay(Op3Time,A112State); SignalEv(CmdIn,NullTime,A112State); Ev(LtOut,NullTime,A112State); Delay(Op5Time,A112State); InactiveTask(A112State); Join(A11Status); END LOOP; END PROCESS A112Behavior; END BLOCK A11; END BLOCK A1; END BLOCK ExitExample; END Behavioral; 4.6.6 Transcription des conditions d activation Des conditions composées ont été prévues dans le modèle de performance pour le contrôle du comportement d une fonction ou d une activité. La figure 4.14 rappelle les possibilités et indique les solutions de transcription retenues. L ordre strict est simple puisqu il suffit de mettre en séquence les diverses attentes (figure 4.14-a). L ordre ET implique une simultanéité d attente de toutes les conditions (figure 4.14-b), la poursuite se faisant lorsqu elles sont toutes satisfaites. On utilise pour cela la technique de l activation multiple déjà vue dans le paragraphe 4.6.2. L attente OU est identique à une attente conditionnelle multiple (figure 4.14-c). On utilise donc cette technique sachant qu une seule séquence est exécutable après. La Sélection (figure 4.14-d) ne pose pas de difficultés car il s agit d indiquer l indice (attribut Path) de l entrée sélectionnée dans le vecteur. M.C.S.E 121
Chapitre 4 E1 E2 Ordre strict ET sans ordre L un Sélection E1 E1 Pt[1:n] & ^ OR S E2 E2 Op1&?(E1&E2)&A1 Op1&?(E1^E2)&A1 Op1&?(E1 E2)&A1 Op1&?$Pt[:]&A1 a) b) c) d) E1 E1 & E2 Idem à b) mais en utilisant la technique de l attente conditionnelle multiple Sélection par l indice dans le vecteur E2 a) OP: PROCESS..; Ev(E1,OpState); Ev(E2,OpState);.; END PROCESS OP; b) OP: PROCESS..;. BlockingTask(OpState); Fork(OpStatus); Join(OpStatus); ingtask(opstate).; END PROCESS OP; E1AndWithoutOrder: PROCESS InactiveTask(E1AndWithoutOrderState); LOOP Fork(OpStatus); ingtask(e1andwithoutorderstate); Ev(E1,E1AndWithoutOrderState); InactiveTask(E1AndWithoutOrderState); Join(OpStatus); END LOOP; END PROCESS E1AndWithoutOrder; -Figure 4.14- Les conditions et leur principe de transcription. 4.6.7 Transcription des actions La transcription des actions multiples est la duale de celle des conditions et ne pose pas de difficultés particulières. Seul le cas de la simultanéité diffère et nécessite l activation de process synchronisés par les méthodes Fork/Join (figure 4.15-b). Séquence & Op&!(S1&S2) S1 S2 Simultanéité S1 ^ S2 Op&!(S1^S2) c) OP: PROCESS..; InitConditionalActivation(E1.protocol,1,now); InitConditionalActivation(E2.protocol,1,now); ConditionalActivation(ProtocolVector, BranchNumber, state); ResetConditionalActivation(E1.protocol); ResetConditionalActivation(E2.protocol); CASE BranchNumber IS WHEN 1 => Ev(E1,state);.; WHEN 2 => Ev(E2,state);.; END CASE;.; END PROCESS OP; Alternative S1 OR S2 Op&!(S1 S2) Path Sélection Pt(1:n) S Op&!$Pt[:] a) b) c) d) S1 S2 & S1 S2 Utilisation de la condition pour l exécution de la sortie sélectionnée Sélection par l indice dans le vecteur -Figure 4.15- Les actions et leur principe de transcription. 122 M.C.S.E
Transcription du modèle de performance en VHDL 4.6.8 Bilan sur la transcription du modèle comportemental La transcription d un modèle de comportement séquentiel (utilisation d un process VHDL) et les constructions telles que l alternative et la répétition n ont pas posé de difficulté. Dans le cas général, le comportement de chaque fonction est modélisé comme un ensemble de process synchronisés et coopérants. Le mécanisme de synchronisation de process concurrents est très simple. Il est basé sur l utilisation d un signal à trois états dont la valeur courante est gérée avec une fonction de résolution. Le protocole de communication en 4 phases a permis de traduire aisément l attente conditionnelle. Les primitives d accès aux éléments de relation ont été modifiées car le protocole peut maintenant être déjà commencé lors de leur appel procédural. La transcription de l achèvement forcé d activité a été plus difficile. Elle a néanmoins été facilitée par le fait que l entité gérant un élément de relation est passive par rapport à la ressource d exécution des fonctions ou activités. En effet, les temps d accès sont gérés au niveau des primitives d accès et non pas par l entité modélisant l élément de relation. Un état supplémentaire (ExitNow) a été rajouté à l ensemble des états possibles d un tâche (fonction ou activité). Les primitives associées à l état d une tâche ont donc été légèrement modifiées. Les primitives d accès à un élément de relation ont également été enrichies pour prendre en compte une fin d activité forcé sans perdre pour autant un degré de concurrence sur les accès à l élément de relation utilisé. Les conditions et actions simples se traduisent par l appel à une primitive d accès. La traduction des conditions ou actions composées repose sur l utilisation des principes de traductions définis pour le parallélisme et l attente conditionnelle. 4.7 CONNEXION ENTRE ELEMENTS DE RELATION ET COMPOSANTS ACTIFS En VHDL, les éléments sont reliés obligatoirement entre eux par des signaux définis par un type. Comme la généricité de définition d un type est limitée, l instanciation multiple et le respect de la hiérarchie du modèle source nous amènent à considérer trois cas de problèmes. 4.7.1 Utilisation d un lien de connexion uni-dimensionnel Si l élément de relation est simple ou multiple mais avec un seul consommateur/producteur (correspondance indice par indice ou élément actif simple), alors le signal de connexion est un vecteur. Ce vecteur regroupe tous les accès (ou liens) rattachés à l élément de relation. Pour des problèmes de convention de nom et de restriction au niveau du port map du composant gérant l élément de relation (le simulateur utilisé n accepte pas l opérateur de concaténation & de signaux lors du port map), nous utilisons des alias pour distribuer les éléments du vecteur sur les différentes fonctions; ce qui nous oblige à gérer les indices de ce vecteur et de ces alias. La figure 4.16 représente un cas où le signal reliant le composant gérant l élément de relation et les blocks représentant les fonctions est obligatoirement un vecteur. La structure fonctionnelle considérée (figure 4.16-a) fait partie de l exemple du serveur vidéo présenté dans le chapitre 7. Deux fonctions multiples Enregistrement et Lecture accèdent à une variable partagée nommée Séquences. La traduction VHDL (figure 4.16-c) utilise un vecteur nommé M.C.S.E 123
Chapitre 4 SequencesAccess et deux alias LectureSequences et EnregistrementSequences pour répartir ce vecteur sur la fonction Lecture et la fonction Enregistrement. Enregistrement[1:N] a) Représentation graphique de la structure fonctionnelle du système Séquences Lecture[1:N] b) Représentation textuelle partielle du système <Var> Sequences : DefSequences; <Component> [1:n] Enregistrement (InOut Var Sequences : DefSequences; ); <EndComponent> <Component> [1:n] Lecture (In Var Sequences : DefSequences; ); <EndComponent> c) Code VHDLpartiel CONSTANT NPlus1 : INTEGER := n+1; CONSTANT DeuxN : INTEGER := n+n; Serveur : BLOCK SIGNAL SequencesAccess:DefDataAccessVector(1 TO DeuxN); ALIAS EnregistrementSequences is SequencesAccess(1 to n); ALIAS LectureSequences is SequencesAccess(Nplus1 to DeuxN); Sequences : DataObject GENERIC MAP(NbUsers=>DeuxN, ) PORT MAP (Accesses=>LectureEnregistrementSequences, ); Lectures : BLOCK PORT (Sequences : INOUT DefDataAccessVector(1 TO n); ); PORT MAP(Sequences=>EnregistrementSequences, ); MultipleInstanciation: FOR i IN 1 TO n generate Lecture : BLOCK PORT (Sequences : INOUT DefDataAccess; ); PORT MAP (Sequences=>Sequences(i), ); END BLOCK Lecture; END GENERATE MultipleInstanciation; END BLOCK Lectures; Enregistrements : BLOCK PORT (Sequences : INOUT DefDataAccessVector(1 TO n); ); PORT MAP (Sequences=>LectureSequences, ); MultipleInstanciation: FOR i IN 1 TO n generate Enregistrement : BLOCK PORT (Sequences : INOUT DefDataAccess; ); PORT MAP (Sequences=>Sequences(i), ); END BLOCK Enregistrement; END GENERATE MultipleInstanciation; END BLOCK Enregistrements; END BLOCK Serveur; -Figure 4.16- Structure fonctionnelle et code MCSE et VHDL d un élément de relation simple. Il faut déterminer la taille du vecteur (pour les ports et les événements, il faut déclarer un vecteur d entrée et un vecteur de sortie). Pour des problèmes de convention de nom et de restrictions au niveau de la connexion du port map, nous utilisons des ALIAS pour distribuer les éléments du vecteur sur les différentes fonctions; ce qui nous oblige à gérer les indices de ce vecteur. 4.7.2 Utilisation d un lien de connexion bi-dimensionnel Si l élément de relation est multiple et est relié à plusieurs producteurs/consommateurs alors le signal de connexion est un vecteur de vecteur. La figure 4.17 donne un exemple ainsi que le principe de transcription pour ce cas. L exemple est dérivé de l exemple précédent. La variable Séquences a été remplacée par un port (DemD) et une fonction (Disque) multiple. Le rond noir sur les liens entre le port DemD 124 M.C.S.E
Transcription du modèle de performance en VHDL et les producteurs de messages Enregistrement et Lecture indique que tous les éléments du vecteur de fonction Enregistrement (respectivement Lecture) peuvent accéder à chaque élément du vecteur de port DemD. Ainsi, chaque élément du vecteur de port DemD est rattaché à 2*N fonctions d où la déclaration d un vecteur de dimension P d un vecteur de dimension 2*N. Comme la langage VHDL ne permet pas de définir un vecteur non contraint d un vecteur non contraint et ne permet pas de définir des paramètres génériques au niveau d un package, les types et la primitive d accès sont nécessairement définis au niveau de l entité. a) Représentation graphique de la structure fonctionnelle du système Enregistrement [1:N] DemD[1:P] Disque[1:P] Lecture [1:N] b) Code VHDLpartiel CONSTANT NPlus1 : INTEGER := n+1; CONSTANT DeuxN : INTEGER := n+n; Serveur : BLOCK TYPE DefDemDVectorOfPortInVector IS ARRAY (NATURAL RANGE <>) OF DefPortInVector(1 TO DeuxN); SIGNAL LectureEnregistrementDemD: DefDemDVectorOfPortInVector(1 TO P); -- on ne peut pas definir des types non contraint d'elements non -- contraint donc comme on ne connait pas N et ND(P) au niveau du -- Package on est oblige de declarer des primitives send a ce niveau PROCEDURE send( information : IN DefDemD; SIGNAL message : INOUT DefDemDVectorOfPortInVector; dest : IN NATURAL; source : IN NATURAL; LinkWriteTime : IN TIME; priority : IN NATURAL; date : IN TIME) IS VARIABLE TmpPortAccess : DefUPortIn; TmpPortAccess.information.InfDemD:=information; TmpPortAccess.protocol:= DefProtocol'(priority,date,ActiveReq); message(dest)(source)<=tmpportaccess; END send; InstantiationPortDemD : FOR i IN 1 TO P generate PortDemD : PortObject GENERIC MAP (NbUsersInput=>DeuxN,NbUsersOutput=>1, ) PORT MAP (InputAccesses=>LectureEnregistrementDemD(i), OutputAccesses(1)=>DisquesDemD(i), ); END GENERATE InstantiationPortDemD; Sequences : BLOCK PORT (DemD : INOUT DefPortOutVector(1 TO P); ); PORT MAP (DemD=>DisquesDemD, ); MultipleInstanciation: FOR i IN 1 TO P generate Disques : BLOCK PORT (DemD : INOUT DefPortOut; ); PORT MAP (DemD=>DemD(i), ); END BLOCK Disques; END GENERATE MultipleInstanciation; END BLOCK Sequences; Lectures : BLOCK PORT( DemD : INOUT DefDemDVectorOfPortInVector(1 TO P); ); PORT MAP (DemD=>LectureEnregistrementDemD, ); MultipleInstanciation: FOR i IN 1 TO n generate Lecture : BLOCK PORT (DemD : INOUT DefDemDVectorOfPortInVector(1 TO P); ); PORT MAP (DemD=>DemD, ); END BLOCK Lecture; END GENERATE MultipleInstanciation; END BLOCK Lectures; Enregistrements : BLOCK PORT (DemD : INOUT DefDemDVectorOfPortInVector(1 TO P); ); PORT MAP (DemD=>LectureEnregistrementDemD, ); MultipleInstanciation: FOR i IN 1 TO n generate Enregistrement : BLOCK PORT (DemD : INOUT DefDemDVectorOfPortInVector(1 TO P); ); PORT MAP (DemD=>DemD, ); END BLOCK Enregistrement; END GENERATE MultipleInstanciation; END BLOCK Enregistrements; END BLOCK Serveur; -Figure 4.17- Structure fonctionnelle et code VHDL d un élément de relation multiple. M.C.S.E 125
Chapitre 4 Au niveau des primitives d accès, chaque producteur doit alors donner son identité et l indice du port destinataire du message. 4.7.3 Problème des accès de niveaux hiérarchiques différents. Un point particulier de la transcription en VHDL concerne les éléments de relation à multiple producteurs/consommateurs lorsque les producteurs/consommateurs se situent dans des niveaux hiérarchiques différents comme le montre l exemple de la Figure 4.18. F3 F6 F4 V F2 F5 F1 Solution a Solution b F3 Block F4 Block Composant Interface d élément de relation Block F2 Composant élément de relation F6 Block F3 Block F4 Block Composant élément de relation F6 Block F5 F5 Block Entité F1 Block Entité F1 -Figure 4.18- Transcription VHDL d une variable à multiples écritures Deux approches sont possibles pour ce problème mais aucune n est réellement statisfaisante: - La première approche (solution a) consiste à utiliser une interface dans chaque fonction (décodeur de priorité). La priorité de l accès devient alors locale au niveau. Si l on ne tient pas compte de l attribut Concurrency de l élément de relation (concurrence infinie), cette implantation est possible et permet de respecter la hiérarchie du modèle MCSE. - Si l on doit tenir compte de l attribut Concurrency, on n a pas d autres choix que de mettre à plat la description (solution b). Mais, cette mise à plat n est pas possible si il y a une imbrication de fonctions multiples sur plusieurs niveaux. 126 M.C.S.E
Transcription du modèle de performance en VHDL 4.8 EXTRACTION DES RESULTATS D UN MODELE DE PERFORMANCE L évaluation des performances d un système nécessite l extraction des informations pertinentes pour l analyse. Ces informations pertinentes dépendent des indices de performance à analyser. Le monitoring, terme aussi utilisé pour l extraction de performances, concerne d une manière générale l observation de: - l état des fonctions, activités, opérations, processeurs, - l état des éléments de relation, - le respect de certaines contraintes telles que des contraintes de temps par exemple. Deux solutions de monitoring sont envisageables: - une solution systématique qui se traduit par une instrumentation automatique du code VHDL pour observer toutes les transitions exploitables pour les performances, - une solution spécifique pour chaque modèle. Le code VHDL ajouté est décidé et écrit par le concepteur du modèle pour ses besoins propres. Une librairie de composants de monitoring peut être mise à disposition du concepteur. -A- Solution systématique: génération d un fichier de trace et analyseur de performances La première solution fait l objet d une étude approfondie par l équipe et se traduit par le développement d un outil temps-réel d analyse de performances. Cet outil est présenté plus en détail dans [CALVEZ-95b] [CALVEZ-95c] [CALVEZ-98a]. Pour l exemple du serveur vidéo présenté dans le chapitre 7, avec la trace générée par simulation et l outil d analyse de trace, on observe: - le nombre d utilisateurs actifs (NbUsers), - la charge globale imposée au système (Throughput), - le nombre de fragments dans la fifo interne d un canal (Mess count), - le taux d occupation d un Processeur Execution. Non représentés par les courbes de la figure 4.19-a, on peut également obtenir à partir de la trace générée: - le nombre de disques utilisés (NbDiskUsed), - le taux d occupation d un disque. L outil d analyse de trace sert également à visualiser des traces capturées en temps réel et de visualiser un déroulement temporel (time line) de l application utile pour une analyse détaillée telle que par exemple la recherche de la cause du non respect d une contrainte temporelle. Un exemple de déroulement temporel obtenu par simulation d un système d asservissement en vitesse et position d un moteur à courant continu [HELLER-93] est donné par la figure 4.19-b. Le diagramme temporel permet de visualiser l état des fonctions et la trace des événements et de mesurer les temps de réponse. Ainsi, il facilite la compréhension des dépendances d activation entre tâches et la recherche des éventuels problèmes d ordonnancement (non respect de contrainte de temps, interblocage, etc.). M.C.S.E 127
Chapitre 4 a) calcul et visualisation d indices de performance b) déroulement temporel -Figure 4.19- Aperçu de l interface graphique de l outil d analyse de Trace. -B- Solution spécifique Avec l utilisation d un simulateur VHDL, les possibilités d observation sont de 2 types: - l observation sous forme de chronogrammes: il s agit de suivre l état d un signal du type State. Quatre valeurs différentes sont possibles ce qui permet de suivre précisément l état d un constituant actif: Inactive=X, Blocked=0, ing=z, Active=1. 128 M.C.S.E
Transcription du modèle de performance en VHDL - l observation de données obtenues par une évaluation VHDL et mémorisées dans un fichier. Des programmes (en Shell par exemple) permettent ensuite d obtenir les résultats selon la forme souhaitée et de les visualiser en exploitant par exemple le logiciel GnuPlot. Ces 2 possibilités ont été exploitées simultanément sur les deux exemples. La première forme d observation sert plus particulièrement pour la mise au point et la vérification fine du bon comportement du modèle et nettement moins pour l évaluation des indices de performance. Preemption waiting Le chronogramme ci-dessus permet de voir pour l exemple du serveur vidéo l effet de préemption du processeur: la fonction de lecture du canal 5 perd le processeur au profit de celle du canal 4 et ne le récupère qu après la fin d activation de la fonction lecture du canal 6. Le signal nbactivetasksprocessorexecution avant dernier chronogramme réprésente le nombre de tâches actives sur le processeur d exécution et sert également pour calculer le taux d occupation du processeur. -Figure 4.20- Exemple de chronogrammes. 4.9 EXEMPLE DE VALIDATION L exemple de validation considéré ici est le serveur vidéo simplifié dont le modèle de performance a été présenté dans le chapitre 3. Nous présentons donc les résultats de performance obtenus par transcription du modèle de performance en un modèle VHDL comportemental, puis par simulation du programme VHDL obtenu. La taille du code source MCSE est de 129 lignes et la taille du programme VHDL est de 651 lignes pour l entité et 1108 lignes pour le package. 4.9.1 Résultats de simulation du modèle fonctionnel La première simulation consiste à vérifier le bon déroulement temporel de l application sans considérer l effet du processeur P. Aussi son degré de concurrence est supposé infini. M.C.S.E 129
Chapitre 4 On se place dans le cas de 2 disques possédant un temps d accès de 20 ms, de 10 usagers lancés progressivement d une manière aléatoire. La figure 4.21 donne le résultat de simulation en montrant: le nombre de disques sollicités, le nombre d usagers et le débit global de transmission. 25 "DisksConcurrency" "TransmissionRate" "WatchingUsers" 20 15 10 5 0 0 10 20 30 40 50 60 70 Temps (s) -Figure 4.21- Déroulement temporel pour la validation du modèle. 4.9.2 Simulation avec un modèle réaliste des disques Le modèle est maintenant modifié pour être plus réaliste pour les disques. La variable partagée est remplacée par un ensemble de ND fonctions Disque. Les demandes se font par des ordres de lecture et d écriture DemD[i]. Dans le cas de la lecture, le retour est fourni par RepD[i]. Les demandes sont mémorisées dans les ports DemD[i]. Le comportement de chaque disque est décrit par un modèle comportemental. Le temps de lecture ou d écriture est défini par le temps de positionnement sur la piste, le temps d attente du bloc sous la tête, le temps de lecture du bloc. DemD[] * Disque[] User[1:n] Cmd Supervision TV set[1 DemD[] Op=write Write OR DemD[] Op=read Read RepD[] Read Time = TaccDisk; Write Time = TaccDisk; Source BlockIn Recording OrderRec Processor P P Concurrency=M; Séquences DemD[1:ND] RepD[1:n] OrderRead[1:n] BlockOut[1: ReadMovie TaccDisk = Tseek + Tlatency + Tread; with - Tseek = U(2,24) ms (U a random law), - Tlatency = U (0,11) ms, - Tread = 12,8 ms (read time) Disque[1:ND] Explicit concurrency of ND; -Figure 4.22- Modélisation réaliste des disques. 130 M.C.S.E
Transcription du modèle de performance en VHDL Le modèle étant vérifié au niveau fonctionnel, on considère maintenant que les fonctions ReadMovie sont implantées sur un processeur P de degré de parallélisme M. Pour le dimensionnement de l architecture, nous faissons une évaluation de M et de ND en fonction du nombre simultané d usagers ou du débit global. Pour cela, le degré M est incrémenté jusqu à ne plus détecter de rupture de séquence. Le nombre de disques est ici évalué d une manière statique par le débit global des disques qui doit être supérieur au débit de transmission. La figure 4.23 donne le résultat du dimensionnement. 12 "NumberOfDisks" "NumberOfProcessors" 10 8 6 4 2 0 0 5 10 15 20 25 30 35 40 45 50 Nombre d usagers -Figure 4.23- Dimensionnement du processeur et des disques en fonction de la charge. 4.10 CONCLUSION Les principes de transcription du modèle de performance en un programme VHDL simulable présentés dans ce chapitre se sont inspirés: - des concepts des exécutifs temps réels pour l implantation des processeurs à degré de ressource limité, - du mécanisme de communication par jeton du modèle UVa pour la communication entre éléments de relation et composants actifs, - de l implantation en VHDL des SpecCharts pour le parallélisme d activité et l achèvement forcé d activité. Comme remarques concernant l emploi de VHDL, on peut citer les points positifs et négatifs suivants [CALVEZ-95a]: - son intérêt pour représenter des modèle hiérarchiques et paramétrables, - son intérêt certain pour la simulation d un parallélisme, - son intérêt pour les instanciations multiples statiques, et sa restriction gênante pour notre modèle de performance concernant l instanciation dynamique de blocks ou de process, ce qui serait pratique pour l instanciation d activités, - l intérêt de la surcharge d opérateurs et de procédures, - la limitation sérieuse concernant l absence de records variants, - l impossibilité de définir un package générique et un vecteur non contraint de vecteur non contraint, M.C.S.E 131
Chapitre 4 - l absence de possibilité de suspension et reprise d un process avec gel du temps ce qui aurait permis une modélisation aisée de la notion de ressource d exécution avec degré de concurrence limité. Les constructions telles que l attente conditionnelle, l achèvement forcé d activité et certains cas de l instanciation multiple ont posé des difficultés de transcription. Dans ces cas, la complexité de la solution d implantation en VHDL retenue se paie malheureusement au niveau de la génération de code et de la lisibilité et l efficacité du code VHDL produit. Les principes de transcription ont d abord été expérimentés sur l exemple simplifié du serveur vidéo puis ont été validés à l aide de deux exemples qui sont présentés dans le chapitre 7. Ces deux exemples ont permis de constater la nécessité de ressources importantes pour la simulation (puissance de calcul et mémoire) et une durée de simulation souvent trop longue pour trouver rapidement la solution optimale recherchée. Il est probablement possible de réduire le temps de simulation en générant un modèle ne respectant pas la hiérarchie du modèle MCSE (moins de process et de signaux à gérer pour le simulateur) et en utilisant deux signaux Req et Ack au lieu d une fonction de résolution pour le protocole de communication. Mais, le couple VHDL/Simulateur restera quand même moins performant que la technique basée sur l exécution d un programme C++ dans un environnement multi-tâches qui sur l exemple du système de communication présenté dans le chapitre 7 s est révélée environ 4 fois plus rapide. L emploi de VHDL a cependant permis d expérimenter rapidement le modèle de performance sur des exemples alors que le simulateur C++ a demandé un temps de développement et de mise au point relativement long. Maintenant que les règles de transcription ont été décrites, nous devons nous charger de les implanter dans un générateur automatique de code. La technique de génération de code retenue fait l objet des chapitres 5 et 6. 132 M.C.S.E