Académique Documents
Professionnel Documents
Culture Documents
Yannick HERVE
Cet ouvrage présente le langage de conception de systèmes du standard IEEE 1076-1999 et son importance dans
le cadre d’une utilisation industrielle. Ce langage est connu sous le nom VHDL-AMS pour « VHSIC Hardware
Description Language – Advanced and Mixed Signal » avec VHSIC : Very High Speed Integrated Circuit. On
trouvera toutes les explications sur ce nom complexe dans le chapitre 2.
Tous les exemples présentés sont disponibles sur le CD-ROM distribué avec le livre. Certains exemples illustrent
des constructions de la norme qui ne sont pas disponibles sur les outils industriels utilisés ; Ils seront signalés
comme tels. Le langage de base, VHDL’93, sur lequel est construit VHDL-AMS est connu, enseigné et utilisé
depuis longtemps et sera présenté assez rapidement. On se reportera, pour plus de détails sur la partie purement
numérique (à événements discrets), aux ouvrages existants et à ceux cités dans la bibliographie.
Beaucoup d’anglicisme, de néologismes et de mots de jargons sont utilisés, et ce, à dessein : c’est le langage de
la profession. Ils seront traduits ou expliqués dans le glossaire, comme toutes les abréviations, les acronymes et
les sigles.
L’auteur se permettra quelques petites digressions dans des encadrés dûment signalés.
Ce livre est composé de trois parties : (I) Les besoins et l’histoire, (II) Le langage et ses applications industrielles
et (III) Les outils et des exemples.
Dans les deux premiers chapitres, après avoir situé les besoins et les tendances de l’industrie électronique nous
présenterons la genèse du langage. Ces chapitres nous permettront de poser les bases conceptuelles générales sur
lesquelles les concepteurs du langage se sont appuyés.
La présentation du langage sera répartie sur les chapitre 3 et 4 alors que les applications et les limitations feront
l’objet des chapitres 5 et 6. Le chapitre 3 nous permettra de présenter les notions essentielles à une approche
simplifiée mais opérationnelle alors que le chapitre 4 verra la description des constructions plus avancées. Nous
donnerons quelques pistes d’utilisation rationnelle dans le chapitre 5 et nous soulignerons les limitations au
chapitre 6.
La partie III permettra de présenter deux outils industriels existant au moment de l’écriture de cet ouvrage ainsi
que des exemples plus conséquents.
2
Partie I : Les besoins et la naissance
Chapitre 1 : Les besoins
1.1 Introduction : Les défis de l'électronique moderne
Les circuits intégrés complexes sont présents de plus en plus souvent dans notre environnement sans que nous
n'y portions une attention particulière (systèmes de sécurité embarquée des automobiles, téléphones portables,
organiseur, ...). Ils sont "enfouis" au sein des systèmes et doivent mesurer, traiter, calculer, piloter des actions,
cohabiter de plus en plus "intelligemment" et de façon transparente pour nous avec leur environnement. Pour ce
faire, la technologie permettant de mettre à disposition des applications les circuits performants dont elles ont
besoin est en mutation permanente, et ce, depuis la création du premier circuit intégré par Kilby en 1958.
Les évolutions techniques se font à plusieurs niveaux et même si les chercheurs travaillent actuellement sur
l'électronique d'après demain basée sur des principes de fonctionnement différents de ceux utilis és à l'heure
actuelle (principes quantiques, électronique mono-électron, électronique moléculaire,...), les architectures
classiques basées sur les transistors MOS ou Bipolaires sont encore à l'ordre du jour. Les améliorations de
performances en surface d'intégration, tension d'alimentation, fréquence ont été basées principalement sur la
diminution de la longueur de la partie active du transistor (mais aussi par la maîtrise des matériaux et la physico
chimie associée, la connectique, les techniques de fabrication, ...). L'évolution passée (et prévue) de la géométrie
participe à la loi de Gordon Moore (on double les performances tous les 18 mois) et bien que de faux prophètes
prévoient la mort du transistor classique depuis plusieurs années, il vit encore. La taille des canaux de transistor
approche de 100 nm en production industrielle, à comparer à la taille de la maille cristalline du silicium de 0,54
nm. Les circuits intégrés numériques sont d’une complexité qui dépasse l’entendement, même des spécialistes
(42 millions de transistors dans un Pentium 4 qui fonctionne à plus de 1 GHz).
Ces évolutions [ROAD] ne sont possibles qu'en surmontant de grosses difficultés technologiques, conceptuelles
et méthodologiques. Les usines pour fabriquer des dispositifs basés sur les nouvelles géomètries ont des coûts
incroyablement élevés. Les transistors utilisés présentent des effets nouveaux ou rendent importants des effets
qui étaient secondaires voire négligeables dans les "anciennes" technologies. L'épaisseur d'oxyde, inférieure à 5
nm, qui influence la capacité d'oxyde fait apparaître des effets quantiques parasites pour le fonctionnement
attendu. Les performances sont maintenant plus dépendantes des paramètres externes du transistor (capacité de
recouvrement, parties résistives, couplages, ...) que de sa partie active. Bien entendu, le concepteur doit tenir
compte de tous ces effets pour assurer une conception de qualité. Ces comportements doivent donc être intégrés
dans les modèles, de plus en plus complexes, de transistors permettant des simulations fiables et productives. Les
outils permettant de manipuler des modèles doivent être faciles d'accès et sources de gain de productivité c'est-à-
dire remplir les tâches antinomiques de manipuler de plus en plus de transistors, de plus en plus d'équations par
transistor et de donner un résultat fiable et représentatif de la réalité dans un temps non prohibitif. Ils doivent
permettre d’exprimer et de simuler le système complet.
Les circuits intégrés contiennent donc de plus en plus de transistors mais en plus on y fait cohabiter des systèmes
analogiques et numériques contenant éventuellement du logiciel enfoui. De surcroît, les progrès accomplis par
les techniques d'intégration permettent d'embarquer des micro-systèmes mécaniques, optiques ou chimiques au
sein même du circuit. Par cette approche on peut disposer de capteurs (température, pression, champ magnétique,
...) ou de micro-actionneurs (moteurs, vérins, miroirs pivotants, ...) sur le même substrat que l'électronique. Ces
circuits sont nommés MOEMS (Micro Optical Electronical Mechanical Systems) et sont en pleine évolution. On
prévoit, par exemple, de pouvoir faire ingérer un système de ce type, gros comme une gélule, à un malade. Ce
système autonome se déplacerait dans l'intestin, libérerait une micro-dose de médicament à heure fixe, ferait des
prélèvements de tissus et transmettrait par radio les résultats pour diagnostic par le spécialiste.
Le concepteur du futur (proche) sera alors confronté au problème crucial de la conception d'un système multi-
disciplines avec des contraintes industrielles fortes : modélisation formelle et exécutable du cahier des charges,
détection des erreurs tôt dans le cycle de conception, circuit intégré qui fonctionne dès la première fabrication,
gestion de la durée des projets pour satisfaire des "time to market"* de plus en plus exigeants, réutilisabilité des
conceptions, gestion de grosses équipes de conception, simulation d'un circuit intégré tenant compte de son
environnement effectif, ...
Pour intégrer toutes ces contraintes on comprend que la méthodologie utilisée pour le développement joue déjà,
et jouera de plus en plus, un rôle primordial dans la réussite des projets industriels d’envergure. Pour la
3
conception des systèmes entièrement numériques, les outils de Conception Assistée par Ordinateur (CAO) ont
beaucoup progressé en 30 ans [CAE] et permettent de concevoir des circuits «quasiment » automatiquement. A
partir d’une description de haut niveau de la fonction désirée avec un HDL* , on utilise un logiciel de synthèse
logique* , un simulateur, un optimiseur (front-end) puis des utilitaires de placement-routage* permettant de
préparer les données à envoyer à l’usine de fabrication (le fondeur). Ces techniques de conception ont vu leur
efficacité grandir avec la maturité des langages de description de matériel dédiés au numérique (VERILOG et
VHDL). Tous les acteurs parlant le même langage, les outils associés se sont développés et la conception de
système numérique est plus devenue un problème de concepts à faire cohabiter qu’un problème technologique.
Ce « workflow » * (semi) automatisé n’est malheureusement pas disponible pour l’analogique ou les autres
systèmes intégrés mais pour profiter de cette dynamique la communauté de l’électronique a proposé par
l’intermédiaire de l’IEEE (Institute of Electrical and Electronics Engineers) un standard nommé officiellement
IEEE 1076-1999 et connu plus pragmatiquement sous le nom de VHDL-AMS. L'industrie électronique
commence à fournir aux concepteurs un cadre de travail permettant d'appréhender tous ces besoins de façon
globale. Ces outils reposent sur des normes internationales et il deviendra indispensable, pour être efficace, de
faire reposer les études sur celles-ci. Il devient incontournable de travailler avec des outils de haut niveau
permettant de se consacrer aux concepts plutôt qu'aux détails. Le concepteur est et sera de plus en plus un
utilisateur de l'outil informatique abstrait.
La suite du chapitre fait une présentation plus détaillée de toutes ces contraintes techniques et méthodologiques.
L’électronique à plusieurs noms en fonction de la forme de l’information utilisée. Le signal à traiter peut être à
temps continu (tc) ou discret (td) et à amplitude continue (ac) ou discrète (ad).
Classiquement on parle d’électronique analogique (tc,ac), numérique ou « digitale » (td,ad), quantifiée (tc,ad) et
échantillonnée (td,ac).
Certains auteurs (en fait, beaucoup) parlent d’électronique digitale. En français, en dehors du néologisme créé
récemment pour l’occasion, digital fait référence aux doigts (empreintes digitales). C’est par une mauvaise
utilisation du mot anglais « digital » (digit veut dire chiffre en anglais) que le néologisme à été créé [Faire du
calcul digital, c’est en fait compter sur ses doigts ! ]. La bonne façon de parler de cette électronique serait de dire
que c’est une électronique des signaux à temps discret et à amplitude discrète : c’est un peut lourd. Le terme
électronique numérique semble préférable ; précis et juste puisque l’objectif est de manipuler les nombres
(exprimés la plupart du temps, mais pas obligatoirement, en binaire) sans se préoccuper (au premier ordre) de
l’amplitude effective du signal physique.
Le nom « ANALOGIQUE » vient de la période ou l’électronique continue (en temps et en amplitude) avec ses
composants passifs et ses amplificateurs (à lampe d’abord, à transistor ensuite) permettait par ANALOGIE de
résoudre un réseau d’équations différentielles. C’était la période des calculateurs (ou simulateurs) analogiques.
Un système physique pouvant être mis en équations par des équations différentielles ordinaires peut être
« singé » par un système électrique bien choisi : C’est par cette analogie que le système physique était étudié et
que l’électronique était qualifiée. Le nom est resté alors que la technique n’existe quasiment plus. Il serait donc
plus juste de parler d’électronique continue, mais l’habitude du temp s a déjà fait son œuvre.
La mise en place d’un projet d’envergure pour une société d’électronique est une décision complexe, stratégique
et difficile. La vie de plus en plus courte des produits, leur complexité croissante fait que l’industriel doit
travailler avec des «time to market » de plus en plus court dans un réseau de partenariat (fournisseurs,
distributeurs, ...) de plus en plus serré. Les gros projets sont forcément multi métiers et doivent faire cohabiter
des cultures et des pratiques parfois fort différentes. L’industriel doit alors développer et lancer des produits
innovants dans un contexte normatif et réglementaire de plus en plus contraignant (qualité, environnement,
temps de travail, sécurité, ..)
4
Cette description du métier peut paraître très noire mais grâce à des techniques de gestion des hommes et des
techniques des réussites technologiques incontestables ont pu, et continuent de, voir le jour (GSM, Ordinateurs
portables, ..) Cette présentation peut paraître loin du sujet qui nous intéresse ici, mais si des projets si complexes
peuvent être pris en charge c’est grâce en partie aux méthodes de conception assistée par ordinateur et les
langages de description ont permis de prendre en charge des complexités inimaginables quelques années
auparavant et le développement des outils comme le VHDL-AMS participent et participeront à l’explosion
industrielle du futur.
Le cycle de production depuis l’idée jusqu’à la distribution est réparti entre différentes activités pouvant, en
partie, se dérouler en parallèle. L’encadré suivant fait un bilan non exhaustif de différentes étapes que peut
traverser un projet. A tout moment le projet peut être modifié ou arrêté s’il met en péril la santé de la société.
Le volume de vente d’un produit dépend de plusieurs facteurs dont le prix (intrinsèque et comparé à la
concurrence). Dans une première approche simple le prix de vente HT d’un produit peut être défini de la façon
suivante :
Prix = I / Nv + Nf / Nv . Cm + M
Avec :
I: Investissement total
(Dont le coût des études et des outils, appelé aussi NRE pour « Non Recurrent Engineering Cost »)
Cm : Coûts unitaire matières premières, transport, salaires production …
Nv : Marché potentiel
(On fait l’hypothèse que le marché correspond à la production, problème si Nv n ’est pas atteint)
Nf : Volume total produit (Nf - Nv est le rebut)
Nf / Nv : Rendement de production
M: Marge totale (Permet investissements et profits)
5
On voit que le prix est influencé par le montant des investissements ramené au volume vendu mais aussi au
rendement de production. Les différents rôles de la CAO dans la définition du prix donc de la compétitivité sont
donc :
Les circuits intégrés ont leur propre flot de conception (workflow). Classiquement le processus et les outils
associés sont décomposés en deux ensembles nommés le FRONT-END (pris en charge par la CAD) et le
BACK-END (pris en charge par la CAE) qu’on peut traduire en français par conception assistée par ordinateur et
ingénierie assistée par ordinateur.
Le FRONT-END est constitué de toutes les tâches (et des outils permettant de remplir ces tâches) permettant de
passer du cahier des charges à une netlist* de composants de base (porte en numérique et transistors en
analogique). C’est dans cette partie que l’on trouve les éditeurs de schémas ou de HDL, les synthétiseurs
logiques, les optimiseurs de haut niveau. C’est au cours de ces étapes que toutes les simulations fonctionnelles
ont lieu.
Le BACK-END est la partie de la conception du projet qui le prend en charge depuis la netlist jusqu’à la
préparation des données pour la fabrication. On y trouvera les placeur-routeurs, les simulateurs physiques, les
DRC* (Design Rule Check), les LVS * (Layout Versus Schematic), les outils de préparations des données pour
les machines de fabrication et de tests. C’est pendant le BACK-END que des simulations temporelles sont
effectuées et les résultats sont réinjectés dans les netlist de haut niveau du FRONT-END (rétro-annotation ou
back-annotation).
Pour être efficaces tous ces outils doivent partager la même base de données et profiter le plus possible de
descriptions communes en évitant les traducteurs de format toujours source de perte de précision sémantique et
d’erreurs.
Dans les flots de conception modernes la frontière n’est plus très nette entre ces deux parties car les effets
« canaux courts » des nouvelles géométries de transistor doivent être appréhendés le plus tôt possible pour être
efficacement pris en charge. De la même façon la prédominance dans les délais de transmission de l’information
de la longueur des pistes par rapport aux transistor donne une importance de plus en plus prépondérante au
placeur-routeur. (25% des délais avec des technologies 0,5 ?m contre 80% pour une technologie 0,15 ?m)
Pour mener à bien toutes les activités concourant à la réussite d’un projet industriel la méthodologie est très
importante. Dans la suite nous présentons quelques techniques utilisées en conception électronique. Certaines
d’entre elles ne sont pas encore matures pour être utilisées dans le monde industriel mais sont en développement
dans les laboratoires universitaires.
Remarque : Chaque concept méthodologique présenté est précédé de deux lettres entre crochets. Dans la
présentation du langage les constructions supports de ces techniques seront annotées avec ces repères.
L’établissement d’un cahier des charges complet et précis d’un système complexe est une tâche très ardue. Les
fonctionnalités et les contraintes associées sont décrites en langage naturel dans un document qui peut être
6
extrêmement volumineux. Cette technique est sujette à imprécisions, ambiguïtés, oublis voire contradictions.
Aucune prédiction de performances ou de coût ne sont possibles sans l’expérience des chefs de projets et des
architectes systèmes.
La tendance actuelle est de privilégier des langages de description formelle de cahier des charges donnant accès
à une simulation fonctionnelle partielle ou complète. On va alors exprimer le QUOI (la fonction)
indépendamment du COMMENT (l’implémentation physique). La conception sera l’exercice du passage du
premier au deuxième niveau. Avec ces outils, toutes les conceptions pourront se référer, pour comparaison, aux
résultats de simulation fonctionnelle du cahier des charges.
La conception descendante est le fait d’effectuer une conception en débutant avec un haut niveau d’abstraction
(une description fonctionnelle) pour passer par étapes successives à une réalisation physique par interconnexion
de composants de base (circuits discrets ou circuits intégrés complexes, ASIC, processeurs, logiciel, …). Cette
approche est complémentaire de la technique précédente [CF].
Cette approche permet de retarder le choix de la technologie le plus tard possible dans le cycle de conception. De
la même façon une modification de technologie ne remet pas en cause les premières étapes de la conception. Elle
s’oppose à l’approche BOTTOM-UP pour laquelle on va commencer par concevoir technologiquement toutes les
briques de base pour ensuite les assembler (avec les risques d’erreurs dans les définitions de connexions).
Dans la réalité on utilise un mélange des deux techniques ; par exemple la conception d’ASIC (Circuits
spécifiques de l’application) à partir d’une technique de cellules pré-caractérisées peut être mener avec une
conception TOP-DOWN mais les cellules sont issues d’une approche BOTTOM-UP (mais une fois pour toutes).
La multi-abstration est le fait de pouvoir mélanger dans une même description des objets décrits de façons très
différentes. On peut alors simuler un système avec des parties décrites au niveau fonctionnel (par exemple une
équation mathématique) alors que d’autres parties sont décrites par l’instanciation structurelle de transistors de la
technologie choisie tenant compte des phénomènes physiques au niveau du semi-conducteur.
La puissance de vérification des conceptions en cours est augmentée : Un concepteur prend en charge la
conception d’un sous système Xk au sein d’un système X. Ce système est décrit sous une forme structurelle
(interconnexion de modèles) de chacun de ses sous-ensembles X1 , X2 , X3 , … et cette description est simulable
[CF]. Les vérifications de toutes les étapes de conception du sous-ensemble Xk en cours d’étude pourront se
faire en tenant compte des interconnexions avec les autres sous-systèmes.
Quand un système est constitué de plusieurs parties et que la simulation pose des problèmes de temps de calcul
on peut profiter de cette méthode pour améliorer la situation. Plus un objet est décrit à un haut niveau
d’abstraction plus sa simulation est performante en temps. En associant les modèles à différents niveaux
d’abstraction on peut valider complètement un système sans avoir à le simuler globalement au plus bas niveau.
Quand on sait (voir la presse spécialisée) que quand un circuit intégré ne fonctionne pas c’est dans 90% des cas
un problème d’interconnexion avec l’extérieur on comprend l’attrait de cette possibilité !
Un système (S) ou un circuit intégré n’est jamais conçu pour fonctionner seul. Il est toujours au sein d’un
système plus global (SG), éventuellement interconnecté avec d’autres entités de celui-ci. Dans les flots de
conception moderne on fera l’étude du système (ou du CI) en tenant compte des interactions avec
l’environnement en fabriquant un modèle global.
Il sera possible par exemple de prévoir l’augmentation de température liée au fonctionnement du système global
(en tenant compte de la dissipation propre de (S)) et d’en tenir compte dans les performances du système en
cours d’étude.
Un autre exemple : Un ASIC permettant de construire une loi de commande de convertisseur de puissance en
vue du pilotage en vitesse d’une machine tournante sera étudié de façon beaucoup plus précise si, dans les
7
simulations, le système complet est pris en charge (mesure de vitesse et de courants, conversion des
paramètres, loi de commande, élaboration des commandes du convertisseur, le convertisseur, le réseau
électrique, la machine tournante, l’environnement thermique, …). Les fonctions du circuit intégré en cours
d’étude sont notées en gras.
Pour des facilités de prise en charge ceci implique que des phénomènes non-électriques (thermiques,
mécaniques, magnétiques, …) soient modèlisables directement avec les équations et les unités caractéristiques
du domaine physique considéré. Bien entendu l’environnement sera la plupart du temps décrit avec un haut
niveau d’abstraction [MA].
La hiérarchie de conception est une organisation des informations gérée par les environnements de
développement. Elle permet de manipuler facilement la conception descendante en spécifiant pas à pas la
structure et le contenu de chaque sous-système.
Un système est considéré comme une boite-noire avec ses entrées et ses sorties, les contraintes associées et
éventuellement un modèle fonctionnel de simulation. Puis cette boite est elle-même définie comme
l’interconnexion d’autres boite (vue structurelle) et ce de façon récursive jusqu’à la définition technologique des
objets de base qui apparaissent alors comme les feuilles terminales de l’arbre de conception. Chaque objet de
base n’est défini que comme une instance d’un objet générique qui peut être disponible dans une base de
données. Par exemple si la conception utilise 100 portes NAND, il n’y a qu’un modèle instancié plusieurs fois.
Cette méthode de travail est supportée par des outils informatiques spécialisés aussi bien par la gestion de
schémas récursifs que de schéma interconnectant des boites définies par un code HDL.
A chaque niveau de définition ou coupe à profondeur constante dans l’arbre, on a un niveau d’abstraction. Ainsi
toutes les étapes de l’approche descendante [TD] sont disponible au même moment. Pour profiter de la puissance
d’analyse et de prévision de cette technique il faut qu’elle soit combinée avec les autres précédemment définies :
[CF][TD][MA] [SE]
La synthèse logique est l’application qui permet à partir d’une description de haut niveau de fabriquer
«automatiquement » et en tenant compte des contraintes (vitesse, surface, consommation, …) l’électronique
numérique d’un projet. Les ressources de base sont des cellules précaractérisées * (ASIC), des structures
précalculées (FPGA * ) ou des structures déjà implantées (CPLD * , PREDIFFUSES * ).
Au milieu des années 80 on pouvait concevoir le schéma d’une PAL* à partir d’un jeu d’équations booléennes
(autour de 2000 portes équivalentes). A l’heure actuelle on peut décrire avec un haut niveau d’abstraction un
système numérique grâce à un structurel de description HDL (logique combinatoire, synchrone, FSM * ),
tabulaires (tables de vérité) ou graphiques (schémas, graphes de fluence, réseaux de petri) dans le cadre d’une
hiérarchie de description (quelques millions de portes). Les travaux universitaires étendent les possibilités des
langages et la sémantique possible pour rendre synthétisables des descriptions de plus en plus haut niveau.
Le concepteur n’a plus qu’à se consacrer efficacement au QUOI plus qu’au COMMENT. Ainsi des circuits de
plusieurs millions de transistors sont conçus sans qu’aucun schéma de base (au niveau porte et encore moins au
niveau transistor) ne soit conçu par des humains.
La preuve formelle est une technique récente pour prouver, sans simulation, l’égalité de deux descriptions.
Actuellement seules les descriptions fonctionnelles sont manipulables à l’exclusion, donc, des définitions
temporelles.
Les techniques utilisées sont issues des mathématiques. Chaque description est traduite en un graphe et on
détermine automatiquement si un graphe couvre l’autre. Une autre technique consiste à considérer une des
descriptions comme un théorème, l’autre devant en être la preuve.
8
Petite digression : Des limites de la simulation en preuve des systèmes
L’état d’un système numérique à M entrées et N bascules à un moment T est défini par les 2(N+M) états qu’il peut
prendre. Simuler un système pour prouver qu’il fonctionne dans tous les cas de figure revient à lui faire atteindre
tous les états possibles à partir de ses entrées. Un petit calcul avec M et N raisonnables (10 et 100 par exemples)
montre aisément que c’est humainement impossible même avec des ordinateurs les plus puissants possibles.
Dans le cas des systèmes analogique le problème est encore plus difficile et la simulation n’illustrera qu’une
idéalisation de la situation car il est très difficile de simuler en tenant compte de tous les phénomènes intervenant
(diaphonie, dispersion des caractéristiques, influences extérieures, variations des conditions d’utilisation, …)
avec des modèles de composants prenant en compte tous les phénomènes physiques.
La simulation ne prouve donc pas qu’un système fonctionne de la même façon qu’en mathématique
l’énumération des cas favorables ne remplace pas une démonstration générale. Elle peut dans le meilleur des cas
faire le bilan de quelques cas qui ne présentent pas de problème. C’est donc un pis -aller pour lequel nous
n’avons pour l’instant pas d’alternative mais qui bien utilisé peut couvrir la plupart des cas utiles.
Il y a quelques années quand un circuit devait embarquer des parties numériques et d’autres analogiques les deux
conceptions étaient menées indépendamment et les sous systèmes étaient intégrés en toute fin de processus de
création. Beaucoup d’erreurs ne pouvaient être détectées assez tôt pour être corrigées efficacement avec un coût
négligeable.
A l’heure actuelle les descriptions doivent pouvoir, de façon simple, prendre en charge des conceptions mixtes
pour assurer la cohabitation planifiée des sous-systèmes.
[CD] Co-design
Les systèmes se complexifiant, ils embarquent de plus en plus souvent du logiciel (embedded software * , logiciel
enfouis, firmware * ) pour piloter les micro-contrôleurs intégrés dans le cœur même des applications. La
méthodologie de conception doit être capable de proposer aux concepteurs la gestion et le développement
commun du logiciel et du matériel.
Il existe déjà des environnements de conception pour les applications de traitement de signal permettant de
spécifier des structures mixtes. La partie matérielle est prise en charge par une synthèse logique tandis que la
partie logicielle est automatiquement générée en assembleur pour un processeur de traitement de signal.
Il est indispensable de pouvoir vérifier tous les systèmes sortant de production pour assurer le rendement, le
pilotage (réglage) de la chaîne et de façon plus globale la qualité de la production. Il faut que l’outil de
conception fournisse tous les utilitaires pour effectuer ces tâches automatiquement. Les structures améliorant la
testabilité, les vecteurs de test, l’analyse de fiabilité devront être calculés de façon autonome au cours de la
conception du système. De plus, il faut pouvoir tracer les erreurs pour pouvoir agir sur la cause effective.
La vérification des systèmes (le test) est encore plus difficile que celui de la simulation car tous les points de
mesure utiles ne sont pas forcément atteignables.
9
Pour un système numérique : Un système est observable si à partir de ses sorties on peut déduire l’état de toutes
ses bascules. Un système est dit pilotable si à partir de ses entrées on peut imposer l’état de toutes ses bascules.
Un système est dit testable s’il est pilotable et observable. Un système aura un taux de couverture en test de X%
si X% des états peuvent être vérifiés par le test (pilotages des entrées et diagnostic par les sorties).
On peut être amené à construire un jeu de vecteur de test d’une taille absolument gigantesque pour pouvoir
vérifier les systèmes par un testeur approprié. En fait la conception pourra être menée en vue d’une couverture de
test maximale.
Des techniques récentes comme le Boundary scan (ou test par scrutation de la périphérie) permettent à moindre
frais, sous l’hypothèse que le circuit a été augmenté des sous-systèmes de service, d’atteindre aussi bien en
lecture qu’en écriture tous les points du circuit.
Dans la mesure du possible l’ensemble des tâches d’une conception doit se dérouler dans le même
environnement logiciel pour minimiser la probabilité d’erreurs de transcription. L’outil unique ou framework
sera ouvert pour pouvoir accueillir de nouveaux outils et partager les base de données de stockage de la
conception.
Dans un processus de conception beaucoup de tâches sont interdépendantes, éventuellement séquentielles. Par
une analyse des flux de matières, de personnes il est possible de construire un graphe des tâches permettant de
maximiser la mise en parallèle des actions et ainsi de contrôler les temps et les coûts. Pour pouvoir mettre en
œuvre cette technique il faut pouvoir disposer de méthodes de conception étant compatibles avec le but
recherché.
[RE] Réutisabilité
Il est rare qu’un produit soit complètement nouveau. La plupart du temps une société base ses nouveaux
développements sur l’évolution d’un système existant ou intègre des fonctions déjà connues. Cette réutisabilité
(mot qui n’existe pas encore officiellement – reusability en anglais) n’est possible que si les conceptions sont
assez générales, bien documentées et pouvant évoluer avec la technologie disponible.
Les avancées continue de l’industrie électronique implique des nouveaux besoins méthodologiques et des
contraintes plus fortes pour les outils de conception. Les technologies sub-microniques rendent plus complexes
les simulations car les modèles de transistors s’éloignent des phénomènes physiques.
Devant l’évolution rapide des besoins en nouveaux modèles de transistor on ne peut plus se contenter de
simulateurs à primitives (c’est à dire dont les modèles manipulables sont compilés avec le noyau de simulation).
Il faut disposer de résolveurs génériques de réseaux d’équations différentielles permettant de construire et de
faire évoluer des modèles dans des bibliothèques externes. L’évolution, la maintenance s’en trouvent grandement
améliorées.
Les systèmes n’intègrent plus seulement de l’électronique mais aussi des capteurs ou des actionneurs (circuit
contenant un accéléromètre pour les air-bags, DMD ou micro miroirs des vidéoprojecteurs de nouvelle
génération, …). Ces possibilités nouvelles de la technologie doivent être prises en compte par les langages de
modélisation et les simulateurs associés
La synthèse analogique est le serpent de mer de l’électronique moderne. L’objectif est de définir un système par
ses caractéristiques recherchées et de laisser un programme concevoir l’objet voulu comme en numérique. On en
est encore loin et les recherches universitaires se poursuivent. L’appui sur un standard serait un plus indéniable
pour dynamiser ces efforts.
10
L’industrie est d’autant plus performante et dynamique qu’elle peut s’appuyer sur des standards reconnus et
acceptés (qui se souvient des très bons formats vidéos Betamax ou V2000 devant le VHS plus limité mais
reconnu comme standard ? Qui utilise encore le BeBOP – téléphone de ville analogique ?).
Le monde de la conception électronique a vu grandir dans les années 80 et 90 une tour de Babel de langages de
description de matériel. Chaque métier avait ses formalismes et les traductions étaient obligatoires à chaque
étape de la conception. Les efforts étaient alors morcelés et les investissements fragiles ; une société qui basait
ses développements sur le langage d’une société qui disparaissait à la faveur d’une crise ou d’une fusion devait
reprendre intégralement ses conceptions et se trouvait dans l’impossibilité de réutiliser le passé. De plus les
échanges avec les sous-traitants, les donneurs d’ordre devenaient quasiment impossibles.
Pour la pérennité des investissements il devenait nécessaire, voire indispensable, que la situation soit clarifiée.
De la même façon les concepteurs de circuits intégrés étaient, il y a quelques années, encore très dépendants des
fondeurs (les fabricants de circuits intégrés) puisque c’est eux qui fournissaient les outils de conception.
Ce n’est que si la communauté s’appuie sur un environnement cohérent que les échanges deviennent
naturellement possibles et que les travaux de recherches profitent à tous. De plus, une industrie de service liée au
modèles peut voir le jour seulement si tout le monde parle le même langage. Cette nouvelle activité nommée IP
(pour Intellectual Property) qui consiste à fournir des modèles à des tiers n’est possible que si une
standardisation est effective.
11
Chapitre 2 : La naissance d'un standard
2.1 Histoire, nécessité, genèse
Au début des années 80, devant le foisonnement des méthodes de description (plus de 80), le DoD, Département
de la défense américain, lance un appel d ‘offres pour la définition d’un langage de description de matériel
numérique (HDL). En effet, pour expertiser les réponses des fournisseurs aux demandes d’équipement et pour
pouvoir suivre, documenter et maintenir les projets en cours, le DoD doit utiliser de plus en plus de spécialistes ;
la comparaison des solutions proposées devient difficile et le risque d’être inféodé à un fournisseur est
stratégiquement inacceptable.
Au même moment la DARPA gère des projets de recherche nationaux (l’équivalent des projets européens
Eureka ou Esprit de l’époque). L’un d’entre eux est nommé VHSIC (Very High Speed Integrated Circuit) et un
de ses sous-produits est le langage VHDL 7.2 (VHSIC-Hardware Description Language). C’est ce langage que le
consortium IBM/Texas Instruments/Intermetrics propose à la DoD. Il est accepté et devient le standard interne
pour la réponse aux appels d’offres du département de la défense. Il s’inspirer de façon ouverte d’ADA.
En effet, quelques années auparavant le même problème avait été soulevé avec les langages informatiques et une
procédure identique mais internationale avait permis de choisir le langage ADA issu de l’université française (les
Français sont souvent en avance pour l’informatique conceptuelle, de haut niveau et universitaire, les Américains
étant plus présents pour la facette commerciale de la chose !). Pour éviter que ne se reproduise ce petit camouflet
pour l’industrie américaine les appels d’offres pour le HDL et les contrats des développements associés seront
classés « sensibles » et ne pourront sortir des Etats-Unis.
Quelques années plus tard, en 1985, le DoD met VHDL 7.2. Dans le domaine public et propose à l’IEEE de
transformer le langage en norme, chose faite le 10 décembre 1987 sous le nom peu commercial de IEEE 1076-
1987. Le langage sera plus connu sous le nom naturel de VHDL ou VHDL’87.
Les premiers outils seront produits par Intermetrics pour un coût de 700 KF (disponibles en France seulement
après que l’autorisation d’exporter ces technologies sensibles eut été obtenue). Un petit outil a très vite été
proposé sur PC sous DOS pour quelques milliers de francs puis sous Windows 1.1 pour 10KF par ce qu’on
appellerait maintenant une start-up : Model Technology. Cette société est certainement devenue le leader
mondial pour les compilateurs/simulateurs VHDL et a été racheté par Mentor Graphics.
L’IEEE privilégie la normalisation par les acteurs. Ainsi chaque homme du métier peut (et devrait) donner son
point de vue. On est loin de l’état d’esprit où un appareil d’état édicte des normes (en collaboration avec la
profession dans le meilleur des cas) pour application obligatoire.
Une proposition de norme passe par un ensemble de procédures administratives (voir www.ieee.org ou
www.vhdl.org) permettant de s’assurer du sérieux, de l’indépendance, de la cohérence de la construction.
Chaque norme doit repasser par toutes ses étapes tous les 5 ans pour assurer la vie du standard. Ainsi le VHDL
original a été re-normalisé en 92. Des retards font que la nouvelle mouture n’a été disponible qu’en 1993 sous le
nom IEEE 1076-1993 ou VHDL’93. Les modifications étaient minimes mais la décision a été prise au même
moment de lancer un effort pour la définition d’un sur-ensemble de VHDL pour prendre en charge l’électronique
analogique ; le sub-par 1076.1.
Au cours de la renormalisation de 98 (arrivée à son terme en 99 – voir encadré), le sub-par 1076.1 a été intégré
dans la norme de VHDL’93 devenu VHDL-AMS. C’est un sur-ensemble de VHDL’93 permettant de traiter la
modélisation analogique de haut niveau compatible avec les modes de description utilisés en numérique.
Cette renormalisation contractuelle de 98 (93 + 5 ans) pour préparer VHDL-A a vu l’antagonisme de deux
« camps » (officieusement autour des deux gros vendeurs de CAO) défendant chacun son point de vue et les
développements internes déjà effectués. Ainsi deux propositions indépendantes ont été faites à l’organisme de
coordination. Ces deux propositions ont reçu des noms de code : JADE et OPAL et ont été soumises à des
12
experts indépendants (peut-on vraiment l’être dans un monde si fermé ?). Après beaucoup de discussions il a été
décidé d’intégrer les meilleurs choses de chacune des propositions dans la version finale.
Comme en parallèle CADENCE avait mis son langage pour le numérique VERILOG dans le domaine public et
convaincu l’IEEE de lancer un effort de normalisation vers VERILOG-A pour l’analogique, le nom de
l’extension de VHDL a été modifié en cours de route pour VHDL-AMS (pour Advanced and Mixed Systems).
Ce processus long a donc débouché, avec un an de retard, sur le standard VHDL’99 ou VHDL-AMS.
Contrairement à un langage informatique classique, un HDL ne vise pas forcément une exécution. Il sert à
décrire du matériel, comme son nom l’indique, avec pour objectifs la spécification, la modélisation, la
simulation, la documentation, la synthèse logique, la preuve formelle ou l’extraction (LVS) … Son utilisation
effective dépend de l’outil avec lequel on l’associe.
Dans un langage informatique l’information est transportée par des variables d’usage dynamique alors que dans
un HDL on définit des signaux qui servent de façon statique à modéliser des équipotentielles. L’information
associée à ces signaux peut être datée et c’est l’histoire de celle-ci qui permet de construire les chronogrammes.
Les variables, avec un langage informatique, sont traitées par des procédures (sous-programmes ou fonctions)
qui sont appelées, exécutées et oubliées. La mémoire nécessaire (avec les variables) est allouée dynamiquement.
Dans un HDL, l’information est transformée par des composants qui sont instanciés (utilisés) de façon statique et
reliés par des signaux. Ils permettent de modéliser des composants matériels et n’ont aucune raison de
disparaître.
Dans un HDL le traitement du temps fait partie intégrante de la sémantique des modèles. Il est traité de façon
rigoureuse par l‘environnement de simulation. Dans le cadre d’un langage informatique, c’est toujours une
construction spécifique interne à la description qui permet de « simuler » l’avancement du temps.
VHDL possède des signaux et des composants, possède une solide sémantique du temps mais a aussi des
variables et des procédures. C’est un HDL doublé d’un langage classique.
Depuis 1969, SPICE et ses variantes se sont implantés dans les entreprises. C’est un simulateur analogique à
primitives, c’est à dire que les modèles simulables sont compilés avec le noyau de simulation. Les systèmes à
modéliser sont sous forme de netlist de ces primitives. On comprend que l’évolution des modèles de base ne soit
pas très souple. Le langage initialement associé au simulateur est très frustre et a connu des améliorations tout en
restant de bas niveau.
Comme SPICE est dans le domaine public beaucoup d’outils universitaires ou industriels s’en sont inspirés d’où
l’apparition d’énormément de jargons et de variantes.
La société ANALOGY propose depuis quelques années le langage MAST et le simulateur mixte SABER
(Algorithme propriétaire CAVALERAS). Cet environnement est très utilisé en mécatronique* et magnétisme.
La société CADENCE, propose le langage SPECTRE-S couplé avec VERILOG, puis depuis 98 le langage
VERILOG-A.
Avec la collaboration d’ANACAD (société issue du CNET, centre de recherche de France Télécom, qui produit
le simulateur analogique ELDO), MENTOR-GRAPHICS proposait en 98 le simulateur HDL-A qui s’inspirait
des travaux préliminaires du groupe de normalisation.
Tous ces outils sont plus ou moins propriétaires et n’assurent pas les avantages d’une norme.
Depuis l’hiver 1999, la société MENTOR-GRAPHICS avec sa filiale ANACAD propose l’environnement ADV-
MS prenant en charge une grande partie de la norme grâce à l’analyseur de code (parser) de chez LEDA et au
13
simulateur ELDO. La société DOLPHIN INTEGRATION propose le simulateur SMASH 4.2 qui prend en
charge VHDL-AMS (en grande partie) depuis 2000. La société ANALOGY (AVANTI !) propose
l’environnement TheHDL prenant en charge le VHDL-AMS. (plus de détails au chapitre 7)
Attention : le paragraphe suivant risque d’être indigeste pour être assez général. Toutes les notions seront
développées dans la suite. (n’hésitez pas à aller prendre un café, un bol d’air avant de l’aborder)
VHDL-AMS permet de décrire des modèles multi-abstractions, multi-disciplines, hiérarchiques à temps continu
et à événements discrets dans des librairies externes. Il permet de gérer aussi bien en numérique qu’en
analogique les abstractions comportementales (la fonction), structurelles (la netlist de modèles) et signal-flow
(sous forme de boites noires). Les modèles analogiques sont exprimés sous forme d’équations différentielles
ordinaire (par rapport au temps). On peut exprimer des transformées de Laplace et en Z. Les approches
spectrales et en bruit son exprimables simplement. La sémantique de connexion des modèles analogiques est
basée sur les lois de kirchoff généralisées (égalité des efforts, somme des flux ègale à zéro) pour des couples
d’unités de type tension-courant, température-quantité de chaleur, distance-force, rotation-couple, champ
magnétique-flux magnétique, … dont le produit est une puissance.
L’environnement de simulation associé doit être capable d’être un résolveur général de réseau d’équations
différentielles à modèles externes (opposé au simulateur à primitive du type de SPICE). En fonction de l’outil on
doit pouvoir retrouver les modes d’analyse de SPICE (DC, transient, AC, noise, Monte-Carlo,…)
Les modèles écrits en VHDL-AMS ne peuvent pas être exprimés avec des équations différentielles d./dx avec x
différent de t. Les modèles « géométriques » sont donc difficilement manipulables.
La sémantique de connexion est figée par la norme et n’est pas accessible à l’utilisateur. D’autres projets plus
ambitieux laissaient entrevoir cette possibilité (MHDL notamment).
Ces limitations font l’objet d’efforts de réflexions pour la renormalisation prévu en 2004.
Avantages commerciaux :
Le fait de disposer d’un langage commun à tous les acteurs permet la naissance de l’IP (Intellectual Property).
Les investissements sont plus sûrs du fait d’un standard industriel, de l’indépendance par rapport au fondeur (au
moins en front-end) et l’indépendance par rapport à un fournisseur d’outils de conception assistée par ordinateur.
De plus les ingénieurs sortent des écoles formés à ces techniques et leur mo bilité est améliorée.
Avantages techniques :
Le langage est moderne, puissant et général. Il est d’une très bonne lisibilité, il permet une haute modularité avec
un typage fort (chaque objet doit être défini par un type) et supporte la généricité (le fait de pouvoir exprimer un
modèle avec des paramètres qui ne seront connus qu’au moment de l’utilisation effective). Le temps et son
utilisation sont solidement définis. La modélisation des conflits est laissée à l’utilisateur (fonction de résolution :
modèles de court-circuits et de conflits de bus). Les ressources sont nombreuses dans une communauté large et
active. Les activités de normalisation associées sont très nombreuse et entretiennent un standard vivant.
Inconvénients :
Le langage est puissant et général donc complexe (mais pas compliqué), les constructions possibles sont
nombreuses et les premiers pas sont assez difficiles.
Il possède des limitations intrinsèques assez contraignantes et est un peu bâclé sur certains points (les méthodes
d’entrées sorties par exemple). La norme est assez «discrète » sur quelques points qui gagnerait à être éclaircis.
Pour l’instant, les simulations sont prisent en charge par des simulateurs existants pour lesquels on a construit un
analyseur de code spécifique. Le support de la norme n’est donc pas encore complet et les constructions les plus
avancées ne sont pas encore accessibles. Il n’existe pas de simulateur spécifique (natif) et les performances
temporelles s’en ressentent. Les outils sont coûteux et ne se répandent pas très rapidement.
Les avantages l’emportent sur les inconvénients, qui ne sont pour certains d’entre eux que transitoires, et
l’implantation de ce langage dans la communauté semble incontournable techniquement et commercialement.
Petite digression : les structures comparées d’un simulateur analogique et d’un simulateur numérique
14
Cet encadré pour essayer de montrer les différences conceptuelles et en complexité des deux mondes et faciliter
la compréhension de certaines difficultés présentées dans les chapitres suivants.
Un simulateur numérique est basé sur l’exécution conditionnelle et itérative d’équations booléennes
interdépendantes dans un temps discrétisé par l’intermédiaire d’événements (changement d’états datés). Le
modèle est un ensemble de sous-modèles définis par des équations booléennes reliés par une netlist.
Un simulateur analogique est basé sur la résolution des équations de kirchoff à chaque t. (Remarque : Il existe
des variantes mais la simulation de systèmes complexes repose toujours sur des techniques approchant celle qui
est sommairement décrite ici. Le modèle est constitué des équations de branches (loi des composants
éventuellement non-linéaires, non stationnaires, …) et des équations de structure (prise en charge par les lois de
Kirchoff)
Cet encadré permet de rappeler aux lecteurs à quoi correspondent les analyses de type SPICE auxquelles on fait
référence.
Analyses DC
.OP : point de repos/polarisation (convergence ?) {v,i} du circuit avec C = circuit ouvert / L = court circuit
(toujours effectué avant une autre analyse)
.SENS : Sensibilité du point de repos (variation d’un paramètre)
.DC : Plusieurs OP dans la même simulation (sweep)
.TF : Fonction de transfert; sortie/entrée en petit signal (calcul dvout /diin , dvout /dv in , diload/dv in , diout /diin )
Analyses AC
.TRAN : Analyse grand signaux temporelle
(difficulté de convergence possible / choix d’algorithme d ’intégration numérique / pas (step) d’intégration
variable géré automatiquement avec spécifications tmax-tmin / temps à simuler spécifié à l’avance)
.AC : Analyse fréquentielle linéaire (petit signal autour d’un point de repos)
.NOISE : Analyse fréquentielle avec sources de bruit
.DISTO : harmonique ou de phase, intermodulation, cross modulation, cross-over (.TRAN+.AC(local))
.FOUR : Analyse de fourier (distortion fort signal = .TRAN+.FOUR)
15
Partie II : Le langage et son utilisation
Avertissements :
Le langage IEEE 1076-1999 est présenté dans les chapitres 3 et 4. Nous avons
décidé de scinder la présentation en deux de façon à faciliter l’approche : Le
chapitre 3 présente les généralités permettant de faire de la modélisation simple
mais effective tandis que le chapitre 4 présente les méthodes plus avancées
proposées par le langage.
16
Chapitre 3 : Présentation générale du langage
Un modèle VHDL-AMS est constitué de deux parties principales : la spécification d’entité (par abus de langage,
l’entité - mot clef : entity) qui correspond à la vue externe du modèle et l’architecture de l’entité (mot clé :
architecture), la vue interne du modèle.
La spécification nommée de l’entité permet, après appel de bibliothèques utiles (mot clef : LIBRARY) et
spécification du contenu à exporter (mot clef : USE) de définir les paramètres génériques (constantes à valeurs
différées) et les ports (mot clef : PORT) par lesquels l’entité pourra recevoir et envoyer de l’information à et vers
son environnement. Les différentes informations pouvant être échangées sont supportées par des ports de type
SIGNAL (pour l’information à événements discrets), QUANTITY (pour les informations analogiques orientées)
et TERMINAL (pour les informations analogiques de type nœuds de connexion). De plus une spécification
d’entité permet de définir un ensemble d’instructions passives, c’est à dire ne modifiant pas l’information
numérique ou analogique (« instructions de service »).
L’architecture de l’entité permet, après une zone de déclaration, de définir le fonctionnement du modèle par
l’intermédiaire d’instanciations de composants (c’est à dire en définissant une netlist d’objets), d’instructions
concurrentes permettant de manipuler l’information numérique et d’instructions simultanées mettant en jeu les
valeurs analogiques du modèle. L’architecture peut manipuler les informations disponibles sur les ports de
l’entité. L’intérêt de VHDL-AMS est que toutes ces instructions peuvent cohabiter, offrant ainsi un support à la
multi-abstraction [MA] et à la conception mixte [CM]. Une entité peut avoir plusieurs architectures
simultanément [TM][MA][SE].
Une entité qui ne définit pas de port de connexion est souvent appelée un « banc de test » ou testbench. Le
modèle interne ne pouvant être excité de l’extérieur doit être autonome pour son fonctionnement. La plupart des
environnements de simulation ne peuvent prendre en charge que des modèles dont le point d’entrée est un
testbench.
Une spécification d’entité est compilable seule avant de connaître l’architecture associée. On dit d’une partie de
code autosuffisante pour être compilée qu’elle est une unité de conception ou UC. De la même façon
l’architecture (de l’entité) est compilable seule si l’entité à laquelle elle se réfère est déjà compilée. On parle
alors d’UC secondaire.
En fait, il existe 5 unités de conception, 3 primaires et 2 secondaires : l’entité et chacune de ses architectures, la
déclaration de paquetage et le corps de paquetage, la configuration.
Toutes les notions de cette présentation générale seront précisées dans la suite de ce chapitre et dans le suivant.
Architecture de l’entité
Zone de déclaration
Corps de l’architecture
Instanciations de composants [support de la hiérarchie]
Instructions concurrentes (dont les process) [traitement à événements discrets]
Instructions simultanées [traitement temps continu]
Fig 3.1 : Les grands constituants d’un modèle VHDL-AMS
17
-- Ce modèle est purement illustratif
-- La compréhension fine de sa structure n’a pas d’importance ici
LIBRARY Disciplines;
USE Disciplines.electric_systems.ALL;
ENTITY exemple IS
generic (tplh : time := 4 ns) ;
port (signal sig_ext:out real; terminal vp,vm : electrical);
Begin
Report « OK » ;
END ENTITY exemple;
L’intérêt de séparer la spécification de l’entité de son architecture présente une souplesse qui n’est pas forcément
directement évidente. Faisons l’hypothèse que le cahier des charges d’un sous-système est défini par un modèle
purement comportemental, c’est à dire qui définit le comportement attendu sans a priori sur l’implémentation
physique. Une fois l’analyse des besoins effectuée on sait quels sont les ports d’entrée-sorties nécessaires. La
spécification d’entité peut alors être écrite, compilée et mise à disposition du reste des intervenants. Elle peut
servir de support au choix du boîtier et, pourquoi pas, au routage du PCB alors que l’architecture n’est pas
encore définie [IC].
L’intérêt de disposer de plusieurs architectures pour le même modèle est extrêmement important. Toujours avec
le même exemple, le modèle comportemental (ENTITY + ARCHITECTURE) a été écrit et validé. Il sert alors
de référence (de cahier des charges) pour le reste de la conception. Le travail étant plus avancé on a conçu une
architecture tenant compte des aspects technologiques effectifs. On peut alors comparer en co-
simulation l’adéquation des deux architectures [VT].
Si un système est constitué de N sous-ensembles interconnectés, l’équipe qui doit concevoir le kème peut le faire
tout en conservant les connexions et les spécifications des entrées sorties des autres sous-ensembles définis au
niveau comportemental [IC][VT][SE][TD]
Tous les autres intervenants qui avaient « instancié » l’entité et son architecture au niveau comportemental
peuvent maintenant choisir une architecture plus précise, par exemple un structurel de portes de base, sans rien
changer à la netlist décrivant le système [TD][MA][SH].
18
3.2 Prise en charge par les simulateurs
La préparation d’un modèle pour la simulation passe par la phase d‘élaboration. C’est à ce moment que les
constantes et les paramètres génériques sont fixés et que la hiérarchie de description permet de récupérer les bons
modèles dans les bibliothèques de ressources. A ce moment toutes les instructions concurrentes (équations
booléennes) sont ramenées au même niveau dans une mer de processus interconnectés et sont prises en charge
par le simulateur à événements discrets et toutes les instructions simultanées (équations différentielles) sont
regroupées dans une structure de données pour le simulateur analogique. Le modèle sera alors pris en charge, la
plupart du temps, par deux noyaux de simulations que l’on devra synchroniser (voir instruction BREAK). Le
simulateur analogique produira des ASP (Analog Simulation Point) tandis que le simulateur « numérique »
produira des LSP (Logic Simulation Point).
La hiérarchie de représentation n’est donc qu’une vue pour faciliter l’approche du concepteur humain mais n’est
d’aucune utilité pour l’environnement de simulation. Certains travaux universitaires utilise la hiérarchie de
conception pour optimiser les temps de calcul.
Ce n’est pas à l’utilisateur de gérer le contenu des bibliothèques. Une compilation qui aboutit sans erreur met à
jour la bibliothèque cible. Les bibliothèques contiennent les unités de conceptions et sont organisées en deux
niveaux : UC primaires et UC secondaires.
Cette méthodologie permet de s’appuyer sur des bibliothèques contenant des descriptions courtes et hiérarchisées
dont on est sûr de la justesse syntaxique. On peut récupérer de l’information dans des bibliothèques de
ressources (de projet, d ’un fournisseur, de test, …) par les clauses :
LIBRARY ressource_lib;
USE ressource_lib.pack_lib.ALL;
La bibliothèque ressource_lib doit être un nom logique connu de l’environnement de travail et doit contenir une
ressource nommée pack_lib. Le mot clé ALL permet d’exporter tout le contenu de pack_lib.
La bibliothèque WORK est implicitement ouverte et la ligne suivante est donc automatiquement intégrée à tous
les modèles :
LIBRARY work;
D’autres bibliothèques sont prévues par la norme et certaines sont de définition implicite (voir 4.14)
Chaque objet est défini par un identificateur qui permet de le nommer et de le manipuler. VHDL-AMS permet
d’utiliser une suite de lettres et de chiffres qui commence forcément par une lettre. Le langage ne fait pas la
différence entre les minuscules et les majuscules (no case sensitive). Il est possible d’utiliser des caractères
spéciaux (graphiques) ou de forcer l’utilisation des majuscules dans un identificateur est les entourants par des
backslash (\). Par exemple BUS et bus sont identiques alors que \COUNT\ et count sont deux identificateurs
différents. Les identificateurs faisant apparaître un backslash sont appelés indentificateurs étendus.
19
Il est possible de poser des traits bas (par exemple : Rdf_232) pour faciliter la lecture des identificateurs. Les
traits bas doubles, les traits bas au début ou à la fin sont interdits.
Le commentaire est de type ligne, il commence par -- et se termine avec la fin de la ligne. Il n’existe pas de
commentaire bloc en VHDL-AMS.
Les valeurs des objets pourront être définies par des littéraux ou par l’affectation d’autres objets. Les littéraux de
type caractère peuvent être exprimés grâce aux 95 caractères imprimables sur les 128 caractères du code ASCII.
Ils seront notés entre apostrophes. (‘a’, ‘b’, ’Q’, …). Les littéraux de type chaînes de caractères seront exprimés à
partir d’une suite de caractères entre guillemets. L’opérateur de concaténation de chaîne est le & (et commercial
ou ampersand).
“C ’est”&
“possible sur deux lignes”
Les littéraux décimaux seront exprimés avec les chiffres, les réels devront obligatoirement faire apparaître le
point décimal. Il est possible d’exprimer les nombres en notation scientifique. Il est possible de poser un trait bas
n’importe où dans l’écriture pour faciliter la lecture.
Il est possible d’utiliser n’importe quelle base pour exprimer la valeur d’un littéral. Il suffit de mettre la valeur de
la base (en base 10) de poser un #, d’écrire la valeur dans cette base et de fermer le #. Dans certains cas, il peut
être plus simple de construire la valeur d’un entier par sa constitution en base deux (par exemple si cet entier
représente une configuration particulière d’un bus de données).
Pour faciliter l’expression de vecteurs de bits, il est possible de les exprimer grâce à des chaînes plus compactes :
B«000110» est un vecteur de bit qui vaut (‘0’, ‘0’, ‘0’, ‘1’, ‘1’, ‘0’)
0«06» est le même vecteur de bit
X«255» est le vecteur de bit (‘1’, ‘1’, ‘1’, ‘1’, ‘1’, ‘1’, ‘1’, ‘1’)
En VHDL-AMS tous les objets utilisés sont typés (strong typing). Cette méthode permet l’initialisation fiable et
augmente le pouvoir de vérification du compilateur. Un type définit les valeurs et les opérations possibles sur les
objets qui y sont associés. Il existe des types scalaires qui ne porte qu’un seul élément à la fois, ces types sont
ordonnés, et des types composites qui portent plusieurs éléments à la fois.
Les types scalaires sont les entiers (integer), les réels (real), les types physiques(physical) et les énumérés
Les types composites sont les vecteurs et tableaux (array) et les enregistrements (record).
Les déclarations de type commencent toujours par le mot clef TYPE suivi du nom du type puis du mot clé IS
suivi des contraintes. Ce sont ces contraintes qui définiront plus précisément le type.
20
Enuméré : TYPE enum_type IS (bleu, blanc, rouge) ;
Un objet défini sur le type enum_type pourra transporter les valeurs abstraites bleu, blanc ou rouge. Ce type
définit une relation d’ordre et dans ce cas on a rouge qui est supérieur à blanc lui-même supérieur à bleu. Le
même littéral peut apparaître dans deux définitions, on dit alors que l’énuméré est surchargé.
La définition d’un entier suit le même schéma avec une contrainte qui restreint les valeurs possibles. La
définition d’un flottant (réel) sera très proche. On notera simplement le point décimal dans la contrainte.
Le type physique est une originalité de VHDL, il permet de manipuler des grandeurs avec leurs unités. Il est
déclaré par l’intermédiaire d’un nom de type, d’une contrainte d’étendue, d’une unité de base et d’un ensemble
de facteurs entiers de conversion. Le facteur de conversion entier nous force donc à choisir la plus petite des
unités comme unité de base. On remarquera que l’espace est obligatoire entre le facteur de conversion et l’unité.
Un objet qui sera du type distance ne pourra porter que des valeurs associant un entier et une unité.
Les expressions suivantes sont légales :
Deux types ayant la même définition mais des noms différents sont incompatibles ; C’est à dire qu’un objet
défini sur un des types ne pourra pas être affecté par un objet défini sur l’autre.
A/ Vecteurs
Un type vectoriel permet de rassembler plusieurs valeurs de même type. Il sera défini par un ou des index (entier
ou énuméré) et les contraintes associées ainsi que par le type porté. Un tableau en VHDL-AMS ne peut
transporter des fichiers.
La déclaration suivante est un type tableau d’entier dont l’indice peut prendre les valeurs 3 à 45.
La déclaration suivante est un type tableau non contraint de réels. La contrainte sur l’indice ne sera connue qu’au
moment de l’utilisation du type. Le caractère <> se lit BOX
Le type suivant est un tableau d’indice énuméré qui contient des entiers.
21
Si A est de type enum_vec on a A(bleu), A(blanc) et A(rouge) qui portent chacun un entier.
On peut avoir autant d’indices que nécessaire et définir des tableaux complexes. L’exemple suivant est un type
permettant de définir une matrice adressée par un énuméré et un entier (non contraint), chaque position de la
matrice contenant un vecteur de réel.
B/ Enregistrements
A.champ_1,
A.champ_2
A.autre_champ
Il est possible de définir des enregistrements de vecteurs, des vecteurs de vecteurs ou des vecteurs
d’enregistrements. Comme les types composites peuvent contenir des pointeurs, ils donnent accès aux types
complexes comme les listes chaînées, doublement chaînées, les arbres, ….
Ces types sont beaucoup moins utiles dans la modélisation de matériel. Seules les variables peuvent être définies
comme des fichiers ou des pointeurs (à l’exclusion des autres objets).
NEW index_ptr ;
La norme fournit des types prédéfinis. Dans les types suivants integer’high et integer’low sont des attributs du
type integer (voir 3.10) qui rendent les valeurs des entiers le plus grand et le plus petit codables par la machine
utilisée.
22
bit TYPE bit IS (‘0’, ’1’) ;
std_ulogic TYPE std_logic IS (‘U’,’0 ’,’1’,’Z’,’X’,’H’,’L’,’W’,’-’) ;
bit_vector TYPE bit_vector IS ARRAY (natural RANGE<>) of bit ;
boolean TYPE boolean IS (false, true)
severity_level TYPE severity_level IS (NOTE,WARNING,ERROR,FAILURE) ;
character TYPE character IS (NUL, SOH,…, ’a’, ’b’, …, ‘~’,DEL) ;
string TYPE string IS ARRAY (positive range <>) of character ;
time TYPE time IS RANGE integer’low TO integer’high UNITS fs;
ps = 1000 fs ; ns = 1000 ps ; us = 1000 ns ;
ms = 1000 us ; sec = 1000 ms ; mn = 60 sec ; hr = 60 mn;
END UNITS ;
Quand on fait de la simulation logique, le type de base (0,1) est trop simple pour pouvoir illustrer les
comportements réels. Comment, par exemple, détecter un court-circuit ou une sortie en haute impédance. Pour
analyser ces phénomènes le MVL4 (Multi Value Logic 4 levels) a été proposé (0,1,X,Z).
Avec ce type on ne pouvait pas s’assurer que l’initialisation avait été faite correctement. On proposa d’ajouter U
(Unitialized) Quand un niveau logique est fourni à travers une longue ligne conductrice (et résistive)
l’équipotentielle est protégée par la résistance, on définit alors en plus le 1 logique faible (H=High) et le 0
logique faible (L=Low). Quand ils se retrouvent reliés le conflit est non destructif et devient faible (W=weak).
Par définition un niveau faible est absorbé par un niveau fort. Pour des activités de simplification logique il faut
pouvoir exprimer le fait que cet état n’est pas important (- = don’t care).
Ainsi est né le MVL9 ou std_ulogic normalisé sous la référence IEEE 1164. Il correspond à l’énuméré
(‘U’,’0 ’,’1’,’Z’,’X’,’H’,’L’,’W’,’-’). Les fonctions logiques sur ce type sont définies par des tables 9x9 et
permettent de surcharger les opérateurs du noyau.
D’autres tentatives ont été essayées et il existe des systèmes à 12, à 128 niveaux logiques ou encore des systèmes
d’intervalles où les niveaux ne représentent plus des valeurs mais des plages de « tension ».
3.5.5 Sous-types
Les sous types permettent de définir des sous-ensembles de valeurs à partir d’un type de base en gardant la
compatibilité avec celui-ci. Le mécanisme de déclaration général est de la forme :
Par exemple :
Un objet défini sur le type real sera affectable par un objet défini sur le type signal_value. Le contraire est vrai
seulement si la contrainte d’étendue est respectée. Dans le cas contraire une erreur sera générée à l’exécution.
Les sous types qui font apparaître un nom de fonction dans leur déclaration sont appelée sous types résolus et
permettent de résoudre des conflits d’affectation (voir 4.10). La tolérance est définie par l’intermédiaire d’une
chaîne de caractères qui servira dans l’environnement de simulation pour les tolérances de convergence de
l’algorithme de simulation analogique. (à notre connaissance aucun outil ne met en œuvre ce mécanisme à
l’heure actuelle)
Les sous types sont à définition dynamique (contrairement au types) et un objet associé au sous-type suivant
verra ses contraintes évoluer en fonction de la valeur de max si celui-ci est variable.
23
SUBTYPE mot IS bit_vector (1 to max) ;
En VHDL-AMS tous les objets sont initialisés implicitement ou explicitement. Contrairement à d’autres
langages il est impossible d’avoir des comportements aléatoires par faute d’initialisation.
La règle définie dans la norme est qu’un objet prend la valeur la plus à gauche de son type sauf pour les quantités
qui prennent la valeur 0.0 :
Un type peut être incomplètement défini, le compilateur attendra le dernier moment pour reporter l’erreur.
Le coût d’une erreur varie exponentiellement avec la phase de conception où elle est détectée.
Anecdote : Il y a quelques années l’auteur reçoit une lettre pour lui signaler que son véhicule (d’une grande
marque française) devait impérativement, comme tous les modèles du même type, être déposé dans une
concession de la marque pour la modification (gratuite) du faisceau électrique. En effet l’équipotentielle qui
commandait le ventilateur de radiateur n’avait pas été équipée de fusible et après quelques incendies dus au
blocage du moteur du ventilateur, le constructeur a décidé de modifier tous les véhicules présentant ce défaut en
insérant un porte fusible sur le fil incriminé.
Les coûts induits par cette opération sont énormes : le porte fusible et son acheminement, le mailing vers tous les
possesseurs du véhicule (même d’occasion), les heures de main d’œuvre pour l’intervention, le prêt éventuel
d’un véhicule de remplacement, …, et surtout le déficit d’image de marque et la prise de responsabilité pénale en
cas de gros sinistre.
Ce coût est à comparer à celui qui aurait découlé d’une vérification formelle sur un modèle du faisceau
électrique. L’outil de CAO aurait pu présenter un message du genre : « Warning : The wire N0034 is
unprotected », le concepteur aurait alors pris sa gomme (électronique) et modifié son schéma en insérant un
fusible. Le coût en études aurait été négligeable (quelques heures d’ingénieur) et le coût industriel aurait été noyé
dans la masse.
On se souviendra aussi du benzène dans une eau pétillante, des carters de boîte trop fins d’une autre marque de
voiture, des défauts sur des robots électroménagers, des jouets dangereux, du bug du Pentium 120, …
On dit classiquement que le coût de réparation d’une erreur est multiplié par 10 à chaque fois qu’on franchit une
étape de conception sans la détecter. Alors même si les langages de conception sont très coercitifs, il faut se plier
aux étapes de vérification indispensables à la bonne santé d’un projet.
La notation par agrégat permet de rassembler une ou plusieurs valeurs dans une représentation vectorielle ou
d’enregistrement. Si V1 et V2 sont deux variables entières :
24
(V1,V2) := (1,2) ;
S1 <= (‘1’,’0’,’1’) ;
Utiliser une expression qualifiée, c’est indiquer explicitement le type de l’expression pour aider le compilateur à
lever une ambiguïté possible. Il ne faut pas confondre cette opération avec une conversion de type :
La conversion de type est possible et explicite en VHDL-AMS pour des types « proches ». Il est ainsi possible de
transformer des entiers en réels ou le contraire. La norme ne donne pas de règle pour l’arrondi. La conversion est
possible pour les tableaux s’ils ont la même taille, des indices et des éléments de types proches
(indépendamment du sens des indices – to/downto).
Type_conversion : := type_mark(expression)
Il est possible de convertir un sous-type dans le type dont il est issu de même que l’opération inverse. Quand un
type est converti en sous-type, une opération de vérification des contraintes est effectuée.
L’utilisateur peut toujours écrire des fonctions de conversion pour les autres types. Certains environnements de
simulation font la bijection entre bit et booléens.
Les objets permettent de transporter l’information dans les modèles. Il existe 6 classes d’objets :
3.6.1 Constantes
Permet de stocker, comme son nom l’indique, des valeurs constantes. Les déclarations suivantes permettent de
définir et d’initialiser un réel et un paramètre physique :
L’initialisation des tableaux peut se faire dans l’ordre de la déclaration ou par nommage des indices. Le mot clé
OTHERS est d’utilisation très puissante pour initialiser des grands tableaux et même des tableaux dont on ne
connaît pas la taille.
25
CONSTANT BV0 : bit_vector(15 DOWNTO 0) := (‘1’, ’0 ’,others=> ’0 ’) ;
Avec TYPE truth_table IS ARRAY(std_ulogic, std_ulogic) of std_ulogic ;
CONSTANT tt : truth_table := (other => (others => ‘ 0 ’)) ;
Avec TYPE inst_list IS (read,data,adrr,write) ;
Et TYPE memory_bus IS ARRAY (inst_list) of bit_vector;
CONSTANT mem_bus : memory_bus := (adrr =>X «00AA»,data=>X«FF», read => ‘0’, write => ’1’,
enable => ’1’ ) ;
Les constantes peuvent être initialisées au moment de leur utilisation. Dans la déclaration suivante N ne peut être
connu qu’à l’élaboration (paramètre générique du modèle par exemple). Si la déclaration de constante est à
l’intérieur d’une fonction alors N peut être un des paramètres de celle-ci.
Une constante peut aussi être à valeur différée. La déclaration suivante peut être trouvée dans une déclaration de
paquetage (exportable), l’affectation pourra être effective dans le corps de paquetage (non exportable). Ce
mécanisme est nécessaire quand on veut masquer l’information. La déclaration suivante est donc valide dans ce
contexte :
3.6.2 Variables
Les variables permettent le stockage et la manipulation de valeurs dans un contexte séquentiel. Il est possible,
mais non obligatoire, d’initialiser les variables au moment de leur déclaration :
A := B *C + 3.0;
Les variables sont dynamiques et ne sont utilisables que dans un contexte séquentiel, c’est à dire à l’intérieur des
process.
La norme prévoit, sur l’insistance des informaticiens depuis VHDL’93, la possibilité de variables partagées, c’est
à dire disponibles en lecture-écriture pour les process définis « sous » sa déclaration. Une variable dont la
déclaration comporte le mot clé SHARED est partagée.
La manipulation de variables partagées est très dangereuse car VHDL-AMS ne définit aucun mécanisme de
protection. Faisons l’hypothèse que nous disposons d’une variable partagée A et de deux process P1 et P2
asynchrones (dont les exécutions sont indépendantes). A vaut 3, le process P1 réalise A := A2 et le process P2
réalise A := A+2. Examinons quelques cas de figure :
26
La norme précise : « A description is erroneous if it depends on wheter or how an implementation sequentializes
access to shared variables. ». Ce qui revient à dire que la variable partagée est une construction qu’il faut bannir.
Il faudra se limiter, en cas de nécessité absolue, à des variables partagées consultables par tout l’environnement
mais modifiable par une source unique. Par exemple, si le modèle calcule sa température de fonctionnement, il
faut la mettre à disposition de tous les sous-systèmes en ne la mettant à jour qu’à partir d’un seul endroit.
3.6.3 Signaux
Les objets de classe SIGNAL sont les objets qui transportent les valeurs du simulateur à événements discrets (ou
piloté par les événements - event-driven). Sa déclaration est complexe et sera précisée au 4.10. La règle de
grammaire ci-dessous montre toutes les possibilités (les explications sur la syntaxe de la grammaire elle-même
sont disponibles en annexe).
L’affectation de signal se fait par l’intermédiaire de <= et permet de préciser le retard entre l’entrée et la sortie de
l’affectation. Cette instruction d’affectation et la mécanique associée seront précisées au 3.9.1 et 3.9.2
Un signal est un objet statique (ou rémanent), il est déclarable dans la partie concurrente du langage. Un signal
modélise (symboliquement) les fils entre les portes logiques. Il possède un passé, une valeur courante et un futur
probable. La structure de données contenant ces informations se nomme le pilote (ou driver) du signal.
3.6.4 Terminaux
Un objet de classe TERMINAL ne porte pas de valeur en soi mais permet de nommer des nœuds de connexion.
Il se déclare suivant la règle de grammaire suivante :
Un terminal possède une nature qui est définie par l’association de deux types réels. Les types définiront le flux
(through) à travers et l’effort (across) au bornes du terminal. Le produit des ces deux quantités représente une
puissance. Les règles de connexion des terminaux seront présentées au 3.7.
SUBTYPE v IS real ;
SUBTYPE i IS real ;
NATURE electrical IS v ACROSS i THROUGH gnd REFERENCE ;
Avec Across = effort / through = flux
Les natures disponibles ne sont pas directement définies par le langage lui-même mais par un paquetage IEEE.
L’utilisateur peut donc définir de nouvelles.
27
Electrical : voltage – current (électrique)
Thermal : temperature – heat flow rate (thermique)
Translational : velocity – force (mécanique translation)
Rotationnal : angular velocity – torque (mécanique rotation)
Hydraulic : pressure – volume flow rate (hydraulique)
3.6.5 Quantités
Les quantités sont les containers des valeurs analogiques (à temps continu). Il en existe trois sortes : les quantités
libres, sources ou de branche. Toutes les quantités ont un type issu d’un type réel.
Les quantités sources sont des quantités libres qui possèdent le mot clé spectrum ou noise dans leur déclaration.
Elle seront présentées en détail au 4.7.
Il existe aussi des quantités implicites qui sont créées par l’environnement sans déclaration préalable :
Les modèles compilés peuvent être instanciés dans des modèles de plus haut niveau. Ils sont alors interconnectés
selon les besoins. Le comportement de ces associations sera déduit de la sémantique associée à ces connexions.
28
Dans la spécification d’entité on précise les paramètres génériques et les ports de connexion.
ENTITY exemple IS
generic (par1, par2, par3 : real ; par4 : time := 3 ns) ;
port (signal sig :{in|out|inout|linkage|buffer} real;
quantity q: {in|out} real ;
terminal vp,vm : electrical);
BEGIN
{instructions passives = pas d’affectations de signal}
END [ENTITY] [exemple];
Les modes possibles pour les ports de classe SIGNAL sont in, out, inout, linkage, buffer. Les deux derniers
modes sont apparemment réservés pour des utilisations futures et sont très peu décrits par la norme (et inutilisés
en pratique). Un port de classe signal ne peut être branché que sur un signal ou sur un port de même type, les
modes doivent être compatibles. Un port de mode INOUT est forcément résolu (voir 4.10). Un port de mode
OUT n ’est pas lisible dans l’architecture et un port de mo de IN n’y est pas affectable. Le mot clef OPEN à
l’utilisation permet de laisser ouvert un port.
Dans l’exemple suivant on utilise le mécanisme d’instanciation directe que l’on détaillera (et critiquera) au 3.9.2
et au 4.12. Ici on instancie trois fois le même modèle en le spécialisant (par son label, son paramètre générique et
ses connexions). L’instanciation permet de fabriquer une netlist en connectant les objets par l’intermédiaire de
signaux déclarés localement (les équipotentielles du schéma). On remarquera que les signaux déclarés
localement n’ont pas de mode.
On a: ENTITY testdetector IS
PORT (SIGNAL extin : IN real; extout : OUT real);
END;
LIBRARY disciplines;
USE disciplines.Electromagnetic_system.ALL;
ARCHITECTURE test OF testdetector IS
SIGNAL pin,pout:real;
BEGIN
u1:ENTITY source(pulse_proba) PORT MAP (extin,extout);
-- connexions aux ports de l’entité
u2:ENTITY source(pulse_proba) PORT MAP (pin,pout);
-- connexion aux signaux laocaux
u3:ENTITY source(pulse_proba) generic map(2) port map(open,open) ;
29
-- ports laissés ouverts
END;
-- extin,extout,pin,pout sont des ports réels (actual)
Fig 3.7.1 : connexions de type « event driven »
La connexion de type flot de signal est le paradigme qui est utilisé couramment pour la description des systèmes
sous forme de schémas blocs (ou boite noires), par exemple en automatique. Dans ce cas de figure les sorties ne
sont pas influencées par les entrées (impédance de sortie nulle et d’entrée infinie). Le support de l’information
est à temps continu.
Les ports permettant de mettre en œuvre cette modélisation sont de classe QUANTITY. Ils peuvent être de mode
in ou out. Les objets connectés doivent être de même classe, de même type et mode compatibles.
ENTITY exemple IS
port (QUANTITY Q1 : in real,
Q2 : out real);
END exemple;
On remarquera que les quantités libres déclarées localement n’ont pas de mode.
On a: ENTITY black_boxes IS
PORT (QUANTITY extin : IN real;QUANTITY extout : OUT real);
END;
LIBRARY disciplines;
USE disciplines.Electromagnetic_system.ALL;
ARCHITECTURE test OF black_boxes IS
QUANTITY ploc:real; -- Free Quantity
BEGIN
u1:ENTITY block1(beh) PORT MAP (extin,ploc);
u2:ENTITY block1(beh) PORT MAP (ploc,extout);
END;
Fig 3.7.2 : connexions de type « signal flow »
La connexion de type conservatif correspond aux nœuds où sont reliées les grandeurs de flux et d’effort tout en
conservant la puissance globale. Cette définition est valable pour toutes les disciplines relevant des lois de
Kirchoff généralisées. Sur ces nœuds (connexion de plusieurs terminaux) la somme des flux est nulle alors que
l’effort est commun. Les ports permettant de mettre en œuvre cette modélisation sont de classe TERMAINAL.
Ils ne possèdent pas de mode. Les objets connectés doivent être de même classe et de même nature.
En d’autres termes :
ENTITY exemple IS
port (TERMINAL T1,T2 : electrical); --PAS DE MODE/VALEUR
END exemple;
KIRCHOFF LAW : Si T1 est branché sur T2 et si les aspects ACROSS et THROUGH sont définis alors
ACROSS( T1 ) = ACROSS( T2 )
et THROUGH( T1 ) + THROUGH( T2 ) = 0
Ces équations sont implicites et n’ont donc pas être écrites. C’est le simulateur qui les met en œuvre
automatiquement. Dans l’exemple suivant les lois de kirchoff seront appliquées par le simulateur sur le terminal
local.
30
Avec : LIBRARY disciplines;
USE disciplines.Electromagnetic_system.ALL;
ENTITY block1 IS
PORT (TERMINAL a,b : electrical);
END;
On a: ENTITY kirch IS
PORT (TERMINAL extin,extout : electrical);
END;
LIBRARY disciplines;
USE disciplines.Electromagnetic_system.ALL;
ARCHITECTURE test OF kirch IS
TERMINAL tloc:electrical; -- terminal local
BEGIN
u1:ENTITY block1(beh) PORT MAP (a,tloc);
u2:ENTITY block1(beh) PORT MAP (tloc,b);
END;
Fig 3.7.3 : connexions de type conservatif
En électronique analogique on prend l’habitude de désigner des entrées et des sorties. En fait, les systèmes
peuvent avoir des limitations sur le sens ou la valeur limite des courants les traversants mais formellement les
entrées sorties ne sont que conventions permettant l’étude des systèmes idéalisés. C’est une notion qui est
paradoxalement difficile à faire passer à des étudiants déformés par 10 ans d’idéalis ation.
La théorie des systèmes idéalisés nous interdit de brancher deux sources de tension l’une sur l’autre. Si l’on tient
compte des impédances séries de chaque générateur on peut calculer un point de repos. Si celui-ci n’implique
pas la destruction par une puissance à dissiper trop forte et si les générateurs sont réversibles en courant alors il y
aura un générateur qui fournira de la puissance et l’autre qui l’absorbera. Sur la connexion il n’y donc pas le
besoin de définir de notion d’entrée ou de sortie.
ENTITY exemple IS
GENERIC(k : integer := 3);
PORT (SIGNAL a : in real;
SIGNAL b : out real;
QUANTITY c :in real;
QUANTITY d :out real;
TERMINAL e,f,g : electrical);
END;
3.8 Opérateurs
VHDL-AMS définit 6 classes d ’opérateurs et les niveaux de priorité associés. (L ’évaluation d ’une expression
commence par la priorité la plus haute). Dans l’ordre croissant des priorités :
logic : and, or, nand, nor, xor, xnor, sll, sla, sra, srl, rol, ror
s ’appliquent à boolean et bit, surcharge sur IEEE_1164
Sur les bit_vector :
sll, sla : décalages logiques
31
sra,srl : décalages arithmétiques
rol, ror : rotation
addition : +, -, &
& : concaténation sur type STRING
signe : +, -
Les opérateurs sont surchargeables (4.6) mais leur priorité ne peut être modifiée ; On peut définir une nouvelle
fonction ayant le même nom qu’un opérateur existant mais avec une interface différente. C’est le compilateur qui
choisira la bonne fonction en relation avec le contexte de son utilisation.
Le fonctionnement du modèle détaillé dans l’architecture est exprimé grâce à des instantiations de composants,
des instructions simultanées et des instructions concurrentes. Le PROCESS est une instruction concurrente
définie par l’utilisateur à partir d’instructions séquentielles. Les quatre sections suivantes présentent les
instructions les plus importantes. Le reste des instructions sera présenté au chapitre 4.
Les instructions séquentielles sont évaluées en séquence dans le corps des process. Les instructions principales
sont l’affectation de variable, l’affectation de signal, le wait, l’exécution conditionnelle, l’exécution itérative.
A/ Affectation de variable
Une variable peut être affectée par un littéral, une variable, un signal ou une quantité. Dans tous les cas la
compatibilité de type doit être respectée. Cette affectation est instantanée. Pour les sources de type signaux ou
quantités c’est la valeur à cette date (valeur de l’horloge de simulation) qui est prise en compte. L’affectation
peut se faire pour des structures complexes en une seule instruction du moment que les membres gauche et droit
soit de même type. Le signe de l’affectation est :=. Les exemples suivants sont valides :
B/ Affectation de signal
L’affectation d’un signal est une proposition de transaction dans le pilote de celui-ci. On appelle événement le
fait qu’un signal change de valeur à une date donnée. Une transaction est la prise en compte d’une nouvelle
valeur (même identique) dans le pilote du signal.
32
avec : target ::= name | aggregate
avec : waveform ::= wf_element {,wf_element} | unaffected
avec : wf_element : := value_expression [after time_expression]
Cette instruction propose la transaction (‘0’, 3 ns) dans le pilote du signal S. C’est la politique de filtrage-
abandon qui décidera si cette transaction sera conservée comme un événement qui sera pris en compte dans 3
ns. Si tel est le cas, quand l’horloge de simulation avancera de 3 ns par rapport au temps courant, S prendra la
valeur ‘0’.
Les sources possibles pour calculer value_expression de la règle de grammaire sont les littéraux, les constantes,
les variables, les signaux, les quantités et les fonctions sur tous ces objets. L’affectation par agrégat est aussi
possible. Si l’affectation est construite avec une forme d’onde (waveform) les délais des différents éléments
d’ondes doivent être dans l’ordre croissant. Dans le cas contraire une erreur est générée à la compilation si les
temps sont des constantes évaluables à ce moment là.
Un cas particulier d’affectation est l’affectation à temps nul. La théorie de la simulation démontre qu’un modèle
ne peut être simulé que s’il peut prévoir son avenir, c’est à dire qu’à une date donnée il faut qu’on puisse
proposer une valeur dans son futur. Une affectation à temps nul est donc inutile voire source d’instabilité des
modèles bouclés (de toute façon non physique puisque acausal). La syntaxe suivante est pourtant permise :
Le simulateur met en œuvre le mécanisme dit « delta-time ». Le temps, géré par le simulateur piloté par les
événements de VHDL, est manipulé comme un couple (temps, delta). Le temps et delta son codés sur des entiers
positifs. Si une affectation à temps non-nul est effectuée à la date To :
La transaction résultante sera datée (To + Td, 0). Si la même affectation est effectuée à temps nul, la transaction
résultante sera datée (To,1). Comme l’algorithme de simulation repose sur une liste ordonnée d’événements, la
relation d’ordre suivante est utilisée :
Si un signal avec un delta non nul (k) est la source d’une affectation à temps nul alors la transaction résultante est
datée de (To, k+1). Si un signal avec un delta non nul (k) est la source d’une affectation à temps non-nul avec un
délai Td, alors le compteur de delta est remis à zéro et la transaction résultante sera datée de (To+Td, 0).
On peut voir le fonctionnement du temps sur un graphe à deux dimensions, l’axe horizontal représentant la
croissance du « vrai » temps et l’axe vertical le nombre de delta. Les affectations à temps nul déplacent le point
de fonctionnement verticalement tandis que les affectations à temps non nul ramène le point de fonctionnement
sur l’axe horizontal et le déplace vers la droite.
33
Un signal ne peut être affecté que par une seule source. Dans le cas contraire le compilateur ou le simulateur
génère une erreur. Le cas particulier du signal résolu, c’est à dire du signal associé à une fonction de résolution
des conflits d’affectation sera présenté au 4.10.
Toutes les transactions ne sont pas des événements. La norme définit un certain nombre de mécanismes :
transport, inertie, réjection (3 mécanismes utilisateurs), abandon (mécanisme interne).
Abandon : Quand une transaction est proposée dans le driver d’un signal toutes les transactions avec
une date postérieure sont abandonnées (effacés). Toutes les transactions sont analysées pour ne garder
que des événements. Un waveform est considéré comme une seule transaction.
Filtrage par inertie explicite : target <= reject time inertial valeur after Td ;
Ce mécanisme a été introduit dans VHDL’93 pour corriger l’approche anti-physique du mécanisme de
base. On peut alors préciser la valeur de l’inertie par le temps qui suit le mot clé REJECT. Ce temps
doit être inférieur à Td (celui du premier élément d’onde).
To : 3 / 5 - 10 ns / 1 - 12 ns / 0 - 15 ns
C/ Le WAIT
Cette instruction est certainement la plus importante de la partie numérique. C’est grâce à elle que l’horloge de
simulation peut avancer et que le simulateur peut choisir les instructions concurrentes à exciter à chaque pas de
simulation. La forme générale de l’instruction est la suivante :
Pour au plus time, si un événement survient sur un signal de signal_list, la condition booléenne
bool_cond est évaluée : si elle est fausse on se remet en attente sinon on passe à la ligne suivante.
La composante signal_list est la liste de sensibilité du wait. Quand elle est omise, elle est déduite des signaux qui
sont dans la condition booléenne. Le simulateur peut gérer le temps par le mécanisme suivant : Quand tous les
PROCESS sont sur un WAIT, il y a blocage du simulateur, il recherche alors le prochain signal à être modifié
dans la liste d’événements, réveille tous les process qui attendent ce signal et on avance l’horloge de simulation
en produisant un nouveau LSP.
34
Wait ; -- arrêt jusqu’à la fin de la simulation
Wait on a ; -- attente d’un événément sur le signal a
Wait on a,b ; -- la même chose sur a ou b
Wait for 10 ns; -- time out de 10 ns (en temps de simulation)
Wait until a=‘1’; -- détection de front montant;
Tous les temps spécifiés dans les modèles font référence à un temps simulé, c’est à dire pris en charge par une
variable incrémentée par le simulateur. Il est strictement indépendant du temps pris par le simulateur pour
exécuter le modèle. L’instruction « wait for 10 h ;» ne prendra pas plus de temps que « wait for 10 fs ; » S’il y a
le même nombre d’événements à traiter par le simulateur. L’intérêt de l’algorithme de simulation à événement
discret associé à la sensibilisation des process (seuls les process qui le doivent sont exécutés) permet de fabriquer
des simulateurs optimum en temps de calcul.
VHDL-AMS propose deux mécanismes d’exécution conditionnelle ou sélective dont la syntaxe est explicite :
[label:]case expression is
when value_1 => {séquence d’instruction séquentielles 1}
{when value_2 => {séquence d’instruction séquentielles 2}}
when others => {séquence d’instruction séquentielles 3}
end case ;
Toujours pour augmenter la puissance de vérification la section when others est obligatoire, même si elle est
vide, ainsi aucun cas ne peut être oublié dans le traitement.
E/ Exécution itérative
Contrairement à d’autres langages la boucle infinie n’est pas pathologique si elle contient au moins une
instruction wait qui permettra de la suspendre périodiquement.
35
Itérative : [label :] for i in 1 to 100 loop
{séqu. Instr. Séqu.}
[[next_label :] next [loop_label] when cond_bool ;]
[[exit_label :] exit [loop_label] when cond_bool ;]
end loop ;
La variable de boucle i est déclarée de facto, elle est de type entier ou énuméré. Il est possible d’écrire des
boucles sur des structures dont on ne connaît pas la taille (voir l’attribut RANGE au 3.10).
La sortie des boucles, même imbriquées, est proprement traitée par les instructions exit et next.
F/ Auto-test et rapport
Le langage donne la possibilité de vérifier une condition booléenne au moment de l’exécution de cette
instruction. Si la condition est fausse un message est envoyé à la console du système et un niveau de sévérité au
simulateur qui aura été configuré pour réagir de façon adéquate :
Cette instruction permet, par exemple, à un modèle de vérifier lui-même et de façon dynamique ses conditions
d’utilisation ; L’instruction suivante permet à une bascule de vérifier en temps réel si son temps de set-up n’est
pas violé. On remarquera que le sens du test est inversé puisque le test est effectué en logique négative :
Le process est l’instruction concurrente fabriquée par l’utilisateur par l’intermédiaire d’instructions séquentielles.
Tous les process sont au même niveau pour le simulateur ainsi un process ne peut pas contenir d’autres process
ou d’autres instructions concurrentes. La forme générale d’un process est la suivante :
Un PROCESS vit toujours, il est global. Il est éventuellement suspendu sur un wait
Un PROCESS est itératif, il démarre sur son mot clé begin, se déroule jusqu’à son mot clé end et recommence.
Seul le wait peut le suspendre. Un PROCESS qui n’est jamais suspendu ne rend pas la main à l’environnement et
entraîne la famine des autres process. Dans le meilleur des cas le simulateur prévient qu’un PROCESS est trop
gourmand et propose à l’utilisateur de corriger le problème, dans le pire des cas il faut arrêter le simulateur par
une procédure d’urgence.
36
Il existe une variante issue de l’ancienne version VHDL 7.2. Cette méthode, dite de la liste de sensibilité, est très
pauvre sémantiquement, est exclusive du wait et est à proscrire. Beaucoup d’outils de synthèse logique la
supportent ou la préconisent et quelques-uns uns la rendent obligatoire.
Quand on utilise le WAIT pour «synchroniser » un processus, il est possible d’y associer des conditions et
surtout il est possible d’en utiliser plusieurs dans le même process ce qui enrichit énormément les possibilités.
Quand le wait est associé à une boucle infinie on dispose d’une méthode d‘initialisation performante.
process
{zone de déclaration / pas de signaux}
begin
{pré-processing : initialisation}
loop
{traitement effectif}
{instruction_wait}
end loop ;
end process ;
P1 : process
variable index_tab : integer := 0 ;
begin
wait on input1,loc_sig ;
if loc_sig'event then
index_tab := index_tab +1 ;
sortie <= 1.0 ;
wait for 1 us ;
sortie <= 0.0 ;
else
if input1 = ’1’ ;
sortie <= index_tab ;
index_tab := 0 ;
end if ;
end if ;
end process;
P2 : process
begin
wait for 100 us ;
loc_sig <= not loc_sig;
end process;
Fig 3.9.2-A : Exemple de deux process inreragissants
Dans l’encadré précédent le process P2 fabrique une horloge de demi-période 100 ?s sur le signal loc_sig. Le
process P1 est démarré périodiquement sur les événements de loc_sig et sur les événements de input1. A chaque
événement sur loc_sig, un compteur interne est incrémenté et une impulsion d’une microseconde est générée sur
la sortie. Quand input1 (signal d’interrogation) passe au niveau ‘1’ alors la valeur du compteur est présentée sur
la sortie et il est remis à zéro.
B/ Affectation de signal
37
Toutes les instructions concurrentes sont des raccourcis d’écriture qui peuvent être mises sous forme d’un
processus équivalent. Par exemple l’affectation concurrente peut toujours être mise sous la forme d’un process
contenant une affectation séquentielle, un ensemble de test et un wait.
Les mécanismes transport/reject/inertial sont identiques à ceux vu aux 3.9-A. L’option GUARDED sera
explicitée au 4.4. Cette affectation est en attente d’un événement sur un des signaux qui apparaît dans waveform.
Ainsi l’instruction concurrente (S <= 5.0 ;) ne sera effectuée qu’une seule fois à l’initialisation du modèle, alors
que, si A est un signal, (S <= A after 12 ns ;) sera effectuée à chaque fois que A présentera un événement.
C/ Break
Cette instruction très importante permet de synchroniser les noyaux de simulation et sera présentée en détail dans
la section 3.11.
E/ Assertion
38
Cette instruction permet de surveiller en permanence une condition booléenne. Quand cette condition devient
fausse un message est envoyé à la console et un niveau de sévérité au simulateur.
Cette forme permet de fabriquer des équations de branche en liant les différentes quantités entre elles. Elle peut
être explicite (on exprime l’inconnue en fonction du reste) ou implicite.
Dans cette expression f et g sont deux fonctions non-linéaires contenant des quantités, des constantes, des
valeurs de signaux. Le simulateur s’assure qu’à chaque point de simulation analogique on a bien f-g = 0.0
(équation caractéristique) aux tolérances prêt. VHDL-AMS propose un mécanisme de spécification des
tolérances associées à chaque sous type ou à chaque équation simultanée. Actuellement, les environnements de
calcul n’utilisent pas cette spécificité et assure une tolérance (absolue et relative) globale pour toutes les
quantités du modèle.
On dit qu’une fonction est pure si le résultat qu’elle rend est toujours le même quand elle est appelée avec les
mêmes conditions. Elle est impure dans le cas contraire. Une instruction simultanée est dite pure si elle génère le
même résultat quand elle est évaluée avec les mêmes valeurs au même temps. Elle est impure dans le cas
contraire. C’est une erreur de spécifier une fonction comme impure quand elle ne l’est pas.
Les exemples suivants sont valides, avec Q, Y, U, I des quantités et C une constante, et devront être résolus par
le simulateur :
ENTITY R IS
generic (R_value : real := 1_000.0)
port (TERMINAL vp,vm:electrical);
END;
ARCHITECTURE equ OF R IS
QUANTITY V ACROSS I THROUGH vp TO vm;
BEGIN
V == R_value * I;
END;
Fig 3.9.3-A : Equation simultanée dans le modèle d’une résistance générique sur sa valeur
Cette instruction permet de choisir dynamiquement le jeu d ’équations en fonction de conditions booléennes. Les
outils actuels (pas la norme) obligent le concepteur à avoir des branches équilibrées pour faciliter la vérification
du critère de solvabilité (voir 3.12). Cette instruction est « imbricable ».
39
label : IF cond_1 USE
{instruction(s) simultanée(s)}
ELSIF cond_2 USE
{instruction(s) simultanée(s)}
…
ELSE
{instruction(s) simultanée(s)}
END USE label;
A chaque ASP, les conditions sont évaluées séquentiellement pour trouver le jeu d’équation à simuler. La théorie
des équations différentielles nous dit que cette approche a une solution si les conditions initiales sont spécifiées.
Ce sera le rôle d’instruction BREAK (3.11) ;
D/ Procedural
L’encadré suivant présente l’exemple d’un sommateur analogique pondéré dont on ne connaît pas le nombre
d’entrées à la compilation. Avec beta:real_vector et Quantity vp ACROSS T to GND (tailles identiques
inconnues)
ARCHITECTURE
…
BEGIN
PROCEDURAL IS
variable bvs : real := 0.0;
BEGIN
FOR i IN beta’range loop
bvs := bvs + beta(i) * vp(i);
END LOOP;
Qout := bvs;
END PROCEDURAL;
END;
Fig 3.9.3-D : Exemple d’utilisation du PROCEDURAL
E/ null
Quand on veut compter une instruction simultanée mais ne rien faire on peut utiliser l’instruction null.
40
Certains auteurs (et la norme) classe l’instanciation de composant dans les instructions concurrentes. Nous
pensons que ce mécanisme est assez spécifique pour être isolé.
L’instanciation de composant revient à prendre une copie (une instance) d ’un modèle dans une bibliothèque
(work ou bibliothèque de ressources), la personnaliser, la configurer et la brancher à son environnement.
L’instanciation peut être directe ou effectuée par l’intermédaire d’une configuration (voir 4.12). La forme directe
est effectuée par l’instruction :
On remarquera que le label est obligatoire et c’est lui qui permettra de faire la différence entre plusieurs
instanciation du même modèle. Si l’architecture du composant n’apparaît pas dans l’instanciation alors
l’environnement instanciera la dernière analysée par le compilateur (Cette dernière spécificité dépend de l’outil
utilisé).
Les ports formels correspondent aux noms (muets) qui sont données dans la spécification d’entité, les ports réels
correspondent aux noms des objets locaux. Les règles de déclaration (scope rules) permettent d’utiliser les
mêmes noms.
Un objet peut toujours être nommé par son nom complet. Dans l’exemple suivant, si l’entité nandg est définie
dans plusieurs bibliothèques ouvertes on peut nommer l’endroit effectif : ressource_lib.nandg
Onpeut écrire :
entity RS is
port (S,R : bit ; Q,Qb : out bit);
end entity;
architecture structural of RS is
signal n1_out,n2_out : bit ;
begin
nand1: entity nandg port map(in1=>S, in2=>n2_out, outp=>n1_out);
nand2: entity nandg generic map (5 ns) port map(R,n1_out, n2_out);
Q <= n1_out;
Qb <= n2_out;
end structural;
Fig 3.9 : Exemple d’instanciation directe
Un port formel qui n’est pas branché est associé au mot clé OPEN.
Quand une entité est élaborée par le simulateur, il doit vérifier les dates de compilation des objets instanciés. Si
un objet instancié a été compilé plus tardivement que l’objet qui l’englobe un message « Warning » doit être
déclenché. C’est l’utilisateur qui prendra la décision de continuer ou de vérifier la cohérence temporelle de sa
description.
Un attribut prédéfini est une «fonction », fournie par le langage, à syntaxe spécifique qu’on applique à différents
objets qui peut rendre différents types d’objet (valeur, range, signal, quantité, fonction, type, terminal) et qui
n’est pas surchargeable. On présente ici les principaux attributs. Le reste des 55 attributs définis par VHDL-
AMS sera présenté au 4.13. Il existe aussi des attributs définis par l’utilisateur, ils seront présentés au 4.2.
41
Dans la liste suivante A? B signifie qu’un attribut appliqué à l’objet A rend un objet B.
Pour la simulation mixte il faut que les noyaux numérique et analogique puissent se synchroniser. Dans la
plupart des applications chaque noyau gère sa propre horloge mais doit conserver des liens avec l’autre pour
assurer la cohérence de l’évaluation.
Pour l’action du noyau numérique sur le noyau analogique, un événement sur un SIGNAL doit pouvoir
provoquer une évaluation analogique. Comme le pas temporel de la simulation analogique est variable on n’a
aucune assurance qu’au moment de l’événement numérique il y ait un point analogique, il faut donc forcer le
calcul d’un ASP au moment d’un événement. L’instruction BREAK est la solution prévue par VHDL-AMS.
L’instruction simple suivante force le calcul d’un ASP à chaque événement sur le signal S.
La forme complète de l’instruction BREAK permet de choisir la quantité cible, les nouvelles conditions initiales,
la liste de signaux à suivre ainsi qu’une condition d’exécution (Voir l’exemple 3.11-B). Sa complexité fait
qu’elle n’est que très imparfaitement supportée par les outils actuels.
[label :] Break [[for Q1] use Q2 => expression] [on S][when cond];
L’action du noyau analogique sur le noyau numérique se fait en fabriquant un événement à partir d’une quantité.
L’attribut suivant fabrique un signal booléen qui change d’état quand la valeur de Q croise « Value ». Quand Q
est supérieur à «Value » le signal résultant est vrai (true).
42
Q’above(Value) ;
La simulation analogique revient à résoudre un système d’équations à chaque pas de temps. Il faut s’assurer qu’à
tout moment le modèle contient autant d’équations que d ’inconnues. Le concepteur doit alors remplir un critère
de solvabilité :
CRITERE DE SOLVABILITE :
SS = QT + QF + Qout
ATTENTION : Ce critère n’assure pas la CONVERGENCE qui est une caractéristique dynamique du réseau
d’équation couplé aux techniques d’analyse numériques mises en place.
Ce critère est suffisant mais pas obligatoirement nécessaire, il en est assez contraignant. D’autres propositions
ont été faites au cours du processus de normalisation mais elles étaient complexes, difficilement automatisables
et laissaient au concepteur un travail d’étiquetage des équations très compliqué.
L’intérêt de ce critère est qu’il peut être assuré localement. On peut concevoir des sous-systèmes et les associer
sans se préoccuper de la résolution globale si on assure le critère pour chacun d’eux. Un modèle qui n’assure pas
ce critère ne passe pas la compilation et n’est donc pas stocké dans la bibliothèque de travail.
43
end architecture Good;
Fig 3.12 : Exemple pour le critêre de solvabilité
Devant la diversité des constructions possibles le débutant est souvent très perturbé par les possibilités et les
limitations de déclaration des objets. En fait on peut découper les modèles en deux mondes complémentaires : le
séquentiel et le concurrent.
Monde séquentiel (zone de déclaration des process, des procédures, des procedural):
Variables, Constantes, Types et sous-types, Procédures, Alias (4.2), Attributs (4.2), Group (4.3)
Monde concurrent (zone de déclaration des architectures, des blocks (4.4), des paquetages)
Les limitations imposées par ces règles sont assez naturelles. De plus, le même nom peut être utilisé pour deux
objets différents s’ils ne sont pas dans la même zone de visibilité ou s’il n’y a pas d’amb iguïté possible, il y a une
erreur dans le cas contraire.
Certaines difficultés ne sont pas levées par les outils. Par exemple quand deux fonctions ont le même nom et le
même prototype dans deux paquetages accessibles certains outils choisissent le premier rencontré. Quand un
type est défini plusieurs fois, par exemple localement et dans un paquetage il y a des difficultés. Formellement
on peut avoir plusieurs objets portant le même nom du moment qu’il n’y a pas ambiguïté. Sur certains outils si
un label porte le même nom qu’un autre objet le compilateur fait une erreur.
Les objets sont visibles dans tout le modèle compris sous leur déclaration. Tous les objets statiques définis «au-
dessus » sont accessibles par une notation pointée :
L1 : Block
Signal A,B :bit ;
Begin
L2 : Block
Signal B :bit ;
Begin
A <= B after 5 ns ; -- signifie L1.A <= L2.B
B <= L1.B after 10 ns ; -- signifie L2.B <= L1.B
End block ;
B <= a after 15 ns ; -- signifie L1.B <= L1.A
End block ;
La clause USE permet d’exporter les définitions, d’une bibliothèque (USE lib.all;), d’un paquetage (USE
lib.target_paq.all;) ou d’un objet (USE lib.target_paq.object_name;).
Cet exemple présente un modèle de porte NAND générique sur les temps de retard à la montée et à la descente
de la sortie par rapport à l’entrée. La première architecture utilise la notion (fausse) de temps de délai moyen
tandis que la deuxième cherche à savoir quelle est la variation effective de la sortie pour appliquer le bon retard.
LIBRARY IEEE;
use ieee.std_logic_1164.all;
ENTITY nandg IS
GENERIC (tplh,tphl : time := 10 ns);
PORT (SIGNAL inp1,inp2 : IN std_ulogic, outp : OUT std_ulogic);
44
END;
-- Architecture en temps moyen
LIBRARY IEEE;
use ieee.math_real.all;
ARCHITECTURE beh1 OF nandg IS
BEGIN
outp <= inp1 nand inp2 after (tplh + tphl)/2;
END;
-- Architecture en tplh et tplhl
ARCHITECTURE beh2 OF nandg IS
BEGIN
Process
variable loc : std_ulogic;
begin
wait on inp1, inp2;
loc := inp1 nand inp2;
if loc = ‘1’ then
outp <= loc after tplh;
else
outp <= loc after tphl;
end if;
end process;
END;
3.14.2 Bascule D
Cette bascule est modélisée dans deux architectures par une instruction concurrente et un process
LIBRARY IEEE;
use ieee.std_logic_1164.all;
ENTITY bascd IS
GENERIC (tpd: time := 10 ns);
PORT (SIGNAL D,CLK : IN std_ulogic; SIGNAL Q : OUT std_ulogic);
END;
-- A base d’affectation concurrente
LIBRARY IEEE;
use ieee.math_real.all;
ARCHITECTURE beh1 OF bascd IS
BEGIN
Q <= D after tpd when (CLK’event and CLK=‘1’) else unaffected;
END;
-- A base de process
ARCHITECTURE beh2 OF bascd IS
BEGIN
Process
Begin
wait until CLK=‘1’;
Q <= D after tpd ;
end process ;
END;
ENTITY R IS
generic (R_value : real := 1_000.0) ;
port (TERMINAL a,b:electrical);
END;
ARCHITECTURE equ OF R IS
QUANTITY V ACROSS I THROUGH a TO b;
45
BEGIN
V == R_value * I;
END;
ENTITY C IS
generic (C_value : real := 1.0e-6) ;
port (TERMINAL vp,vm:electrical);
END;
ARCHITECTURE equ OF C IS
QUANTITY V ACROSS I THROUGH vp TO vm;
BEGIN
I == C_value * V ’dot;
END;
ENTITY L IS
generic (L_value : real := 1.0e-3) ;
port (TERMINAL vp,vm:electrical);
END;
ARCHITECTURE equ OF L IS
QUANTITY V ACROSS I THROUGH vp TO vm;
BEGIN
V == L_value * I ’dot;
END;
ENTITY RLCs IS
generic (R,L,C : real) ;
port (TERMINAL vp,vm:electrical);
END;
ARCHITECTURE struct OF RLCs IS
Terminal RC,CL : electrical;
BEGIN
lab_R: entity R generic map (R) port map (vp,RC);
lab_C: entity C generic map (C) port map (RC, CL);
lab_L: entity L generic map (L) port map (CL, vm);
END;
ARCHITECTURE equ OF RLCs IS
quantity V across I through vp to vm;
BEGIN
V == R*I + L*I’dot + I’integ/C ;
END;
ENTITY RLCp IS
generic (R,L,C : real) ;
port (TERMINAL vp,vm:electrical);
END;
ARCHITECTURE struct OF RLCp IS
BEGIN
lab_R: entity R generic map (R) port map (b => vm, a => vp);
lab_C: entity C generic map (C) port map (vp, vm);
lab_L: entity L generic map (L) port map (vp=>vp ,vm=>vm);
END;
ARCHITECTURE equ OF RLCp IS
quantity V across I1,I2,I3 through vp to vm;
BEGIN
V == R*I1 ;
V == L*I2’dot ;
V == I3’integ/C ;
END;
46
3.14.5 Générateur sinus idéal
library Disciplines;
use Disciplines. electrical_ system. all;
ENTITY gene_sinus IS
generic (Ampl,freq,phase : real) ;
port (TERMINAL vp,vm:electrical);
END;
library ieee;
use ieee.math_real.all;
ARCHITECTURE beh OF gene_sinus IS
quantity V across I through vp to vm; -- I pour le critère solv.
BEGIN
V == Ampl * sin( 2.0 * math_pi * freq * now + phase) ;
END;
d
Ic ? (tt.I d - 2.C jo . v j ² - v j .vd )
dt
ENTITY diode IS
generic(Iss:real:=1.0e-14;n,af:real:=1.0;tt,cjo,vj,rs,kf:real:=0.0);
port (TERMINAL anode,cathode:electrical);
END;
ENTITY diodth IS
generic(Iss:real:=1.0e-14;n,af:real:=1.0;tt,cjo,vj,rs,kf:real:=0.0);
port (TERMINAL anode,cathode:electrical;
TERMINAL junction:thermal);
END;
47
BEGIN
ic == qc ’dot;
qc == tt * id - 2.0 * cjo * sqrt( vj**2 - vj * vd );
id == iss * exp(( vd - rs*id )/( n * vt )) - 1.0);
vt == temp * boltzmann / elec_charge ;
power == vd * id;
END ARCHITECTURE level0;
48
Chapitre 4 : Présentation approfondie
4.1 Ce qu'il reste à éclaircir
Le chapitre précédent nous a permis de présenter les fondements du langage. Nous allons maintenant aller plus
loin dans trois catégories :
Nous complétons aussi la présentation des attributs et donnons le contenu des paquetages standards. Nous
parlons aussi de la partie normalisée de la prise en charge des modèles par un simulateur en abordant le cycle
compilation/élaboration/simulation.
L’instruction ALIAS permet de renommer un objet (constante, variable, signal, quantité, terminal) - quand un
type apparaît dans l’instruction - ou autre chose qu’un objet, pour pouvoir le manipuler plus facilement. Cette
instruction doit se trouver dans une zone de déclaration.
Anecdote : La société LEDA propose un crypteur de source basé sur l’application itérative de l’instruction
ALIAS. Le source devient illisible pour l’humain mais reste compatible avec les compilateurs VHDL.
L’utilisateur peut définir des attributs propriétaires. Contrairement au mécanisme puissant des attributs définis
par le langage, l’attribut utilisateur ne peut définir que des propriétés constantes d’objets (entity, architecture,
configuration, procedure, function, package, type, subtype, constant, signal, variable, quantity, terminal, nature,
subnature, component, label, group, file, units). Cette instruction a sa place dans les zones de déclaration.
Pour faire la différence entre les énumérés surchargés (voir 4.6 pour les sous-programmes) on utilise le
mécanisme de signature qui permet d’associer le prototype de l’objet visé à la déclaration. (les crochets font
partie de la syntaxe).
L’attribut Mapping ne s’applique qu’au littéral JMP défini dans le type énuméré OpCod et vaut « 001 ». Si
JMP apparaît dans un autre énuméré il ne sera pas décoré (c’est le terme employé dans la norme) de l’attribut
Mapping. De plus le littéral JMP du type OpCod pourra être remplacé par le littéral GOTO.
49
4.3 Group
La norme propose une instruction pour pouvoir grouper les objets dans des collections nommées. Elle décrit la
procédure pour déclarer la structure d’un groupe et le groupe lui-même mais ne donne aucune indication sur leur
utilisation possible.
Déclaration de groupe :
group G1 : resource(L1,L2) ;
group G2 : resource(L1,L2,L3) ;
group C2Q : pin2pin(Projet.Global.CK, Q) ;
group SetG : diff_c(G1,G3) ;
4.4 Block
Cette construction permet de rassembler des instructions concurrentes ou simultanées sous la même zone de
définition et la même condition de garde. On appelle condition de garde une condition booléenne, nommée
implicitement GUARD, qui permet de contrôler le fonctionnement des instructions gardées, c’est à dire les
affectations de signal faisant apparaître le mot clé GUARDED qui ne pourront s’effectuer que si GUARD est
vrai.
Les blocks peuvent définir des paramètres génériques ainsi que des ports et sont configurables (voir 4.12). Ils
sont imbricables.
4.5 Generate
Cette instruction très puissante permet l’écriture automatique itérative ou conditionnelle de code. Ainsi, par
exemple, nous pouvons décrire structurellement un compteur N bits générique sur N en instanciant N bascules
avec N inconnu. Chaque instruction générée aura un label implicite alloué à l’élaboration. Les GENERATE sont
imbricables.
50
…
Loc(0) <= input ;
Shf_R : for i in 1 to N generate
Basc : entity bascd(beh) port map (loc(i-1),loc(i)) ;
end generate Chf_R ;
Output <= loc(N) ;
…
Fig 4.5-A: Instanciation automatique de N Bascules pour un Shift Register
…
entity adderN is
generic(N : integer := 16);
port (a,b : in bit_vector(N downto 1);
cin : in bit;
sum : out bit_vector(N downto 1);
cout: out bit);
end adderN;
Comme dans tous les langages modernes il est possible de rassembler des algorithmes en une structure
réutilisable : les sous programmes. Les sous-programmes de VHDL-AMS ne peuvent rassembler que des
instructions séquentielles. Il existe les procédures qui peuvent modifier leurs paramètres et les fonctions qui ne
peuvent pas consulter ou modifier leur environnement (pas d’effet de bord) et qui rendent une valeur. Les
fonctions sont manipulables comme des variables paramétrées.
On dira qu’une fonction est pure si elle rend le même résultat quand elle est appelée avec les même valeurs. Les
fonctions NOW et FREQUENCY, qui rendent respectivement le temps ou la fréquence courante d’analyse sont
impures. C’est à l’utilisateur de préciser le caractère pur ou impur de ses fonctions. C’est une erreur de spécifier
une fonction pure si elle est impure. Par défaut une fonction est considérée comme pure.
La définition d’un sous programme peut se faire en deux temps la déclaration et la spécification. Cette méthode
permet d’exporter le prototype d’une procédure tout en cachant sa constitution effective. Quand une procédure
est spécifiée ailleurs que dans un paquetage la déclaration et la spécification se font en même temps. La
déclaration permet de définir le prototype du sous programme.
51
function : constant (in), signal(in), file
Les fonctions sont surchargeables, c’est à dire redéfinissables avec le même nom avec un autre prototype
(nouvelle interface ou nouveaux types)
Pour faire la différence entre deux sous programmes surchargés on utilise une signature. C’est un mécanisme
permettant de rappeler le prototype du sous programme dans la déclaration d’un attribut ou d’un alias. Quand le
sous programme est une fonction le mot clé return doit apparaître dans la signature. Attention : les crochets font
partie de la syntaxe.
Dans cet exemple seule la fonction ayant le prototype spécifié, même si elle est surchargée, pourra bénéficier de
l’attribut Buitlin.
Il est possible d’effectuer un appel concurrent à une procédure. Dans ce cas la procédure devient une instruction
concurrente. En cas d’événement sur sa liste de sensibilité la procédure est exécutée et se remet en attente. C’est
la liste des signaux inout de l’interface qui définit une liste de sensibilité implicite. Il est interdit d’utiliser des
variables dans les paramètres. S’il n’y a pas de signal en mode inout dans l’interface alors il n’y aura qu’un seul
appel.
Un sous programme peut être décoré de l’attribut FOREIGN défini dans le paquetage STANDARD. La valeur
de type chaîne de caractères fournie par cet attribut peut spécifier une information sur l’implémentation non-
VHDL de ce sous-programme. Par exemple certains utilitaires de calcul peuvent être fournis sous forme de
programmes extérieurs en C. Ces implémentations peuvent présenter des restrictions sur les possibilités de
modes, classes, types des paramètres formels. Ces sous programmes sont nommé FOREIGN SUBPROGRAM.
Les simulateurs à temps continu pour l’électronique proposent différents modes d’analyse. Avec la terminologie
SPICE, on peut trouver les analyses du point de repos (OP), qui précède toujours les autres analyses, petits
signaux fréquentielle linéaire (AC), transitoire (TRAN), en bruit (NOISE), de sensibilité à un paramètre (SENS),
par tirage aléatoire d’un paramètre (MONTE-CARLO), …
52
La norme impose à l ’environnement de simulation de fournir le signal DOMAIN en fonction du mode d’analyse
en cours. DOMAIN est défini sur l’énuméré (quiescent_domain, time_domain, frequency_domain,). Il permet
d’écrire des modèles qui tiennent compte du mode d’analyse par le mécanisme suivant :
Les analyses AC et NOISE se font avec des sources particulières qui définissent respectivement le comportement
d’un phaseur et le spectre de bruit en fonction de la fréquence. Ces analyses sont menées après linéarisation du
modèle autour d’un point défini par la polarisation (OP). Au sens général une source est définie par une quantité
qui prend la forme :
La source aura le comportement définie par la source associée au mode d’analyse, les autres étant ignorées. Une
quantité définissant un comportement AC ou NOISE est appelée une quantité source. L ’analyse AC se fait avec
les sources SPECTRUM après analyse OP tandis que l ’analyse en bruit se fait avec les sources NOISE.
Le comportement temporel s’appuie sur la fonction NOW qui rend le temps courant de la simulation alors que
les comportements AC utilise la fonction FREQUENCY qui rend la fréquence courante.
quantity ac : real spectrum 1.0 , K * frequency ; -- ampl., phase variable (retard constant)
quantity nois_src : real noise bruit_rose(frequency) ; -- fonction utilisateur
quantity white_src : real noise Kb/frequency ;
Le modèle peut contenir des indications pour le simulateur. Il est possible avec l’instruction limit de spécifier le
pas de temps minimum d’évaluation d’une quantité donnée.
53
4.8 Postponed
Quand ce mot clé apparaît dans une instruction concurrente qui profite de cette option (process, assertion,
affectation, procedure) son exécution est retardée jusqu’à la fin du cycle de simulation courant, c’est à dire que
l’exécution sera effectuée une fois que tous les délais delta seront épuisés dans ce cycle.
C’est une erreur d’indiquer le mot clé POSTPONED pour une instruction à délai delta puisqu’elle devrait
s’exécuter après elle-même, ce qui est incohérent.
postponed S <= ‘0’; -- crée un delta time donc génère une ERREUR
4.9 Tolérance
Le langage permet de définir une tolérance associée à un sous-type ou à une instruction simultanée. Les quantités
définies sur ce sous-type héritent de cette tolérance et pourront être simulées en tenant compte de cette tolérance.
La tolérance est définie par une chaîne de caractères qui sera associée à une tolérance numérique effective dans
l’environnement de simulation.
Cette volonté du normalisateur est intéressante mais malheureusement inapplicable dans l’état actuel des
algorithmes de simulation. En effet il est déjà difficile de choisir correctement une tolérance globale pour tout le
système (retlol, abstol et vntol en SPICE, epsilon en ELDO), et même dans ce cas là il peut être très compliqué
d’assurer la convergence du système de résolution. Pour l’instant cette possibilité est ignorée.
On a déjà indiqué (3.9.1-A) qu’un signal ne peut avoir qu’une seule source. Dans la réalité du matériel ce n’est
pas le cas ; bus recevant des sorties trois -états ou collecteur ouvert. Le langage fournit un mécanisme spécifique,
accessible à l’utilisateur : la fonction de résolution (des conflits d’affectation).
Si, dans un contexte concurrent, on a :
A <= B ;
A <= C ;
Le compilateur génère une erreur sauf si le signal est résolu par une fonction F ; Dans ce cas, à chaque tentative
de transaction, le simulateur effectue automatiquement :
A <= F (B,C);
Un signal résolu est défini par le fait qu’il est d’un sous-type lui-même résolu ou qu’un nom de fonction apparaît
dans sa déclaration.
Exemple de déclaration d’un type résolu à partir d’un type de base (bit4), d’un vecteur de ce type de base
(bit4_v), d’une fonction avec pour paramètre un vecteur du type de base et qui rend un type de base et de la
déclaration de sous-type spécifiant le type de base et la fonction (dite de résolution) :
54
Le signal suivant sera alors résolu :
Remarque : Un port de classe signal et de mode inout est forcément associé à un port réel (un signal) résolu.
La fonction de résolution est alors appelée automatiquement à toutes les tentatives de transaction sur les signaux
du type résolu. Elle prend en entrée un vecteur de tous les signaux sources à l ’exception de ceux qui sont
déconnectés (transaction nulle) après l’application d’une instruction DISCONNECT. Les mots clés REGISTER
ou BUS déterminent le comportement de la fonction de résolution quand elle est appelée avec un driver vide
(tous les signaux sont déconnectés).
L’IEEE a défini deux types binaires multi-niveaux pour augmenter la puissance des simulations numériques. Les
types std_ulogic et std_logic sont disponibles dans le paquetage IEEE.STD_LOGIC-1164. La seule différence
entre ces deux types est que le std_ulogic est non résolu (ou unresolved, d’où le u).
Les industriels ont pris la (mauvaise) habitude d’utiliser le type std_logic dans tous les cas de figure. Les
simulations deviennent alors extrêmement lentes puisque à chaque affectation une fonction est appelée sans
aucune raison fonctionnelle. Les outils de simulation ont alors été modifiés par les vendeurs de CAO et une pré-
analyse est menée pour vérifier si std_logic est obligatoire et dans le cas contraire est remplacé automatiquement
par std_ulogic.
Les débutants se disent : « je mets des signaux résolus partout ainsi je ne risquerai pas de conflit ».
En plus du fait que vos simulations vont être plus lentes, faites l’hypothèse que vous faites une erreur dans la
connexion de vos modèles dans une description structurelle. Si vous aviez des types non résolus le compilateur
pourrait vous indiquer l’erreur alors qu’avec l’utilisation de types résolus le compilateur trouve normal qu’il y ait
plusieurs sources pour une cible et ne dira rien. De la même façon le simulateur appellera la fonction de
résolution, rendra une valeur et ne pourra d’être d’aucun secours pour la détection de l’erreur. L’analyse des
résultats de simulation risque d’être difficiles puisque le comportement peut être très loin de celui attendu sans
raison apparente.
55
signal_declaration ::= SIGNAL signal_name : [fonc_resolution] type
[contraintes][REGISTER|BUS][:= init_value];
Le signal est dit gardé si le mot-clé REGISTER ou BUS apparaît dans la déclaration. Un signal gardé est
forcément résolu. La différence de comportement est liée à la fonction de résolution quand toutes les sources
sont déconnectées :
Une affectation est gardée (GUARDED) si le mot-clé GUARDED apparaît dans l ’affectation :
4.11 Paquetage
Le paquetage (package) fait partie des cinq unités de conception et permet de rassembler un ensemble de
déclarations en vue de l’exportation par l’utilisation des clauses library/use. Formellement le paquetage est
constitué de la spécification et du corps du paquetage. La spécification permet de rassembler toutes les
déclarations exportables alors que le corps permet de rassembler les spécifications (définitions des procédures /
fonctions déclarées, des constantes ou des types) non exportables. En fonction de l’environnement d’utilisation,
il est possible de cacher les corps de paquetages aux utilisateurs non autorisés pour garantir la sécurité, la
cohérence ou la confidentialité des informations.
PACKAGE bit_vector_ops IS
FUNCTION "+"(left, right : bit_vector) RETURN bit_vector;
type state is (lec, ecr,wait,reset);
END;
56
END bit_vector_ops;
Fig 4.11 : Exemple de spécification et de corps de paquetage
Si le paquetage est compilé dans MYLIB, les informations sont disponibles par :
LIBRARY MYLIB;
USE MYLIB.bit_vector_ops.all;
Toutes les descriptions (sauf le paquetage STANDARD – voir 4.14) commencent implicitement par :
LIBRARY STD,WORK;
USE STD.STANDARD.all;
4.12 Configuration
La configuration permet de réalis er l’association effective de l’instanciation d ’un composant et d’un modèle de
la base de données au moment de l’élaboration sans avoir à recompiler le modèle. C’est un mécanisme
extrêmement puissant qui est souvent négligé par les développeurs. Une configuration se fait à travers 3 étapes.
Faisons l’hypothèse que le modèle suivant est compilé et disponible dans la bibliothèque WORK.
entity adder is
port (a,b,cin : in bit ; sum,cout : out bit);
end adder;
On définit un additionneur 4 bit sous forme structurelle. Cette description est compilable et donc dis ponible en
bibliothèque.
entity adder4 is
port (a,b : in bit_vector(4 downto 1);
cin : in std_logic;
sum : out bit_vector(4 downto 1);
cout : out bit);
end adder4;
57
-- étape (1)
component compo1
port (x,y,z : in bit; v,t : out bit);
end component;
signal carry : bit_vector(0 to 4);
begin
carry(0) <= cin;
-- étape (2) quatre fois
add1:compo1 port map(a(1),b(1),carry(0),sum(1), carry(1));
add2:compo1 port map(a(2),b(2),carry(1),sum(I), carry(2));
add3:compo1 port map(a(3),b(3),carry(2),sum(I), carry(3));
add4:compo1 port map(a(4),b(4),carry(3),sum(I), carry(4));
cout <= carry(N);
end structural;
Fig 4.12-B : Description structurelle générique
La déclaration de COMPONENT n’est qu’une indication d’intention pour le compilateur et lui permet de faire
ses vérifications de connexions avec les signaux locaux ou les ports formels. On n’a pas d’obligation de
« coller » à un composant disponible dans la base de données. Il faut simplement qu’au moment de la
configuration on puisse l’associer à un modèle ayant la même interface.
On peut maintenant définir l’association effective des composants à des modèles disponibles en bibliothèque par
l’intermédiaire de l’unité de conception CONFIGURATION.
-- étape (3)
configuration test_adder4 of adder4 is
for structural
for all: compo1
use entity work.adder(rtl) port map (a=>x, b=>y, cin=>z, sum=>v,
cout=>t);
end for;
end for;
end test_adder4;
Fig 4.12-C : Configuration
Ce module est compilable seul. On remarque que l’association des ports formels actuels se fait au niveau de la
configuration. Au moment de la simulation il suffira d’élaborer test_adder4 pour reconstruire le modèle à partir
de tous ses constituants . Si on fabrique une nouvelle configuration avec, par exemple, other_archi à la place de
rtl on peut simuler une nouvelle architecture sans recompiler les modèles. On conçoit bien que, dans le cas où le
modèle est constitué d’énormément de sous modèles, ce mécanisme puisse être extrêmement efficace.
…
for archi0
for label:compo use entity lib.entity(archi1);
for archi1
for label:compo use entity lib.entity(archi2);
for archi2
for label: compo use entity lib.entity(archi3);
. . .
end for;
end for;
end for;
…
Fig 4.12-D : Configuration hiérarchique
Cette construction est le support d’une méthodologie puissante (voir 5.1.3/5.1.4) et moderne.
58
La norme fournit un raccourci d’écriture permettant d’embarquer la configuration dans l ’architecture.
Ce mécanisme apparemment plus simple que la configuration par unité de conception perd en fait beaucoup de
puissance de généralisation et de spécialisation. Pour modifier la configuration visée il faudra de toute façon
recompiler l’architecture l’embarquant. De plus nous trouvons ce mécanisme pas très rigoureux sur le plan
sémantique puisqu’il faut configurer (2) avant d’instancier (3).
VHDL-AMS propose 55 attributs permettant de disposer d’informations sur les objets manipulés. Après en avoir
fait une liste exhaustive nous reviendrons sur quelques attributs particulièrement intéressants pour la
modélisation des systèmes.
Dans cette liste, les attributs en gras seront juste cité, ils ont déjà été explicités dans le chapitre 3. Le formalisme
[Objet_cible 0 ? objet_résultat : objet_mark'attribut_name] est le même qu’au 3.10.
59
Rend le prédecesseur de la position X dans l’énuméré T
Type T ? Function : T'leftof(X)
Rend le prédecesseur du littéral X dans l’énuméré T
Type T ? Function : T'rightof(X)
Rend le successeur du littéral X dans l’énuméré T
Array A ? Function : A’left[(N)]
Rend l’indice le plus à gauche sur l’indice N du tableau A
Array A ? Function : A’right[(N)]
Rend l’indice le plus à droite sur l’indice N du tableau A
Array A ? Function : A’high[(N)]
Rend l’indice le plus grand sur l’indice N du tableau A
Array A ? Function : A’low[(N)]
Rend l’indice le plus petit sur l’indice N du tableau A
Array A ? Range : A'range[(N)]
Array A ? Range : A'reverse_range[(N)]
Rend la contrainte inverse sur l’indice N du tableau A
Array A ? Value : A’length[(N)]
Array A ? Value : A'ascending[(N)]
Vrai si la contrainte sur l’indice N est est croissante
Attributs : exemples
adr'left = 7
adr’right = 0
adr’low = 0
adr’high = 7
MVL4’pos(‘1’) = 2 MVL4’pos(‘Z’) = 3
MVL4'val(0) = ‘U’ MVL4'val(2) = ‘1’
MVL4'succ(2) = ‘Z’
MVL4'prec(2) = ‘0’
MVL4'rightof(‘1’) = ‘Z’
MVL4'leftof(‘1’) = ‘0’
MVL4'image(‘Z’) = « Z »
MVL4'value(« 0 ») = ‘0’
mem’low = 0
mem’high = 7
mem’left = 7
mem’right = 0
mem(3)’low = 31
mem(3)’high = 0
mem’length = 8
mem(3)’length = 32
mem’range = 7 downto 0
mem(3)’range = 31 downto 0
mem’reverse_range = 0 to 7
60
mem’base’left = word
mem’ascending = false
Fig 4.13.1 : Exemples d’application d’attributs
61
4.13.2 Détails de quelques attributs importants
A/ S'RAMP
S'ramp([TR[,TF]]) :
Cet attribut sur signal de type real (ou issu de) et qui rend une quantité permet de fabriquer une quantité sous
forme de rampe à partir d ’un signal «tout ou rien ». La rampe est caractérisée par un temps de montée TR et de
descente TF (de valeurs réelles non négatives). Si TF est omis il prend la valeur de TR.
B/ S'SLEW et Q’SLEW
S'slew([max_rising_slope, [max_falling_slope]])
Q'slew([max_rising_slope,[max_falling_slope]])
Ces deux attributs permettent à partir d’un signal de type réel ou d’une quantité de fabriquer une quantité qui
présente un slew rate borné par max_rising_slope (de valeurs réelles non négatives) et max_falling_slope (de
valeurs réelles non positive). Si le deuxième argument est omis il prend la valeur 0.0.
C/ Q’zoh
Cet attribut sur quantité permet de fabriquer une quantité qui en est l’échantillonnage-blocage avec une période
de T (de type réel, en secondes) et un délai initial spécifié par le deuxième paramètre (de type réel, en secondes).
D/ Q'LTF
Cet attribut permet d’appliquer une transformée de laplace (Laplace Transfert Function) à une quantité par
l’intermédiaire de deux vecteurs de réels qui contiennent les coefficients des polynômes du numérateur et du
dénominateur de l’écriture symbolique en p (ou s). Le résultat est directement disponible sous forme temporelle.
Soit la fonction de transfert en formalisme de laplace :
?
m
ak . p k
k ?0
H( p ) ?
?
n
b .p k
k ?0 k
Alors : Q’ltf(num,den),
Est la sortie du système ayant pour fonction de transfert num/den excité par Q. Par exemple la fonction
de transfert du deuxième ordre suivante :
H0 .? p2
H( p ) ?
?p 2
p2 ? .p ? ? p
Qp
Permet de définir, avec Ho, wp et qp des constantes réelles, les deux vecteurs réels:
num = ( Ho*wp*wp )
den = ( wp*wp, wp/qp, 1)
62
Et Qs == Q’ltf(num,den) ;
E/ Q'ZTF
Le mécanisme d’application de fonctions de transfert en Z est identique au précédent, il suffit juste de préciser en
plus les paramètres de l’échantillonnage ; période et décalage initial.
Q'ztf(num,den,T[,initialelay])
La norme définit un certain nombre de paquetages standards contenant les types, fonctions, constantes de base,
les opérations sur les fichiers. Les deux paquetages de base sont les paquetages STANDARD et TEXTIO
disponibles dans la bibliothèque STD. Toutes les descriptions (sauf le paquetage STANDARD) commencent
implicitement par :
De plus, l’IEEE propose des paquetages normalisés sans qu’ils fassent partie intégrante de la norme du langage.
On les compilera dans la bibliothèque IEEE. C’est le cas des paquetages STD_LOGIC_1164 (MVL9 -
std_ulogic, std_logic et fonctions associées), MATH_REAL et MATH_COMPLEX (constantes, types et
fonctions).
Le support de la modélisation à temps continu se fait par l‘intermédiaire de natures qui sont définis dans les
paquetages ELECTROMAGNETIC_SYSTEM, KINEMATIC_SYSTEM, ROTATIONAL_SYSTEM,
FLUIDIC_SYSTEM et PHYSICAL_CONSTANTS. Ces paquetages seront disponibles dans la bibliothèque
DISCIPLINES.
Il existe aussi des paquetages non normalisés distribués par les fournisseurs de CAO ou par d’autres organismes.
Leur utilisation est assez délicate car il faudra toujours les adjoindre aux modèles que l’on veut partager et
s’assurer pour ça qu’ils sont libres de droit. Le portage n’est alors plus très évident si le paquetage fourni n’est
disponible sur l’outil utilisé que sous forme binaire ; Par exemple, les outils de conception livrés avec des
bibliothèques de ressources de type Intellectual Property (IP) pour lesquelles on n ’a pas accès aux sources. Si
des fonctions utilisées sont définies avec l’attribut FOREIGN les constructions ne sont pas portables.
Les outils existants (VHDL’93 ou VHDL-AMS) ne sont pas associés à des outils de «navigation » dans les
paquetages. Il est assez facile d’avoir à disposition plusieurs centaines de types, constantes, fonctions… à
disposition mais il est très difficile de s’y retrouver. Il est possible, par exemple, d’avoir deux fonctions avec le
même nom et le même prototype (ou deux types) dans deux paquetages différents. Un appel simple sans
nommage complet (library.name) ne permet pas de savoir lequel a été choisi par le compilateur. De la même
façon un paquetage pouvant en appeler un autre il est possible, mais pas très conseillé, de faire des références
circulaires. Encore, quand un type est défini dans deux paquetages et que le premier appelle l’autre, le
comportement des compilateurs peut être très bizarre.
Le contenu exhaustif des paquetages standard et utilitaires IEEE est présenté en annexe.
L’utilisation des modèles VHDL-AMS par un simulateur passe par trois étapes intellectuelles (I) et 3 étapes
techniques (T). Ce sont les étapes de réflexion(I), d’écriture(I), de compilation(T), d’élaboration(T), de
simulation(T), d’exploitation(I). Il est important de comprendre ce qui différencie, et les opérations effectuées
par, les étapes de compilation et d’élaboration. La réutisabilité par le support de la généricité est largement
favorisé par la séparation de ces deux opérations.
63
UC primaires avant UC secondaires
Stockage en bibliothèque si réussite de la compilation
Elaboration : Rassemble les modèles utilisés (propriétaire ou IP) définis dans la configuration,
Vérifie les associations, fixe les génériques, crée les data-structures,
(process inteconnectés + jeu d’équations simultanées)
Initialise les horloges
Les modèles sont pris en charge par le(s) simulateur(s). Il va enchaîner un certain nombre d’opération permettant
de mener à bien la tâche qu’on lui a fixée. Le cycle présenté dans l’encadré suivant est simplifié. Les
implémentations spécifiques sont dépendantes de chaque environnement de simulation.
4.15.3 Conditions initiales pour le calcul du point de fonctionnement ou après une discontinuité
La résolution numérique d’un ensemble d’équations différentielles est un exercice difficile qui peut ne pas
converger vers une solution. On doit définir les conditions initiales des équations au début du cycle de simulation
pour que le simulateur puisse mener le calcul. Comme on peut modifier les équations à utiliser en cours de
simulation en gérant des discontinuités il faut pouvoir initialiser les quantités pour redémarrer un intervalle de
calcul.
L’initialisation au début du cycle de simulation pour le calcul du point de fonctionnement est effectuée par une
instruction break.
64
BREAK v => 0.0, s => 10.0 ;
Cette instruction initialise v à 0.0 et s à 10.0 à T = 0.0. Cette forme simplifiée du BREAK sans liste de sensibilité
est activée une seule fois à T=0.0 et suspendue jusqu’à la fin de la simulation.
Après une discontinuité sur Q on a implicitement Q’dot = 0.0 et Q = Q(t -). Une condition initiale spécifiée
remplace ces équations implicites pendant la recherche du nouvel ASP ;
BREAK [[for selector_quantity] use quantity_name => expression] [on signal_list] [when cond] ;
Si selector_quantity n’apparaît pas c’est quantity_name qui est à remplacer. Si selector_quantity est de la forme
Q’integ alors Q’integ est remplacée, si c’est Q qui apparaît alors c’est Q’dot qui est remplacée.
Une condition initiale doit être spécifiée pour une quantité dont la dérivée n’apparaît pas dans le modèle.
L’utilisateur doit spécifier quelle est l’équation implicite à remplacer.
entity Capacitor is
generic (C: REAL; ic: REAL := REAL’low);
port (terminal p, m: electrical);
end entity Capacitor;
65
Fig 4.15.3-B : Balle bondissante / Mise à jour des conditions initiales après discontinuité
Quand le concepteur à un doute sur la syntaxe fine ou sur l’utilisation d’une instruction rare il fait référence à la
grammaire du langage.
La grammaire est une méthode formelle pour définir la syntaxe d’un langage. On trouvera la grammaire
officielle, au format BNF, dans le manuel de référence du langage (LRM) édité par l’IEEE et disponible pour un
coût approximatif de 150 US$ port compris auprès de cet organisme.
Vous trouverez en annexe les 285 règles avec les références au chapitre du LRM où elles sont traitées. Comme
l’utilisation «papier » de ce formalisme est extrêmement lourd, vous trouverez sur le CD-ROM une version
interactive en HTML. L’ouverture de ce fichier dans un navigateur WEB permet de vérifier très vite une
construction syntaxique. Il suffit de cliquer sur le nom de la règle dans le tableau des règles pour être transporté à
sa définition. Chacun des constituants de la règle, sauf les terminaux, est aussi accessible par un lien hypertexte.
L’utilisation de la touche BACK (ou alt+flêche-gauche) permet de consulter la grammaire sous forme d’arbre de
façon simple, rapide, efficace et fiable.
Les débutants auront un soutien très efficace avec cet outil car les premiers pas avec un langage ayant autant de
constructions différentes ne sont pas très faciles.
66
4.17 Des exemples plus avancés
Remarque préliminaire : ces modèles sont issus de travaux personnels, de documents officiels IEEE, de
publications scientifiques, de publications pédagogiques, de cours de collègues, de tutoriaux, … Ils ont pour
objectif principal d’illustrer les possibilités conceptuelles du langage. Des exemples plus «aboutis » sont
présentés au chapitre 8.
Le modèle suivant décrit un système à entrée analogique et sortie numérique à comportement complexe.
L’enchaînement des phases est contrôlé par une machine d’états finis (ou encore appelée automate ou FSM). La
sortie, de type std_ulogic, vaut ‘X’ si la tension d’entrée reste trop longtemps (timeout) dans la zone de
transition.
dout
‘1’
‘X’
‘0’ vin
vlo vhi
break on vin’above(vlo),vin’above(vhi);
67
process
variable state: states := level(vin, vlo, vhi);
begin
case state is
when one => dout <= ’1’;
wait on vin’Above(vhi); -- wait for change
state := unstable;
when zero => dout <= ’0’;
wait on vin’Above(vlo); -- wait for change
state := unstable;
when unknown => dout <= ’X’;
wait on vin’Above( vhi), vin’Above( vlo);
state := level( vin, vlo, vhi);
when unstable => wait on vin’Above( vhi), vin’Above( vlo)
for timeout;
state := level( vin, vlo, vhi);
end case;
end process;
end architecture Hysteresis;
Fig 4.17.2 : Code VHDL-AMS du comparateur à hystéresis.
Le thyristor est amorcé si la tension directe est positive et la tension de contrôle supérieures à von. Le thyristor
se bloque si la tension de contrôle est inférieure à von et le courant direct passe sous le courant de maintien
ihold.
68
break on ison;
end architecture Ideal;
Fig 4.17.2 : Thyristor parfait
-----------------------------
-- ligne de transmission
-----------------------------
entity ligne is
generic (td, z0: real);
port (terminal t1, t1r, t2, t2r: electrical);
end ligne;
Pour décrire un transistor bipolaire, plusieurs niveaux de modélisation sont possibles. Nous allons tout d'abord
modéliser le transistor bipolaire avec un modèle segmenté puis avec les équations d'Ebers et Moll.
Ce modèle est purement descriptif et doit être complété pour une utilisation effective.
library disciplines;
library ieee;
use disciplines.electromagnetic_system.all;
use ieee.math_real.all;
entity transistor_NPN is
generic (VD0 : real := 0.65; beta :real := 100.0);
port (terminal c, b, e : electrical);
end;
69
vbe == ib * rb + vd0;
if vce'above(vd0) use -- linéaire
ic == beta * ib;
else -- saturé
vce == vd0/(beta*ib) * ic;
end use;
end use;
end architecture SEG;
Fig 4.17.4-A : Modèle segmenté d’un transistor bipolaire
Pour mettre en œuvre les équations d’Ebers-Moll il faut au préalable définir les coefficients suivant : BetaF,
BetaR, Is0, Vbe, Nf, Nr, Vth. Le coefficient Vth est défini en fonction de la température et de deux constantes.
entity BJT is
generic (Iso : real; -- courrant de saturation de transport
Bf : real; -- beta direct ideal
Nf : real; -- coefficient d'emission direct
Br : real; -- beta inverse ideal
Nr : real; -- coefficient d'emission inverse
Temperature : real -- temperature);
Port (terminal collector, base, emitter : electrical);
end BJT;
Cet exemple illustre le cas d'un système mixte analogique-numérique où la plupart des mécanismes VHDL de
base sont exploités. En effet on y trouve l'instanciation de structures placées dans des bibliothèques, l'utilis ation
de composants décrits de manière comportementale et structurelle, l'utilisation de composants numériques et
analogiques.
entity VCO is
generic(fc: real := 1E6; -- frequence de coupure fc pour la tension Vc
df: real := 0.5E6; -- [Hz/V], rapport frequence/tension
Vc: voltage := 0.0 -- tension pour la frequence centrale
);
port(quantity Vin: in voltage;
terminal OutTerminal: electrical);
end entity VCO;
70
architecture PhaseIntegrator of VCO is
constant TwoPi: real := 6.283118530718; -- 2pi
quantity Phase : real; -- Phase is a free quantity:
-- definition d'une branche pour la tension de sortie
quantity Vout across Iout through OutTerminal to ground;
begin
break Phase => 0.0;
break Phase => Phase mod TwoPi on Phase'above(TwoPi);
Phase'dot == TwoPi*realmax(0.5E6, fc+(Vin-Vc)*df);
Vout == 2.5*(1.0+sin(Phase));
end architecture PhaseIntegrator;
entity AnalogComparator is
generic(Vthreshold: voltage := 0.0 ); -- [V] tension de comparaison
port(terminal Pve_T,Nve_T: electrical; -- entree analogique
signal Out_T: out BIT ); -- sortie numerique
end entity AnalogComparator;
C/ Détecteur de phase
entity RSFF is
generic (DelayQ, DelayQB: TIME := 0 ps);
port (SB,RB: in BIT; Q,QB: out BIT);
end entity RSFF;
entity PhaseDetector is
port(In1,In2 : BIT;
Up,Down : out BIT);
end entity PhaseDetector;
71
RST: RSFF port map( SB=>UpB, RB=>M, Q=>TQ, QB=>open );
RSB: RSFF port map( SB=>M, RB=>DownB, Q=>open, QB=>BQB );
RSUp: RSFF port map( SB=>SUp, RB=>M, Q=>Up, QB=>UpB );
RSDown: RSFF port map( SB=>M,RB=>RDown,Q=>DownB,QB=>Down );
end architecture Structure;
D/ Filtre analogique
entity AnalogFilter is
generic (InCurrent : current := 100E-6; -- [A] courant d'entree
-- valeurs des composants du filtre.
R1: REAL := 100E3; R2: REAL := 10E3;
C1: REAL := 100E-12; C2: REAL := 3.3E-9 );
port (signal Up,Down : bit; -- signaux controlant les sources de courant
terminal Filter_T: electrical);
end entity AnalogFilter;
E/ Compteur numérique
entity Counter is
generic (Count: positive := 2; -- divide-by-two by default
Delay: TIME := 0 ns ); -- propagation delay
port (Input : in BIT;
Output : out BIT);
end entity Counter;
72
F/ PLL structurelle
entity PLLFrequencyMultiplier is
port(terminal InWave_T,OutWave_T: electrical);
end entity PLLFrequencyMultiplier;
73
Chapitre 5 : Utilisation industrielle
Il faut noter qu’en absence d’un outil pour faire ses premiers pas en VHDL-AMS on peut utiliser des «parsers »
(analyseur de code) sur le WEB. Par exemple http://www.syssim.ecs.soton.ac.uk/vhdl-ams/web-parser/web-
parser.html analyse votre code source et détecte vos erreurs.
VHDL-AMS est un langage modulaire qui permet de nommer les objets avec des noms explicites. Contrairement
à certains langages à «écriture seule » (pour l’humain) qui réclament énormément de commentaires pour assurer
la maintenance, quand VHDL-AMS est bien utilisé il ne réclame que très peu de commentaires pour être
compréhensible. Il est évidemment possible de faire des descriptions incompréhensibles. On prendra un soin
particulier à présenter correctement le source, à nommer les objets de façon explicite. Les deux encadrés suivants
présentent le même source. Il est clair que le premier n’est compréhensible que si on lui associe des
commentaires alors que le deuxième est quasiment autosuffisant. Le temps «perdu » à présenter correctement le
code sera de toutes façons gagné dans les manipulations futures de celui-ci.
ENTITY bascd IS
GENERIC (tpd: time := 10 ns);
PORT (SIGNAL d,clk : IN std_ulogic; SIGNAL q : OUT std_ulogic);
END ENTITY basd;
LIBRARY ieee;
USE ieee.math_real.all;
ARCHITECTURE beh1 OF bascd IS
BEGIN
q <= d after tpd when (clk’EVENT and clk=‘1’) else UNAFFECTED;
END ARCHITECTURE beh2;
74
ARCHITECTURE beh2 OF bascd IS
BEGIN
bascp : PROCESS
BEGIN
WAIT UNTIL CLK=‘1’;
Q <= D AFTER tpd;
END PROCESS bascp;
END ARCHITECTURE beh2;
Fig 5.1-B : Meilleure présentation du code de la figure 5.1-A
5.1.1 Modularisation
La modularisation permet de partager le travail en entités plus petites et plus facilement appréhendables et
maintenables. La norme définit cinq unités de conception (UC). La recompilation d’une UC ne doit pas
impliquer la manipulation de fichiers qui ne la concerne pas (risques d ’erreurs, temps gaspillé, …).
Chaque UC doit être dans un fichier avec ses clauses library et use
Même si cette méthode morcelle la conception en beaucoup de fichiers les avantages sont nombreux. Une
nouvelle configuration pourra se faire sans recompiler. Les outils vérifiant la cohérence des temps de
compilation, on risque de perturber la cohérence demandée si on modifie une UC au sein d’un fichier qui en
contient plusieurs. L’ordre des UC dans un fichier sera lié aux dépendances définies par les USE et les
instanciations. On pourra partager plus simplement des fichiers courts (et vérifiés) avec d’autres concepteurs.
Les paquetages permettent de rassembler les sous programmes, les types ou les déclarations de composants. Il
faut utiliser ces possibilités pour alléger les descriptions. De plus il faut utiliser les constantes et les sous-
programmes proposés par les paquetages normalisés.
La pratique montre que c’est une très bonne habitude que de s’interdire les instructions wait dans les sous
programmes. En effet en cas d’appel récursif ou même simplement itératif, le comportement est difficilement
prévisible. Si une fonction contient un wait est mal documentée le concepteur, surtout s’il n’a pas accès au corps
de la fonction (masquage d’informations), risque de passer beaucoup de temps à comprendre pourquoi son
modèle ne fonctionne pas.
5.1.2 Tests
Le travail de modélisation passe par des phases de définition globale (cahier des charges), de développement de
sous-modèles, d’association de ceux-ci et d’exploitation en vue d’étude ou d’industrialisation. Les phases de test
doivent être prévues dans le planning de conception comme prioritaires et indispensables. Ce travail long et
exigeant doit être mené de façon très rigoureuse. On utilisera éventuellement une procédure standard de
l’entreprise. On pensera à archiver les rapports de validation et on documentera les hypothèses de
fonctionnement des modèles et leurs limites de validité.
Plus le modèle semble/est simple, plus cette procédure de test est ignorée. C’est une erreur grave qui peut faire
perdre énormément de temps. En effet une erreur qui se produit pour un système complexe instanciant, entres
autres, des modèles de composant simples erronés, ne sera pas directement recherchée à ce niveau. On mettra en
cause d’abord les constructions comp lexes.
75
VHDL-AMS supporte la généricité. C’est un mécanisme puissant permettant le développement et la réutisabilité.
Les modèles développés sont alors utilisables dans des conditions et pour des propriétés différentes de celles
définies au départ. Le temps perdu au développement pour rendre les modèles génériques sera regagné dans la
suite du projet.
Par exemple :
La configuration permet d’élaborer des grosses structures sans recompiler les constituants. En effet
l’instanciation directe ou la configuration embarquée sont trop restrictives de ce point de vue.
Le support de la multi-abstration associé avec la configuration permet des développements incrémentaux fiables
et efficaces. Faisons l’hypothèse qu’un système a été étudié d’un point de vue fonctionnel et qu’après étude
architecturale on confie les trois blocs définis au niveau comportemental (B111000 / B222000 / B333000) le constituant à trois
équipes différentes (e1 / E2 / E3 ) en vue de leur conception pour fabrication.
L’équipe E111 doit concevoir B111 : B111000 à B111nnn. En utilisant la multi-abstraction elle peut vérifier ses travaux en
simulant la structure B111xxx / B222000 / B333000. Avec les anciennes méthodes de conception on faisait la conception des
objets indépendamment et on les interconnectait sur le prototype. S’il y avait une erreur, dans 90% des cas c’était
aux interfaces qu’elle se situait. On comprend l’avantage que peut tirer un concepteur de simuler dans ces
nouvelles conditions.
Les même remarques sont évidemment valables pour les équipes E2 et E3.
Si la description est bien faite (configuration externe) n’importe quelle netlist de type B111xxx / B222yyy / B333zzz est
simulable sans recompiler. Le travail terminé, il sera très facile de configurer la structure B111nnn / B222nnn / B333nnn pour
validation finale.
La multi-abstraction permet aussi des études de performances locales en optimisant les besoins en calculs. En
effet plus un système est modélisé à un haut niveau d’abstraction plus sa simulation est efficace en temps de
calcul au détriment de la précision des résultats. Ainsi on n’instanciera les sous-modèles avec une architecture
précise que pour la partie en cours d’études.
C’est grâce à ces méthodes que l’industrie de l’ASIC numérique peut fabriquer des systèmes justes par
construction, c’est à dire n’ayant pas besoin de prototype pour arriver à un produit final fonctionnel.
Quand elle est associée à la configuration, la généricité peut être le support de rétro-annotation entre le back-end
et le front-end. Dans l’exemple suivant les modèles ont été construits de façon générique sur les temps de calcul.
Après l’étape de back-end on a extrait, en fonction de la technologie visée, les temps caractéristiques de chaque
modèle. On peut alors vérifier par simulation si les contraintes globales sont respectées sans recompiler le
modèle. Il suffit d’effectuer une configuration qui définit les valeurs des paramètres génériques.
76
La norme VITAL (IEEE 1076.4-1995) permet de fixer la structure à donner au modèle pour permette
l’interaction entre les fichiers de paramètres extraits au format (SDF = Strandard Delay File) et les modèles
VHDL-AMS. Des bibliothèques issues des fondeurs respectent cette norme.
Dans le même ordre d‘idée, l’instruction generate est un support très intéressant puisque le modèle peut écrire
des instructions de façons itérative ou conditionnelle à la place du concepteur. Associé à la généricité cette
instruction permet de disposer de systèmes de «taille » quelconque. On profitera d’autant plus de ces possibilités
si on utilise des ports vectoriels (Signaux/Quantités/Terminaux).
On appelle testbench un modèle permettant d’en tester un autre automatiquement. Classiquement les testbench
n’ont ni port ni paramètre générique. Le test d’un modèle se fait par son instanciation par le testbench en
connexion avec des utilitaires d’excitation des entrées, de récupération et de sauvegarde ou d’analyse des sorties.
Une bonne habitude est de se construire un environnement de test suffisamment général pour ne pas avoir à
redévelopper à chaque fois. Il sera utile de compiler ses objets dans une bibliothèque spécifique permettant de
partager et distribuer les modèles utiles.
Le test de systèmes matériels se fait dans le cadre d’un cahier des charges du test, dans un environnement
rassemblant des générateurs de signaux programmables, des dispositifs d’acquisition des résultats sous le
contrôle d’un automate avec pour objectif de produire un rapport de test (phase de conception) ou de prendre une
décision industrielle - rejet/réparation/OK (fabrication).
VXI, GPIB, …
Cahier des Contrôle LabWIndows, VEE, …
Charges du test du test
Vecteurs de test
générés par la CAO
CI : testeur sous
pointes ou JTAG
Analyse Rapport de test
De données Ou Décision
(GO/NOGO)
Les modèles seront soumis à un environnement simulé reprenant les mêmes fonctionnalités.
Traitement et REPORT
Analyse ou
de données fichier résultat
77
Fig 5.3-B : Modèle en cours de test
Les modèles doivent utiliser toutes les subtilités et toute la puissance de l’environnement de travail. Pour faciliter
le travail et gagner en productivité on aura intérêt à produire des testbench auto-analysants. Les objets de gestion
du test seront purement comportementaux et génériques. On pourra développer des Générateurs analogiques
(Sinus parfait, Sinus modulé, ..), des générateurs de séquences numériques, des Analyseurs ( GoNogo,
Testeur de temps,…) et d’autres mo dèles utiles (VCO, ...).
library …; use …;
entity S_sine is
generic (InitDelay,StartFreq,SweepRate,Ampl:real);
port (quantity S_out:out voltage);
end entity S_sine;
architecture bhv of S_sine is
quantity freq,phi:real;
begin
if NOW > InitDelay use
Freq == StartFreq + SweepRate*(Now-InitDelay);
else
Freq == StartFreq;
end use;
phi’dot == Freq
S_out == Ampl * SIN(2.0 * Math_pi * phi );
end architecture bhv;
Fig 5.3-C : Exemple de modèle comportemental d’une source sinus modulée
Le modèle suivant sera branché à une entrée «électrique » pour excitation et récupérera le résultat obtenu. Le
process permet de calculer le temps de montée de la quantité de sortie. On généralisera facilement à d’autres
paramètres temporels.
library …; use …;
entity Step_meas is
generic (Tbeg, Tlow, Thigh, Trt, Tend, DUTgain:real);
port (quantity T_in:in voltage, quantity T_out:out voltage;
signal rt_v :out real := -1.0);
begin
assert Tbag > 0.0 report «Le temps de départ doit être > 0»;
-- la même chose pour les autres paramètres
end entity Step_meas;
78
Fig 5.3-D : Exemple de modèle permettant de mesurer un temps de montée
La norme « 1029.1-1998 IEEE Standard for VHDL Waveform and Vector Exchange to Support Design and Test
Verification (WAVES) » permet de profiter d’une description commune des vecteurs de test entre les test de
modèles et de matériel.
Le fait d’avoir une norme établie dynamise l’industrie de la fabrication de modèle en vue de leur vente ou de leur
location. En effet ce nouveau métier profite du fait que dans l’industrie, sauf considération stratégique, on
préfère acheter à l’extérieur si c’est meilleur marché et/ou plus rapide qu’un développement interne.
On trouve sur le marché libre ou commercial des bibliothèques générales, des cœurs de processeur ou de micro-
contrôleurs, des mémoires, …
Par exemple Mentor Graphics vend une bibliothèque généraliste nommée Comm_lib qui contient des
convertisseurs analogique-numérique et numérique-analogique, des amplificateurs, des comparateurs, des
primitives pour l’automatique, des convertisseurs delta-sigma, des primitives numériques, des sous-systèmes
exprimés en S ou en Z, des traitements mathématiques, des modulateurs et démodulateurs, des boucles à
verrouillage de phase, des sources numériques.
VHDL-AMS étant (ou sera) intégré dans les chaînes de conception industrielles il profitera de tous les
développements réalisés dans ce domaine. (production de vecteurs de test, la préparation des circuits imprimés,
…).
On rappelle que la synthèse logique est l’opération par laquelle une expression HDL de haut niveau peut être
transformée automatiquement en matériel. Seule la partie numérique de VHDL-AMS, c’est à dire VHDL’93,
peut faire l’objet d’une synthèse logique car la synthèse analogique reste inaccessible pour l’instant. Les
développements peuvent se faire en VHDL’AMS mais les parties numériques devront respecter les contraintes
associées à la synthèse logique [VHDL4]
Tout VHDL n’est pas synthétisable. De plus chaque outil a ses limitations propres et propose ses astuces. Pour
utiliser VHDL pour la synthèse il faudra en plus de la norme, suivre les conseils («guidelines ») fournis avec le
synthétiseur pour profiter au mieux de ses possibilités. L’inconvénient majeur de cette disparité entre les outils
de synthèse logique est que les descriptions ne sont ni portables, ni indépendantes des vendeurs de logiciel. On
rappelle que c’était un des intérêts principaux d’un HDL normalisé.
Pour homogénéiser l’approche l’IEEE a proposé le standard «1076.3-1997 IEEE Standard VHDL Synthesis
Packages » qui contient des types et les opérateurs associés, des fonctions de conversion. Si la conception est
faite à l’aide de ces paquetages et que l’outil est compatible avec cette normalisation alors elle sera portable et
réutilisable.
79
Chapitre 6 : Limitations, pièges et erreurs
Quelle que soit la puissance d’expression et la souplesse d’utilisation de VHDL-AMS, ce langage possède des
limitations. Sa richesse fait que l’apprentissage est assez lent au début et les débutants tombent toujours dans les
mêmes pièges. Ce chapitre devrait aider les néophytes à reconnaître leurs erreurs plus vite et à progresser
efficacement.
6.1 Limitations
VHDL-AMS permet de définir des types physiques associant des valeurs et des unités. Il est dommage qu’il ne
définisse pas de mécanisme de manipulation formelle des unités permettant par exemple de vérifier les équations
aux dimensions augmentant par-là la puissance de vérification des modèles.
Le langage ne permet pas d’exprimer et ne donne donc pas de moyen de résoudre les problèmes modélisés par
des équations aux dérivées partielles. Il est clair que la complexité des algorithmes de résolution de ces
problèmes est encore au-dessus de celle des simulateurs d’ODEs et les problèmes de maillage d’espace ne sont
pas simples.
Il aurait quand même été sage d’augmenter la sémantique pour pouvoir exprimer ces problèmes qui sont de plus
en plus proches des systèmes électroniques notamment à cause des MOEMS. La norme aurait pu poser comme
limitation que les sous-modèles utilisant ce formalisme ne seraient pas pris en charge par le simulateur (un peu
dans l’esprit des sous-programmes décorés de l’attribut FOREIGN)
Contrairement au projet MHDL : MMIC HDL [MHDL], la sémantique de connexion analogique est fixe et
unique (double si on considère le signal flow et le conservatif). On aurait pu entrevoir la possibilité, sur le
modèle des fonctions de résolution, laisser l’utilisateur définir les siennes.
6.2 Pièges
L’erreur suivante est très classique et vient du fait de l’incompréhension (par les débutants) de la différence entre
une transaction et un événement. Le signal A représente les touches d’un clavier et le process est censé compter
le nombre de fois où le clavier a été sollicité.
…
Count : Process
Begin
Wait on A ;
Compteur : := compteur + 1 ;
End process Count ;
…
Fig 6.2.0-A : Le piège événement/transaction
A la fin de la simulation, le compteur ne contient jamais la bonne valeur. En fait si l’utilisateur double une lettre,
une transaction est proposée dans le driver du signal A mais le mécanisme de filtrage l’élimine car il ne définit
pas d’événement. Comme VHDL est piloté par les événements la transaction est incapable de déclencher un
processus.
80
Dans le cas de deux process interdépendants cette erreur peut amener à un blocage de la simulation par deadlock
(éreinte mortelle) pendant lequel chaque process attend l’autre avant d’envoyer ses résultats.
Une solution simple utilise l’attribut sur signal ‘transaction qui transforme une transaction en événement.
…
Count : Process
Begin
Wait on A’transaction ;
Compteur : := compteur + 1 ;
End process Count ;
…
Fig 6.2.0-B : Solution au piège événement/transaction
Certains modèles numériques ne produisent jamais de sortie. En fait la politique de filtrage et d’abandon, quand
elle est mal maîtrisée, joue des tours aux débutants.
L’utilisateur veut fabriquer une séquence numérique à partir d’un signal défini sur le type X01Z de quatre trains
de X01Z, chaque bit étant séparé de 5 ns. L’utilisateur est fier d’avoir trouvé une règle de récurrence
lui permettant une belle modélisation.
Avec s = 5 ns et d = 5 ns
Process
Begin
For i in 0 to 3 loop ;
S <= ‘X’ after (4*i*d+s),
‘0’ after ((4*i+1)*d+s),
‘1’ after ((4*i+2)*d+s),
‘Z’ after ((4*i+3)*d+s) ;
next
Wait ;
End process ;
Fig 6.2.0-C : Belle modélisation … mais fausse
Manque de chance le résultat est pitoyable puisque X apparaît pendant 60 ns puis XO1Z à un rythme de 5 ns.
Comme le mécanisme de base de l’affectation de signal est inertiel la première proposition faite dans le driver de
S est (5 ns, 10 ns, 15 ns, 20 ns). A la deuxième affectation (25 ns, 30 ns, 35 ns, 40 ns), 25 ns permet de filtrer les
impulsions déjà présentes dans le driver ; les impulsions de taille inférieure ou égale à 25 ns sont abandonnées.
La première proposition est complètement effacée. Le même phénomène se répète trois fois pour ne laisser que
la dernière séquence.
Avec s = 5 ns et d = 5 ns
Process
Begin
For i in 0 to 3 loop ;
S <= transport
‘X’ after (4*i*d+s),
‘0’ after ((4*i+1)*d+s),
‘1’ after ((4*i+2)*d+s),
‘Z’ after ((4*i+3)*d+s) ;
next
Wait ;
End process ;
Fig 6.2.0-D : Solution pour faire fonctionner la belle modélisation
81
Une affectation de signal ne le modifie pas mais effectue une proposition de transaction dans son driver.
Process
Begin
A <= B ;
If A =valeur then
…
end if ;
wait on B
end process
Fig 6.2.0-E : Les signaux ne sont pas modifiés par affectation
A l’utilisation, on s’aperçoit que le traitement correspondant au cas A=valeur ne s’effectue jamais quand
B=Valeur mais à l’itération suivante. En fait l’instruction A <= b ne modifiant pas A et on n’aura accès que la
fois suivante à cette valeur. On peut modifier (mais ce n’est pas naturel) le process de la façon suivante :
Process
Begin
A <= B ;
Wait on A ;
If A =valeur then
…
end if ;
wait on B
end process
Fig 6.2.0-F : Forçage de la lecture d’un driver
A<=B ;
B<= A ;
D/ Surcharge explosive
Faisons l’hypothèse que nous définissons un type X01Z (‘X’,’0’,’1’,’Z’) et que nous avons besoin de tester
l’égalité de deux signaux définis sur ce type. Nous surchargeons l’opérateur = défini dans l’environnement par :
Package MVL4 is
Type X01Z is (‘X’,’0’,’1’,’Z’)
“=”(A,B :X01Z) return boolean;
end ;
A l’utilisation, le simulateur commence par ne rien faire puis se plante avec (au mieux) un message de
dépassement de pile.
Comme les appels de fonction sont récursifs l’opérateur = appelé dans le corps de la fonction n’est rien d’autre
que lui-même, et comme il n’y a pas de critère d’arrêt : BOUM !
82
On pourrait utiliser une signature ou une notation pointée pour appeler la fonction créée implicitement à chaque
création d’énuméré mais comme l’opérateur surchargé est dans le même paquetage les notations MVL4.“=” ou
“=”[X01Z,X01Z return boolean] restent ambiguës.
La bonne solution consiste à mettre la fonction dans un paquetage indépendant de la déclaration de type ou à
réécrire la fonction sans faire appel au =.
Il est tentant quand on vient du monde VHDL’93 de considérer le simulateur analogique comme un outil de
service rendant effectivement le service pour lequel il est prévu. C’est une erreur grave qui peut amener des
désagréments récurrents et douloureux.
Un simulateur analogique est un programme complexe piloté par des paramètres nombreux et variés qu’il faut
maîtriser. Il faut choisir son pas de simulation minimum et maximum, son mode d’analyse, son algorithme
d’intégration numérique, la précision de résolution (tolérance) pour assurer la convergence et, si elle est assurée,
la justesse des résultats (la précision est la somme de la justesse et de la fidélité - un simulateur étant,
normalement, déterministe la justesse est réalisée de facto).
Les constantes de temps du système à simuler devront permettre de choisir les pas de temps. Le mode d’analyse
est relié au résultat recherché. Le paramètre de tolérance sera lié à la plus petite valeur à trouver pour sa partie
absolue et au rapport entre la plus grande et la plus petite valeur du système pour sa partie relative.
La modélisation elle-même, contrairement au monde numérique, ne peut se faire en ignorant les arcanes du
simulateur analogique. Les limitations intrinsèques à l’algorithme utilisé imposeront des choix.
Anecdote : Dans le cadre de la modélisation en VHDL-AMS du problème des N-corps qui représentent N corps
massifs en relation gravitationnelle décrits par jeu de N équations différentielles à N inconnues (en
représentation vectorielle pour les accélérations, vitesses et positions en 3D) le simulateur affiche «il n’y pas de
résistance entre tels nœuds et la masse, le point OP ne peut être déterminé, fin de la simulation ».
Le comportement du simulateur et son efficacité en temps dépendra fortement des algorithmes sous-jacents.
Ainsi les deux écritures formellement équivalentes pourront donner (en fonction de l’outil utilisé) des résultats
très différents en temps de calcul.
V == Q’dot ;
Et V’integ == Q ;
C’est dans ce piège qu’on tombe le plus facilement et le plus souvent. Quand on débute, on est tellement
concentré sur la mécanique des instructions à mettre dans un process, on est tellement absorbé par la difficulté
(apparente) des déclarations dans des zones spécifiques (signaux, variables, quantités, ..) qu’on oublie de fournir
un wait au(x) process. Le compilateur ne voit pas cette option comme pathologique et le simulateur fera ce qu’on
lui a demandé, c’est à dire exécuter indéfiniment sans rendre la main la process sans wait. On aboutit alors à une
famine du simulateur et dans le meilleur des cas à une erreur du type « Le process P00234 est exécuté en boucle
pour la millième fois. Continuer OUI/NON ? » et dans le pire des cas, à un plantage.
83
6.2.3 Discontinuité : piège du seuil
Beaucoup d’exemples disponibles, notamment sur le web, illustrent la discontinuité. La plupart des exemples ne
fonctionnent pas. En fait, ils ont été écrits avant l’apparition effective des outils de simulation et n’ont pu être
testés. L’erreur souvent rapportée porte sur le fait que le paramètre de contrôle d’un changement d’équation est
rendu constant.
Sur l’exemple suivant la diode qu’on voudrait parfaite compile parfaitement mais ne simule pas car
library IEEE;
Use IEEE.MATH_REAL.all;
library DISCIPLINES;
use DISCIPLINES.electromagnetic_system.all;
Entity diode is
generic (rd: real := 0.1; -- résistance directe
ri: real := 1.0E6; -- résistance inverse
vs: real := 0.6; -- tension de seuil
vt: real := 0.025; -- tension thermodynamique
iss:real := 1.0e-6); -- courant de fuite inverse
port(terminal vp,vm : electrical);
end diode;
-- CE MODELE FONCTIONNE
-- Commande en tension avec seuil et résistance interne directe et inverse
architecture level_2 of diode is
quantity v across i through vp to vm;
84
begin
break on v'above(vs);
if v'above(vs) use
V == vs + rd * I;
else
V == vs + Ri * I;
end
end; use;
Le modèle suivant avec la première architecture est rencontré sous différentes variantes toutes aussi fausses les
une que les autres. En plus du fait qu’il oublie de piloter la discontinuité par un BREAK, il tombe dans le piège
du seuil.
entity limiter is
generic (gain : Real := 1.0; limit : Real);
port (terminal inp, inm, outp, outm : Electrical);
end entity limiter;
Dans certains cas il est difficile de détecter cette erreur et certains modèles sont obligés de tordre le cou à la
réalité pour s’en sortir. Dans les modèles d’amplificateur opérationnel tenant compte de la non-linéarité de la
sortie il faut comparer la valeur de la sortie avec les alimentations pour décider si la sortie est saturée ou pas
85
entity aop is
generic(model:AOPmodel1:=(gain=>100000.0,vmin=>-15.0,vmax=>15.0));
port (terminal vout, vp, vn: electrical);
end entity aop;
86
6.2.4 Test des quantité et Manque de Break
Il est toujours tentant de contrôler le fonctionnement d’un modèle par la valeur d’une quantité. Malheureusement
il est impossible qu’une quantité (réelle) vaille exactement une valeur et un test de la forme :
If Q = 0.0 then
…
end if ;
ne sera jamais réalisé. De la même façon, une discontinuité qui n’est pas piloté par un BREAK devrait, d’après
la norme, produire une erreur mais les simulateurs ne la signale pas forcément.
Différentes erreurs méthodologiques sont courantes et l’habitude (l’expérience diront certains) montre que les
raccourcis suivants sont mauvais et n’apportent que des faux gains de temps. (En fait, ces remarques sont
généralisables à beaucoup d’activités humaines).
Le bricolage/replâtrage
Quand un modèle ne fonctionne pas, ou pas très bien, faute d’analyse ou de maîtrise de l’outil,
c’est une erreur que d’essayer de le «réparer » en bricolant une béquille. Il vaut mieux
reprendre l’analyse théorique, trouver le problème et recommencer la modélisation sur de
bonnes bases.
Le manque de généralité
Développer au coup par coup sans prendre le temps de s’interroger sur les paramètres pouvant
être génériques (et dire : je le généraliserai plus tard ; ce qu’on ne fait JAMAIS) ne génère
qu’un gain de temps très ponctuel qui sera perdu dés que le même problème (ou un problème
approchant) se reproduira. Tous les mécanismes du langage devront être utilisés pour
développer pour le futur plus que pour le présent.
87
Après analyse de plusieurs projets réels on s’aperçoit que l’analyse, les pré-développements et les tests forment
la partie la plus importante en temps alors qu’on aurait tendance à vouloir consacrer plus de temps à la
modélisation.
88
PARTIE III : Outils, exemples et conclusion
Chapitre 7 : Les outils existants
Au moment de la préparation (au 15/12/2000) et de l’écriture de ce livre les outils disponibles sont en petit
nombre et pour l’instant très coûteux (dernière minute : le compilateur/ simulateur hAMSter est proposé sur PC à
moins de 500$). On pourra trouver des listes tenues à jours sur www.vhdl-ams.com et www.vhdl-ams.org.
Apparemment aucun des outils actuels ne supporte complètement la norme. Les outils qui fonctionnent d’après
une norme ne documente que très peu le langage (puisqu’il est normalisé) et ne renseignent, souvent
incomplètement, que sur les points qui ne sont pas couverts. Travailler avec d’un coté une norme, difficile à
appliquer quand on débute, et de l’autre un outil incomplet (voire buggé) rend douloureux l’approche sereine et
complète de son apprentissage et de l’application de ses possibilités théoriques. Il faut comprendre le formalisme
et, en plus, contourner les limitations (différentes pour chaque outil). De mauvaises habitudes sont vites prises et
il est difficile de les perdre malgré l’évolution des outils.
Les outils intégrés dans un environnement industriel de conception assisté par ordinateur
La tendance actuelle est d’intégrer le formalisme VHDL-AMS dans une hiérarchie de description plus générale
profitant de tous les développements antérieurs de l’outil de CAO dans lequel il est utilisé. Ainsi dans l’outil de
89
Mentor Graphics qui est centré autour de simulateur ELDO (Anacad) pour le continu et V-system
(ModelTechnology) pour le numérique Les modèles AMS peuvent instancier des primitives ELDO et les netlist
ELDO peuvent utiliser des modèles AMS. Pour l’outil fourni par DOLPHIN INTEGRATION les formalismes
qui cohabitent sont VHDL-AMS, ABCD, VERILOG, SPICE. De plus en plus souvent VERILOG est disponible
en même temps que VHDL.
Comme nous avons pu disposer des outils de MENTOR-GRAPHICS et de DOLPHIN INTEGRATION, nous
pouvons les présenter plus en détails.
Cet outil qui fonctionne sur stations de travail SUN et HP (sous réserve de processeur et OS récents) est intégré à
la chaîne de CAO industrielle de MENTOR GRAPHICS. Le prix catalogue d’une licence est de 678 KF HT.
Dans cet environnement le testbench VHDL-AMS ne peut avoir de PORT et on n’a pas accès à toutes les
analyses possibles (NOISE par exemple)
Un modèle ELDO peut instancier un VHDL-AMS et un modèle VHDL-AMS peut instancier un modèle ELDO.
Le modèle doit être associé à un fichier de commande, qui contient les paramètres de pilotage du simulateur
(dont la durée de simulation qui ne pourra être modifiée une fois qu’elle aura démarrée).
L’outil est structuré autour d’une interface utilisateur graphique permettant de consulter les fenêtres de console,
de structure (avec une couleur différente pour chaque formalisme – ELDO/AMS/VHDL), les équipotentielles
(terminaux, quantités, signaux), le source, les process et les variables (dont les génériques manipulables au début
du cycle de simulation).
L’information est organisée sous forme de bibliothèque comme le préconise la norme. Tous les outils utilisés
sont disponibles en mode ligne (vasim : interface graphique et simulation ; vacom : compilateur ; valib, vasetlib :
création bibliothèques ; vadir, vadel, vamap : gestion bibliothèques ; xelga : Grapheur).
Les limitations quant à la couverture de la norme sont assez sévères dans cette version. Quelques-unes unes ne
sont pas documentées et l’utilisateur les découvre au fur et à mesure des développements.
90
TOLERANCES ignorées
Les cibles sous forme d ’aggregats
(A,B,C) <= (‘ 0 ’, ’1 ’, ’0 ’) avec A,B,C : bit ; pas autorisé
Linkage, buffer, Access types
Contraintes
De plus, un modèle purement numérique n ’est pas bien pris en charge par le fichier de commande et il faudra
indiquer explicitement la durée de simulation (RUN xxx ns).
La spécialisation d ’un outil existant (ELDO) génère des limitations et lourdeurs intrinsèques
Cet outil est disponible sur PC et sur SUN. Une version monoposte coûte aux alentours de 40kF. La version
testée n’est que très incomplètement documentée sur la partie AMS et la couverture effective de la norme. La
compilation ne s’appuie pas sur la notion de bibliothèque. Le simulateur est très rapide et d’une utilisation
simple et souple.
A la lecture de la documentation on peut croire que la norme est pratiquement couverte mais à l’utilisation on
s’aperçoit que des constructions comme des quantité sous forme d’enregistrement (record quantities) ou certains
attributs ne sont pas utilisables (sans message explicite du compilateur).
Un modèle est défini par deux fichiers de base : la description (*.nsx) et le fichier de commande (*.pat). Les
fichiers de sources doivent inclure une directive de compilation (>>>VHDL) pour indiquer quel est le langage
utilisé L’ensemble des fichiers à compiler ou à utiliser est décrit dans le fichier de pilotage du compilateur-
simulateur.
91
Une conception VHDL-AMS est intégrable dans un ensemble riche de formalismes interfaçables (VHDL,
VERILOG, SPICE, ABCD).
92
Chapitre 8 : Quelques exemples avancés
8.1 Détecteur de particules et son électronique
8.1.1 Objectif
Les particules énergétiques peuvent être détectées par des «morceaux » de semi-conducteurs soumis à un champ
électrique intense. L’interaction des particules avec le semi-conducteur les transforme en paires électron-trous.
Le champ électrique induit un déplacement des charges électriques, donc un courant. En fait dés la création du
nuage de paires électrons-trous, un courant sera disponible sur les électrodes (théorème de RAMO). Pendant leur
déplacement les particules chargées seront captées par les défauts du cristal (piégeage) et leur nombre ira donc
en diminuant. L’impulsion de courant disponible sur les électrodes sera amplifiée et mise en forme par un shaper
(amplificateur de charges). La mesure de l’énergie de chaque événement se fera alors par l’amplitude ou la
largeur à mi-hauteur des impulsions mises en forme. Le spectre de la source pourra être déterminé en comptant
le nombre d’événement à chaque énergie.
L’objectif principal de ce travail est de fournir un modèle réaliste de détecteur de particules pour optimiser
l’électronique associée. Jusqu’à maintenant, pour ce travail, les détecteurs étaient grossièrement modélisés par
un générateur d’impulsion de courant sur une charge résistive et pris en charge par des simulateurs de type
SPICE. Le modèle présenté ici est construit sur les phénomènes physiques. Il est générique sur le matériau et sur
les dimensions. Le code est très lisible et représente des concepts de haut niveau.
1 ENTITY detector is
2 Generic (sizeX : real; -- detector thiskness in cm
3 w : real := 3.0 -- GAP in ev
4 port (energy_in : in real; energy_out :out real := 0.0;
5 terminal anode, cathode : electrical);
6 END;
7
8 Library ieee; use ieee.math_real.all;
9 Library disciplines; use disciplines.physical_constants.all;
10 ARCHITECTURE archi1 OF detector IS
11 Quantity vbias across in_e,in_t through anode to cathode;
12 Quantity N_e,N_t : real:=0.0; -- nombre de particules générées
13 Quantity Pos_e : real:=0.0; -- position courante des électrons
14 Quantity Pos_t : real:=0.0; -- position courante des trous
15 Quantity Champ : real:=0.0; -- champ électrique
16 Signal N :real:=0.0; -- Quantité de charge crées
93
17 Signal Pos_part : real:=0.0; -- Posiiton à la création
18 Constant v_e : real := 1.0e7;
19 Constant v_t : real := 6.0e5;
20 Constant tau_e : real := 300.0e-9;
21 Constant tau_t : real := 150.0e-9;
22
23 BEGIN
24 Detection:process
25 Variable seed1:integer:=3456; -- for random number generator
26 Variable seed2:integer:=4563;
27 Variable unf,x : real;
28 Variable alpha_p:real:= 10.0; -- [1/cm] photelectric absorb. coeff.
29 Variable alpha_c:real:= 2.0; -- [1/cm] compton absorb. coeff.
30 Begin
31 Wait until energy_in /=0.0; -- waiting for a photon
32 Uniform(seed1,seed2,unf);
33 X := -log(unf)/(alpha_p+alpha_c); -- Exponential absorbtion
34 If x < sizex then -- Absorbtion ?
35 Pos_part <= x;
36 Uniform(seed1,seed2,unf);
37 If unf < (alpha_c/(alpha_c+alpha_p)) then -- Compton/photo.
38 Uniform(seed1,seed2,unf);
39 N <= energy_in * unf / w, 0.0 after 1 ps;
40 Energy_out <= (1.0-unf)*energy_in, 0.0 after 1 ps;
41 else
42 N <= energy_in/w, 0.0 after 1 ps; --all energy deposited
43 End if;
44 Else
45 Energy_out <= energy_in, 0.0 after 1 ps; -- pass through
46 end if;
47 end process;
48
49 break on N; -- Synchro between continuous time and dicret events
50
51 -- moving charges under electrical field and trapping
52
53 if n /= 0.0 use
54 Pos_e == Pos_part; Pos_t == Pos_part; -- Charges creation
55 N_e == N; N_t == N;
56 Else -- trajectory
57 If Pos_e < sizex use
58 Pos_e'dot == v_e; -- constant speed
59 N_e'dot == -N_e / tau_e ; -- trapping electrons
60 Else
61 Pos_e == sizex; N_e == 0.0;
62 End use;
63 If pos_t > 0.0 use
64 Pos_t'dot == -v_t; -- constant speed
65 N_t'dot == -N_t / tau_t ; -- trapping hole
66 Else
67 Pos_t == 0.0; N_t == 0.0;
68 End use;
69 end use;
70 -- RAMO Theorem
71 in_e == N_e * physical_q /sizex * v_e;
72 in_t == N_t * physical_q /sizex * v_t;
73
74 END;
Fig 8.1.3-A : Le code source du détecteur
Lignes Explications
94
1-6 ENTITY : Déclaration et ports
2-3 Paramètres génériques
4-5 Ports
8-9 Déclaration des bibliothèques
10-74 ARCHITECTURE
11-21 Constantes, signaux and quantités locales
23-74 Partie « exécutable »
24-47 Process
25-29 Variables locales au process
30-47 Instructions séquentielles
31 Attente d’un événement
32-47 Calcule la probabilité pour un photon d’être absorbé et la probabilité de produire une interaction
de type compton. Le nombre de porteurs est calculé à partir de l’énergie déposée
49 Synchronisation des noyaux de simulation
53-69 Ces équations définissent le point de vue mécanique des porteurs dans le champ électrique
(trajectoire and piégeage)
72 Théorème de RAMO
73 Note : l’addition de in_e et de in_t est implicit (see line 25)
Fig 8.1.3-A : Structure explicité du code source du détecteur
8.1.4 Le testbench
Pour valider le modèle du détecteur, nous modélisons un environnement à un haut niveau d’abstraction (Source,
Shaper, Spectromètre).
La source de photons est monochromatique et ominidirectionnelle. Elle est générique sur l’énergie (ev) et sur
l’activité (micro-curie). La statistique des événements est de type POISSON et celle de la direction est
UNIFORM.
1 ENTITY source is
2 generic (energy : real :=100.0e3; -- ev
3 activity : real := 50.0); -- microcurie
4 port (event_out,teta,phi:out real := 0.0);
5 end;
6
7 library ieee;
8 use ieee.math_real.all;
9 ARCHITECTURE pulse_proba of source is
10 Begin
11
12 Process
13 Variable seed1:integer:= 2345;
14 variable seed2:integer:= 123;
15 variable unf:real;
16 -- tau en nanosecondes
17 constant tau : real := 1.0e6/(activity*3.7);
18 begin
19 uniform (seed1,seed2,unf);
20 wait for -tau*log(unf) * ns;
21 uniform(seed1,seed2,unf);
22 teta <= 360.0 * unf;
23 uniform(seed1,seed2,unf);
24 phi <= 180.0 * unf;
25 event_out <= energy, 0.0 after 1 ps;
26 end process;
27 end;
Fig 8.1.4-A : Modèle d’une source monochromatique, uniforme en espace avec une statistique de poisson
95
Le shaper est implémenté par une ODE qui modélise le comportement d’un filtre du second ordre. Ce modèle
pourra être remplacé par celui du système électronique à optimiser.
Le spectromètre détecte le passage par zéro de la dérivée de l’impulsion puis incrémente un analyseur
multicanaux. L’index du canal est fixé par l’amplitude au moment de l’annulation de la dérivée de l’impulsion.
96
36 spectre <= 0.0;
37 elsif vtest'dot'above(0.0) = false then
38 -- mise à jour
39 if vtest < ampl_max and vtest > 0.0 then
40 index_tab := integer(real(channel_nb)*vtest/ampl_max);
41 spectre_res(index_tab) := spectre_res(index_tab) + 1;
42 end if;
43 end if;
44 end process;
45 end;
Nous pouvons maintenant instancier tous ces modèles dans un tesbench structurel.
1 Entity testdetector is
2 End;
3
4 Library disciplines; use disciplines.Electromagnetic_system.all;
5 Use work.all;
6 Architecture shaped of testdetector is
7 signal photonin,photonout,teta,phi:real;
8 terminal alim,comm,gnd,shape_out: electrical;
9 quantity tension_alim across alim to gnd;
10 quantity ibias through alim to gnd;
11 quantity tension_shap_out across shape_out to gnd;
12 signal spectre : real := 0.0;
13 constant sizex : real := 0.1; -- épaisseur en cm
14 constant tau:real:=1.0e-6;
15 begin
16 u1:ENTITY source(pulse_proba) generic map (100.0e3,15.0)
17 port map (photonin,teta,phi);
18 u2:ENTITY detector(archi1) generic map (sizex,0.3)
19 port map (photonin, photonout,comm,gnd);
20 u3:ENTITY shaper(archi1) port map (alim,comm,shape_out);
21 u4:ENTITY spectro(algo) generic map (100 ms, 100, 4.0e-5)
22 port map(shape_out,spectre);
23 tension_alim == 10.0e3 * sizex;
24 end;
8.1.5 Résultats
Le comportement du modèle est très proche des comportements théoriques et des mesures. On peut voir sur les
courbes suivantes qui représente l’impulsion de courant, le déficit balistique, l’empilement et le piégeage.
97
Fig 8.1.5-A : Deux impulsions différentes (dépend de la profondeur d’interaction),
les décroissances sont liées au piégeage
98
Fig 8.1.5-C : Sortie du spectromètre de haut niveau avec une source monochromatique
8.2 N-corps
Le modèle décrit dans cette section n’a pas pu être compilé par les outils bien qu’il respecte la norme. Il est cité
pour illustrer les possibilités sémantiques du langage.
8.2.1 Objectif
Ce problème est celui de N corps massifs (ayant une masse) en relation gravitationnelle. Seul le problème à 2
corps a une solution analytique générale et l’appréhension des autres configurations ne peut se faire que par la
simulation. Les équations à mettre en œuvre sont simples ; il s’agit de conditions initiales (masses, positions,
vitesses), de l’équation fondamentale de la dynamique et des équations de déplacement. Tous les calculs doivent
se faire en trois dimensions (accélération, vitesse, position).
Le paquetage N_corps_pak permet de définit un type 3D qui sera utilisé pour tous les vecteurs et un vecteur de
ce type qui permettra de manipuler le système au complet. Différentes fonctions arithmétiques sur les vecteurs
sont définies.
Package N_corps_pak is
type Vector_3D record
x:real;
y:real;
z:real;
end record;
type V_vector_3D is array(range <>) of Vector_3D;
99
function sigma(a:real_vector) return real;
Le modèle par lui-même est basé sur des paramètres génériques (nombre de corps avec leur masse, positions et
vitesses initiales). L’architecture définit les quantités libres qui vont contenir les accélérations, vitesses et
positions courantes. Le modèle est constitué de trois équations vectorielles et matricielles.
-- ******************************************************************
-- ** Modèle des N corps ** Y.HERVE herve@erm1.u-strasbg.fr
-- ** N-bodies simulation ** 09/10/2000
-- ******************************************************************
use work.N_corps_pak.all;
Entity N_corps is
generic (N:integer := 3;
M: real_vector(1 to N)
XYY0:V_vector_3D(M'range);
V0:V_vector_3D(M'range));
end;
use work.N_corps_pak.all;
architecture one of N_corps is
Constant M_T: real := sigma(M);
Quantity XYZ: V_Vector_3D(M’range):= XYZ0;
Quantity V: V_Vector_3D(M’range):= V0;
Quantity Gamma: V_Vector_3D(M’range);
begin
Force(M_T,M,XYZ) == M * Gamma;
V == Gamma'dot + V0;
XYZ == V'dot + XYZ0;
end;
Fig 8.2-B : Le problème des N-corps
Ce modèle n’est pas compilable par les outils actuels qui ont des faiblesses dans la prise en charge des ports ou
des quantités libres sous forme complexe (vecteur, matrices, record ou, pire, combinaison de tous ces types).
Un automate cellulaire est une topologie de cellules. La valeur de chaque cellule, mise à jour sous le contrôle
d’une horloge, dépend de l’état initial et de son voisinage (équation de fonctionnement). Si la structure est
ouverte on peut fixer un ensemble de conditions aux limites.
100
Ces structures sont issues des travaux de Von Neumann sur les machines autoréplicantes. L’automate cellulaire
le plus célèbre est sans aucun doute le jeu de la vie inventé par Conway en 1978. Par cette méthode on peut
résoudre des équations aux dérivées partielles discrétisées (écoulement de fluide, aérodynamique, champ de
pression, …).
Du fait de la synchronisation explicite, l’expression d’un automate cellulaire est facile en VHDL-AMS.
entity Space_2D_time is
generic (N,M as natural;
k: real := 10.0);
end;
-- Automate cellulaire
-- Conditions au limites
for i=1 to N generate
xy(i,0) <= 0.0;
xy(i,M) <= 0.0;
end generate;
for j=1 to M generate
xy(N,j) <= 0.0;
xy(N,j) <= 0.0;
end generate;
end;
Certains systèmes de la nouvelle électronique sont basés sur des réseaux de plots métalliques dans une matrice
isolante. Les plots font quelques nanomètres de diamètre et sont séparés par des distances nanométriques. Un
phénomène physique appelé le blocage de coulomb permet avec ces dispositifs (à une température très basse
101
pour l’instant et grâce à l’effet tunnel) de contrôler le passage des électrons un par un avec des tensions de
commande macroscopiques.
La fabrication de tels systèmes (au stade de la recherche) se fait, par exemple, par pulvérisation d’une pointe de
tungstène sous un champ électrique. Les dispositifs sont fortement aléatoires. Un travail demandé à l’auteur était
d’étudier la statistique de la résistance globale (résistance du chemin de résistance minimum) des réseaux compte
tenu de la statistique du procédé de fabrication (distribution de la taille des plots, distribution des espacements).
Après modélisation par les physiciens du laboratoire reliant les distances et diamètres aux résistances inter plots,
un modèle électrique simple mettant en jeu des résistances avec une dynamique de près de 1030 dans un réseau
2D a été étudié par un procédé de monte-carlo. Le travail a été mené avec des programmes de génération de
netlists SPICE, un simulateur SPICE modifié pour pouvoir manipuler des dynamiques de valeur très étendues et
des outils d’analyse statistique.
La modélisation de ce problème a été reprise depuis l’apparition de VHDL-AMS pour profiter de sa puissance
d’expression ; Sa modélisation devient simple, explicite et générique.
library Disciplines;
use Disciplines.electromagnetical.all;
Entity N-plots is
generic(N,M:integer:=2);
port (terminal vp,vm:electrical); -- Les deux électrodes
end ;
Ce modèle peut être instancié par un testbench faisant les tirages aléatoires des résistances suivant une statistique
connue, rassemblant les résultats et effectuant les analyses statistiques en autonomie. Le testbench peut fournir
directement es histogrammes de résistance série des systèmes produits pour déterminer le rendement de
fabrication (R<1011 ohms).
VHDL-AMS ne permet ni d’exprimer, ni de manipuler des équations aux dérivées partielles. Le modèle suivant
permet de définir une zone de l’espace (par exemple) et son maillage régulier associé. Un champ de valeur est
échantillonné sur cet espace par une quantité matricielle. Chaque point spatial peut être calculé en fonction de
ses voisins au cours de temps.
entity Space_2D_time is
102
generic (N,M as natural;
k: real := 10.0);
end;
-- Excitation
for j=1 to M generate
XY(0,j) == f(now);
end generate;
-- conditions au limites
for i=1 to N generate
XY(i,0) == 0.0;
XY(i,M) == 0.0;
end generate;
for j=1 to M generate
XY (N,j) == 0.0;
XY (N,j) == 0.0;
end generate;
end;
Fig 8.5 : Résolution par VHDL-AMS de PDE
La conversion analogique-numérique est réalisée par des dispositifs qui sont rapides (en MHz) ou précis
(Nombre de bit). Le coût sera directement au facteur de mérite vitesse*résolution. Un système relativement
récent permet un compromis intéressant. Il est basé sur l’asservissement à zéro de l’intégrale (sigma) de l’erreur
(delta) entre le signal et du signal converti sous le contrôle d’une horloge.
On obtient alors un train binaire d’une fréquence beaucoup plus élevée que la fréquence de Shannon dont la
valeur moyenne est égale au signal d’entrée. Ce modulateur sigma-delta produit un « bit stream » qui est ensuite
traité par un filtre analogique qui va permettre d’abaisser la fréquence de sortie par moyennage local
(décimation).
Le schéma de principe est présenté sur la figure suivante. Dans les circuits industriels l’intégration peut être d’un
ordre plus élevé, on a alors des contraintes de stabilité.
+VRef
-
-VRef + Filtre numérique
+ 1 Passe-bas n
Vin D Q
Décimation F/N
103
-
F
Fig 8.6-A : Schéma de principe du modulateur Delta-Sigma suivi du filtre de décimation
L’intérêt de ce principe est que le bruit de conversion est repoussé vers les hautes fréquences. Le rapport signal à
bruit peut facilement monter à plus de 120 dB, ce qui correspond sous certaines hypothèses explicitées dans les
bons livres de traitement de signal à un convertisseur de plus de 20 bits équivalents.
La difficulté d’étude avec ce type de système est que la simulation est difficile. En effet les constantes de temps
très différentes imposent un nombre de points de calcul incompatible avec des durées permettant d’analyser une
plage temporelle suffisante. La partie analogique doit être simulée avec un pas permettant de traiter l’intégration,
le train de bit peut être traité à la fréquence de l’horloge alors que le filtre numérique peut être simulé à la
fréquence de sortie. VHDL-AMS apporte une solution naturelle à ce problème, on peut étudier le modulateur à
un niveau technologique suffisamment bas pour prévoir tous les cas de figure. La partie décimation sera étudiée
en remplaçant le modulateur par sa version comportementale qui remplace l’intégration analogique gérée par le
simulateur par une intégration numérique gérée par le modèle lui-même. Le rapport des temps de simulation est
d’environ 15 en faveur du modèle de haut niveau.
library disciplines;
use disciplines.electromagnetic_system.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
use work.all;
entity modulator is
generic (K:real := 1.0;
vref:real :=5.0);
port (terminal T_in :electrical;
signal S_out : out std_ulogic;
signal clock : in std_ulogic);
end entity;
DeltSig: process
variable S_mem, S_int : real := 0.0;
begin
wait until clock = '1'; -- détection de front montant
S_int := S_int + K * (vin - S_mem); -- intégration numérique
SS_int <= S_int;
S_mem := sign(S_int) * vref; -- somme d’entrée
if S_int > 0.0 then S_out <= '1'; -- comparateur
else S_out <= '0'; end if;
end process;
end;
104
LocQ <= (vint > 0.0) when clock='1';
vint'dot
S_out <= ==
'1'Kwhen
* (vin - vmem);
LocQ Else '0'; -- intégrateur de différence
Break on LocQ;
if LocQ use
vmem == vref;
else
vmem == -vref;
end use;
end;
Cet exemple reprend un système dont l’étude est la trame de l’apprentissage des outils de CAO électronique pour
le DESS Systèmes Electroniques Intégrés de l’Université Louis Pasteur de Strasbourg et de la troisième année,
option micro-électronique, de l’Ecole Nationale Supérieure de Physique de Strasbourg. Il a été mis au point en
collaboration avec Luc HEBRARD et Freddy ANSTOTZ du LEPSI-Strasbourg.
L’objectif du projet est de concevoir un circuit intégré permettant de mesurer le champ magnétique local. Le
capteur à effet hall de champ magnétique est constitué d’un caisson dopé N avec 4 contacts. Après étude
théorique et architecturale la chaîne de traitement de l’information a été figée. Nous présentons ici les deux
premières étapes de la conception : le cahier des charges et le structurel de comportementaux.
Library IEEE;
Use IEEE.Math_real.all;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_SIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
105
Library Disciplines;
Use Disciplines.Electromagnetic_system.all;
Entity System is
port (terminal B: magnetic;
terminal alim_p,alim_m,alim_gnd,vref:electrical;
signal clk128, on_off : in std_ulogic;
signal serial_out, clk2_out, strobe : out std_ulogic;
signal parallel_out :out signed(7 downto 0));
end;
div_horloge:process
variable compt64 : integer := 0;
variable compt8 : integer:=0;
begin
wait on clk128;
compt64 := (compt64 + 1) mod 32; -- division par 64
compt8 := (compt8 + 1) mod 4; -- division par 8
if compt64=0 then clk2 <= not clk2; end if;
if compt8=0 then clk16 <= not clk16; end if;
end process;
system : process
variable loc_para:signed(parallel_out'range);
begin
wait until clk2 = '1';
loc_para := conv_signed(integer(Gain * Champ),loc_para'length);
parallel_out <= loc_para;
serial_out <= loc_para(7);
strobe <= '1';
wait until clk16='1';
strobe <= '0';
serial_out <= loc_para(6);
for i in 5 downto 0 loop
wait until clk16='1';
serial_out <= loc_para(i);
end loop;
end process;
end;
106
Fig 8.7-B : Code source du système sous forme comportementale
Une fois que le cahier des charges est validé, on peut commencer l’étude des sous systèmes. Un modèle
structurel des différents objets sous leur forme comportementale peut donc être écrit pour fixer les interfaces.
use work.all;
Architecture CdC_struct of System is
-- liaisons intermédiaires
terminal t1,t2,t3,t4,t5 : electrical;
signal s1 : std_ulogic_vector(7 downto 0);
signal s2 : signed (7 downto 0);
signal clk16,clk2:std_ulogic;
quantity v across i through alim_gnd;
begin
v == 0.0; -- La masse
Dans cet exemple on gagnerait énormément à utiliser une configuration pour profiter des études multi-
abstraction intermédiaires (voir 5.1.3) mais l’outil utilisé ne le supporte pas. Chacun des objets peut alors être
étudié tout en tenant compte des autres objets sous forme comportementale ou technologique.
107
Fig 8.7-C : Comparaison des sorties du modulateur delta-sigma
En analogique (2 et 4) et numérique (1 et 3) (bit-stream et erreur intégrée)
Avec excitation sinusoïdale (en bas)
108
Chapitre 9 : Le futur
La renormalisation de VHDL-AMS est prévue pour 2004. Des groupes de travail étudient déjà différentes
possibilités d’évolution. Certains étudient la possibilité d’intégrer MHDL [MHDL], d’autres la possibilité de
définir une sémantique orientée objet.
Les différentes limitations évoquées au 6.1 seront certainement abordées au cours la préparation de la nouvelle
norme (manipulations d’unités, équations aux dérivées partielles, sémantique de connexion).
Les évolutions à court terme à souhaiter pour des gains de productivité, en support du langage actuel, sont
centrées sur le développement de simulateurs natifs supportant vraiment toutes les exigences de la norme avec
des interfaces homme-machine de haut niveau comme on sait déjà les produire pour les outils du numérique. La
complexité des modèles profitera pleinement des développements de simulateurs sur machines parallèles ou
distribuées.
De façon beaucoup plus large, sans liaison directe avec le langage présenté dans cet ouvrage, les besoins à plus
long terme sont étudiés par des organismes de prospectives [ROAD]. Les points forts de ces études soulignent
surtout les besoins en modélisation et simulation au niveau procédé de fabrication et composants élémentaires.
Les besoins de modélisation pour les composants en haute et très hautes fréquences ainsi que pour les
interconnexions rapides, ce qui impliquent le support des constantes réparties, sont importants. Il faudra pour ces
activités tenir compte des effets parasites de la technologie (bruit de substrat, …) et de l’environnement pour
mener les études complètes et précises. La modélisation électromagnétique devra remplacer la simple
modélisation électrique pour effectuer les études CEM. La modélisation basée sur la physique des composants de
très petite géométrie devra être améliorée en tenant compte de tous les effets parasites (électriques, thermiques,
mécaniques). Les modèles devront «descendre » jusqu’à la prise en compte des phénomènes atomiques et des
effets quantiques, parasites ou utiles. La variabilité des paramètres de fabrication peut devenir prépondérante
quand la géométrie est proche des limites des tolérances propres des procédés mis en jeu ; les modèles devront
tenir compte de ces distributions statistiques effectives pour faire les conceptions dans le cas moyen ou dans le
pire des cas.
Au niveau des systèmes l’accent est mis sur les évolutions vers une plus grande intégration dans les flots de
conception de toutes les disciplines effectivement présente dans les micro-systèmes (SoC : System on chip) ; Les
modélisations et les simulations devront pouvoir se faire en vraies 3D.
On peut penser raisonnablement que le vecteur d’un langage commun à toute la communauté universitaire et
industrielle devrait dynamiser les recherches dans le domaine de la synthèse analogique.
Conclusion
Nous espérons avoir démontré dans cet ouvrage tous les atouts de l’approche de haut niveau pour la conception
des systèmes complexes à l’aide d’un HDL. Le langage présenté, VHDL-AMS, a tous les avantages -
polyvalence, adaptabilité, (re)normalisation active - pour devenir le vecteur commun de la profession.
Il ne faut pas s’arrêter au langage mais bien voir comment les outils associés vont évoluer et converger vers des
moyens permettant les gains de productivité et de fiabilité pour relever les défis de l’électronique de demain.
Les jeunes électroniciens sont de mieux en mieux formés à l’approche informatique de leur métier mais
l’adoption d’un langage comme VHDL-AMS va sans aucun doute créer une nouvelle spécialité dans les équipes
de conception. Les jeunes (et les moins jeunes) qui maîtriseront la modélisation à tous les niveaux, de tous les
phénomènes physiques importants seront des personnes très recherchées par les entreprises.
VHDL a mis entre 5 et 10 ans à s’imposer dans l’industrie électronique. Avec les langages mixtes, dont VHDL-
AMS, une nouvelle étape est franchie. Le substrat VHDL déjà installé permettra sans doute à son extension
analogique de s’imposer plus rapidement. Actuellement, les concepteurs qui maîtrisent aussi bien l’électronique
analogique que numérique, sa modélisation au niveau cahier des charges et au niveau technologique sont
extrêmement rares mais ils pourront s’exprimer pleinement avec ces nouveaux outils.
C’est bien un nouveau métier qui est en train de naître dans cette industrie,
C’est aux jeunes de prendre le train au bon moment, c’est à dire maintenant !
109
Bibliographie
[ADV] Documentation de ADV-MS de Mentor Graphics / Anacad (Version 1.1_1.1)
110
Glossaire
Cellules précaractérisées : Un fondeur de circuit fournit à ses clients une base de données des cellules pouvant
être fabriqués dans sa technologie. Chacune d’entre elle est caractérisée en surface,
consommation, fonction, … . La conception des ASICs se fait par l’assemblage des
ces cellules. Quand les cellules sont dans une sign-off library (bibliothèque de
référence) et manipulées par un Golden simulator (simulateur de référence), si la
simulation est juste le fondeur s’engage à un circuit juste par conception (plus de
prototypes)
CPLD : (Complex Programmable Logic Device) Composant programmable sur site ayant la
particularité d’être prévisible en temps (pas de routage). Les temps de retards entrée-
sortie sont connus et fixes au moment de la conception.
Embedded software : Logiciel embarqué (par exemple le logiciel à l’intérieur des téléphones portables).
DRC : (Design Rule Check) Etape de vérification permettant de vérifier toutes les règles de
conception notamment pour les circuits intégrés. La filière technologique impose des
contraintes (plusieurs centaines dans certains cas) que l’on doit respecter (largeur des
pistes, distances entres les parties actives, …) Est souvent couplé à l’ERC pour
Electrical Rule Check.
FPGA : (Field Programmable Gate Array) Matrice Logique programmable sur le site. Ces
circuits permettent de disposer d’un circuit personnalisé sans passer par
l’intermédiaire d’un fondeur. Certains d’entre eux sont même programmables in-situ,
c’est à dire sur la carte les embarquant. Actuellement il existe des circuits mettant à la
disposition de l’utilisateur l’équivalent de 1 million de portes. Leur mise en œuvre se
fait par l’intermédiaire d’un HDL (la plupart du temps VHDL) et la synthèse logique.
LVS : (Layout Versus Schematic) Outil de vérification permettant d’extraire un schéma (ou
une description HDL) depuis un layout (la descrition au niveau géométrique de
l’implantation des transistors). En comparant la description ayant permis de définir le
layout à celle qui en est extraite, n peut vérifier si aucun transistor ou aucune
équipotentielle n’a été oublié.
Placement-routage : Placement : opération de back-end par laquelle on va placer sur le substrat les macro-
cellules de la conception. On essaiera de satisfaire des contraintes glogales pour
faciliter l’opération suivante
Routage : interconnexion automatique de cellules placées.
111
De plus en plus souvent ces deux fonctions sont réalisées en même temps.
PREDIFFUSES : Le fondeur met à disposition sur catalogue des circuits comprenant un ensemble de
ressources et c’est à l’utilisateur de prévoir les dernières couches d’interconnexions
pour spécialiser le circuit. La fabrication s’en trouve accélérée de beaucoup. Devant la
facilité d’emploi des FPGA/CPLD et la démocratisation des pré-caractérisés, cette
technique est limitée à des besoins très spécifiques. Un prédiffusé ne comportant que
des ressources de bas niveau s ‘appelle un sea-of-gate (ou mer de portes).
Synthèse logique : C’est l’opération qui permet de fabriquer automatiquement un système numérique à
partir d’une description de haut niveau sous forme de schéma (interconnexion de
primitives), de HDL , d’autres formalismes de haut niveau ou d’un mélange de ceux
ci.
Time to market : C’est le temps théorique qui sépare le moment de la décision de démarrer le projet et
la date prévue de mise sur le marché pour maximiser les profits. C’est un concept
marketing qui impose aux équipes de concepteurs des contraintes fortes.
Workflow : Ou flot de conception, c’est l ‘ensemble des outils et leur enchaînement, les méthodes
associées, les formats de fichiers permettant de remplir une tâche. Le workflow de la
conception de circuits intégrés, qui comprend le front-end et le back-end, démarre
avec le cahier des charges et termine avec le circuit intégré fabriqué et testé.
112
Annexes
Le contenu du CD-ROM
Niveaux d'abstraction
113
Liste des 108 mot-clés de VHDL-AMS
Abs if register
access impure (93) reject (93)
across (99) in rem
after inertial (93) report
alias inout return
all is rol (93)
and ror (93)
architecture library
array limit (99) select
assert linkage severity
attribute loop signal
shared (93)
begin map sla (93)
block mod sll (93)
body spectrum (99)
break (99) nand sra (93)
buffer nature (99) srl (93)
bus new subnature (99)
next subtype
case noise
component nor terminal (99)
configuration not then
constant null through (99)
to
disconnect of tolerance (99)
downto on transport
open type
else or
elsif others unaffected (99)
end out units
entity until
exit package use
port
file postponed (93) variable
for procedural (99)
function procedure wait
process when
generate pure (93) while
generic with
group (93) quantity (99)
guarded xnor (93)
range xor
record
reference (99)
114
La grammaire VHDL-AMS
Conventions d'écriture
Les règles ont un nom (membre gauche du ::=) et sont exprimées en fonctions d'autres règles ou de jetons
(symboles terminaux)
Les indications de la forme [$xx.x] font référence aux paragraphes du LRM où la règle est traitée. Liste des
règles d'instructions (une construction terminée par ;) :
115
architecture_declarative_part begin
architecture_statement_part
end [ architecture ] [ identifier ] ;
15 [$ 1.2.1] architecture_declarative_part ::= { block_declarative_item }
16 [$ 1.2.2] architecture_statement ::= simultaneous_statement | concurrent_statement
17 [$ 1.2.2] architecture_statement_part ::= { architecture_statement }
18 [$ 3.5.2.1] array_nature_definition ::= unconstrained_nature_definition | constrained_nature_definition
19 [$ 3.2.1] array_type_definition ::= unconstrained_array_definition | constrained_array_definition
20 [$ 8.2] assertion ::= assert condition [ report expression ] [severity expression ]
21 [$ 8.2] assertion_statement ::= [ label : ] assertion ;
22 [$ 4.3.2.2] association_element ::= [ formal_part => ] actual_part
23 [$ 4.3.2.2] association_list ::= association_element { , association_element}
24 [$ 4.4] attribute_declaration ::= attribute identifier : type_mark ;
25 [$ 6.6] attribute_designator ::= attribute_simple_name
26 [$ 6.6] attribute_name ::= prefix [ signature ] ' attribute_designator [ ( expression { , expression } ) ]
27 [$ 5.1] attribute_specification ::= attribute attribute_designator of entity_specification is expression ;
28 [$ 13.4.2] base ::= integer
29 [$ 13.7] base_specifier ::= B | O | X
30 [$ 3.1.3] base_unit_declaration ::= identifier ;
31 [$ 13.4.2] based_integer ::= extended_digit { [ underline ] extended_digit }
32 [$ 13.4.2] based_literal ::= base # based_integer [ . based_integer ] # [exponent ]
33 [$ 13.1] basic_character ::= basic_graphic_character | format_effector
34 [$ 13.1] basic_graphic_character ::= upper_case_letter | digit | special_character | space_character
35 [$ 13.3.1] basic_identifier ::= letter { [ underline ] letter_or_digit }
36 [$ 5.2.1] binding_indication ::= [ use entity_aspect ] [ generic_map_aspect] [ port_map_aspect ]
37 [$ 13.7] bit_string_literal ::= base_specifier " [ bit_value ] "
38 [$ 13.7] bit_value ::= extended_digit { [ underline ] extended_digit }
39 [$ 1.3.1] block_configuration ::= for block_specification { use_clause } {configuration_item } end for ;
40 [$ 1.2.1] block_declarative_item ::= subprogram_declaration |
subprogram_body | type_declaration |
subtype_declaration | constant_declaration |
signal_declaration |
shared_variable_declaration | file_declaration |
alias_declaration | component_declaration |
attribute_declaration | attribute_specification |
configuration_specification |
disconnection_specification |
step_limit_specification | use_clause |
group_template_declaration |
group_declaration | nature_declaration |
subnature_declaration | quantity_declaration |
terminal_declaration
41 [$ 9.1] block_declarative_part ::= { block_declarative_item }
42 [$ 9.1] block_header ::= [ generic_clause [ generic_map_aspect ;]][port_clause [ port_map_aspect ;]]
43 [$ 1.3.1] block_specification ::= architecture_statement_label |
block_statement_label |
generate_statement_label [ (
index_specification ) ]
44 [$ 9.1] block_statement ::= block_label : block [ ( guard_expression ) ]
[ is ] block_header block_declarative_part
begin block_statement_part end block [
block_label ] ;
45 [$ 9.1] block_statement_part ::= { concurrent_statement architecture_statement }
46 [$ 4.3.1.6] branch_quantity_declaration ::= quantity [ across_aspect ] [ through_aspect] terminal_aspect ;
47 [$ 8.14] break_element ::= [ break_selector_clause ] quantity_name => expression
48 [$ 8.14] break_list ::= break_element { , break_element }
49 [$ 8.14] break_selector_clause ::= for quantity_name use
50 [$ 8.14] break_statement ::= [ label : ] break [ break_list ] [ when condition ] ;
51 [$ 8.8] case_statement ::= [ case_label : ] case expression is
case_statement_alternative {
116
case_statement_alternative } end case [
case_label ] ;
52 [$ 8.8] case_statement_alternative ::= when choices => sequence_of_statements
53 [$ 13.5] character_literal ::= ' graphic_character '
54 [$ 7.3.2] choice ::= simple_expression | discrete_range | element_simple_name | others
55 [$ 7.3.2] choices ::= choice { | choice }
56 [$ 1.3.2] component_configuration ::= for component_specification
[binding_indication ; ] [ block_configuration ] end for ;
57 [$ 4.5] component_declaration ::= component identifier [ is ] [ local_generic_clause ]
[local_port_clause ] end component [ component_simple_name ] ;
58 [$ 9.6] component_instantiation_statement ::= instantiation_label : instantiated_unit
[generic_map_aspect ] [ port_map_aspect ] ;
59 [$ 5.2] component_specification ::= instantiation_list : component_name
60 [$ 3.5.2] composite_nature_definition ::= array_nature_definition | record_nature_definition
61 [$ 3.2] composite_type_definition ::= array_type_definition | record_type_definition
62 [$ 9.4] concurrent_assertion_statement ::= [ label : ] [ postponed ] assertion ;
63 [$ 9.8] concurrent_break_statement ::= [ label : ] break [ break_list ]
[sensitivity_clause ] [ when condition ] ;
64 [$ 9.3] concurrent_procedure_call_statement ::= [ label : ] [ postponed ] procedure_call ;
65 [$ 9.5] concurrent_signal_assignment_statement ::= [ label : ] [ postponed ]
conditional_signal_assignment | [ label : ]
[postponed ] selected_signal_assignment
66 [$ 9] concurrent_statement ::= block_statement | process_statement |
concurrent_procedure_call_statement |
concurrent_assertion_statement |
concurrent_signal_assignment_statement |
component_instantiation_statement |
generate_statement |
concurrent_break_statement
67 [$ 8.1] condition ::= boolean_expression
68 [$ 8.1] condition_clause ::= until condition
69 [$ 9.5.1] conditional_signal_assignment ::= target <= options conditional_waveforms ;
70 [$ 9.5.1] conditional_waveforms ::= { waveform when condition else }
waveform [ when condition ]
71 [$ 1.3] configuration_declaration ::= configuration identifier of entity_name is
configuration_declarative_part
block_configuration end [ configuration ]
[identifier ] ;
72 [$ 1.3] configuration_declarative_item ::= use_clause | attribute_specification | group_declaration
73 [$ 1.3] configuration_declarative_part ::= { configuration_declarative_item }
74 [$ 1.3.1] configuration_item ::= block_configuration | component_configuration
75 [$ 5.2] configuration_specification ::= for component_specification binding_indication ;
76 [$ 4.3.1.1] constant_declaration ::= constant identifier_list : subtype_indication [:= expression ] ;
77 [$ 3.2.1] constrained_array_definition ::= array index_constraint of element_subtype_indication
78 [$ 3.5.2.1] constrained_nature_definition ::= array index_constraint of subnature_indication
79 [$ 4.2] constraint ::= range_constraint | index_constraint
80 [$ 11.3] context_clause ::= { context_item }
81 [$ 11.3] context_item ::= library_clause | use_clause
82 [$ 13.4.1] decimal_literal ::= integer [ . integer ] [ exponent ]
83 [$ 4] declaration ::= type_declaration | subtype_declaration |
object_declaration | interface_declaration |
alias_declaration | attribute_declaration |
component_declaration |
group_template_declaration |
group_declaration | entity_declaration |
configuration_declaration |
subprogram_declaration | package_declaration
| nature_declaration | subnature_declaration |
quantity_declaration | terminal_declaration
84 [$ 8.4] delay_mechanism ::= transport | [ reject time_expression ] inertial
117
85 [$ 11.1] design_file ::= design_unit { design_unit }
86 [$ 11.1] design_unit ::= context_clause library_unit
87 [$ 2.1] designator ::= identifier | operator_symbol
88 [$ 3.1] direction ::= to | downto
89 [$ 5.3] disconnection_specification ::= disconnect guarded_signal_specification
after time_expression ;
90 [$ 3.2.1] discrete_range ::= discrete_subtype_indication | range
91 [$ 7.3.2] element_association ::= [ choices => ] expression
92 [$ 3.2.2] element_declaration ::= identifier_list : element_subtype_definition ;
93 [$ 3.5.2.2] element_subnature_definition ::= subnature_indication
94 [$ 3.2.2] element_subtype_definition ::= subtype_indication
95 [$ 5.2.1.1] entity_aspect ::= entity entity_name [ ( architecture_identifier) ] |
configuration configuration_name | open
96 [$ 5.1] entity_class ::= entity | architecture | configuration
| procedure | function | package | type | subtype
| constant | signal | variable | component | label |
literal | units | group | file | nature | subnature |
quantity | terminal
97 [$ 4.6] entity_class_entry ::= entity_class [ <> ]
98 [$ 4.6] entity_class_entry_list ::= entity_class_entry { , entity_class_entry }
99 [$ 1.1] entity_declaration ::= entity identifier is entity_header
entity_declarative_part [ begin
entity_statement_part ] end [ entity ] [
entity_simple_name ] ;
100 [$ 1.1.2] entity_declarative_item ::= subprogram_declaration |
subprogram_body | type_declaration |
subtype_declaration | constant_declaration |
signal_declaration |
shared_variable_declaration | file_declaration |
alias_declaration | attribute_declaration |
attribute_specification |
disconnection_specification |
step_limit_specification | use_clause |
group_template_declaration |
group_declaration | nature_declaration |
subnature_declaration | quantity_declaration |
terminal_declaration
101 [$ 1.1.2] entity_declarative_part ::= { entity_declarative_item }
102 [$ 5.1] entity_designator ::= entity_tag [ signature ]
103 [$ 1.1.1] entity_header ::= [ formal_generic_clause ] [formal_port_clause ]
104 [$ 5.1] entity_name_list ::= entity_designator { , entity_designator } | others | all
105 [$ 5.1] entity_specification ::= entity_name_list : entity_class
106 [$ 1.1.3] entity_statement ::= concurrent_assertion_statement |
passive_concurrent_procedure_call_statement
| passive_process_statement
107 [$ 1.1.3] entity_statement_part ::= { entity_statement }
108 [$ 5.1] entity_tag ::= simple_name | character_literal | operator_symbol
109 [$ 3.1.1] enumeration_literal ::= identifier | character_literal
110 [$ 3.1.1] enumeration_type_definition ::= ( enumeration_literal { , enumeration_literal} )
111 [$ 8.11] exit_statement ::= [ label : ] exit [ loop_label ] [ when condition ] ;
112 [$ 13.4.1] exponent ::= E [ + ] integer | E - integer
113 [$ 7.1] expression ::= relation { and relation } | relation { or relation } | relation { xor relation }
| relation [ nand relation ] | relation [ nor relation ] |
relation { xnor relation }
114 [$ 13.4.2] extended_digit ::= digit | letter
115 [$ 13.3.2] extended_identifier ::= \ graphic_character { graphic_character } \
116 [$ 7.1] factor ::= primary [ ** primary ] | abs primary | not primary
117 [$ 4.3.1.4] file_declaration ::= file identifier_list : subtype_indication [file_open_information ] ;
118 [$ 4.3.1.4] file_logical_name ::= string_expression
119 [$ 4.3.1.4] file_open_information ::= [ open file_open_kind_expression ] is file_logical_name
118
120 [$ 3.4] file_type_definition ::= file of type_mark
121 [$ 3.1.4] floating_type_definition ::= range_constraint
122 [$ 4.3.2.2] formal_designator ::= generic_name | port_name | parameter_name
123 [$ 2.1.1] formal_parameter_list ::= parameter_interface_list
124 [$ 4.3.2.2] formal_part ::= formal_designator | function_name ( formal_designator ) | type_mark
(formal_designator )
125 [$ 4.3.1.6] free_quantity_declaration ::= quantity identifier_list : subtype_indication
[:= expression ] ;
126 [$ 4.1] full_type_declaration ::= type identifier is type_definition ;
127 [$ 7.3.3] function_call ::= function_name [ ( actual_parameter_part ) ]
128 [$ 9.7] generate_statement ::= generate_label : generation_scheme generate
[ { block_declarative_item } begin ]
{concurrent_statement }
{architecture_statement } end generate
[ generate_label ] ;
129 [$ 9.7] generation_scheme ::= for generate_parameter_specification | if condition
130 [$ 1.1.1] generic_clause ::= generic ( generic_list ) ;
130 [$ 1.1.1.1] generic_list ::= generic_interface_list
132 [$ 5.2.1.2] generic_map_aspect ::= generic map ( generic_association_list )
133 [$ 13.1] graphic_character ::= basic_graphic_character | lower_case_letter | other_special_character
134 [$ 4.7] group_constituent ::= name | character_literal
135 [$ 4.7] group_constituent_list ::= group_constituent { , group_constituent }
136 [$ 4.7] group_declaration ::= group identifier : group_template_name (group_constituent_list ) ;
137 [$ 4.6] group_template_declaration ::= group identifier is ( entity_class_entry_list ) ;
138 [$ 5.3] guarded_signal_specification ::= guarded_signal_list : type_mark
139 [$ 13.3] identifier ::= basic_identifier | extended_identifier
140 [$ 3.2.2] identifier_list ::= identifier { , identifier }
141 [$ 8.7] if_statement ::= [ if_label : ] if condition then sequence_of_statements
{ elsif condition then sequence_of_statements }
[ else sequence_of_statements ] end if [ if_label ] ;
142 [$ 3.3.1] incomplete_type_declaration ::= type identifier ;
143 [$ 3.2.1] index_constraint ::= ( discrete_range { , discrete_range } )
144 [$ 1.3.1] index_specification ::= discrete_range | static_expression
145 [$ 3.2.1] index_subtype_definition ::= type_mark range <>
146 [$ 6.4] indexed_name ::= prefix ( expression { , expression } )
147 [$ 9.6] instantiated_unit ::= [ component ] component_name | entity
entity_name [ ( architecture_identifier ) ] |
configuration configuration_name
148 [$ 5.2] instantiation_list ::= instantiation_label { , instantiation_label } | others | all
149 [$ 13.4.1] integer ::= digit { [ underline ] digit }
150 [$ 3.1.2] integer_type_definition ::= range_constraint
151 [$ 4.3.2] interface_constant_declaration ::= [ constant ] identifier_list : [ in ]
subtype_indication [ := static_expression ]
152 [$ 4.3.2] interface_declaration ::= interface_constant_declaration |
interface_signal_declaration |
interface_variable_declaration |
interface_file_declaration |
interface_terminal_declaration |
interface_quantity_declaration
153 [$ 4.3.2.1] interface_element ::= interface_declaration
154 [$ 4.3.2] interface_file_declaration ::= file identifier_list : subtype_indication
155 [$ 4.3.2.1] interface_list ::= interface_element { ; interface_element }
156 [$ 4.3.2] interface_quantity_declaration ::= quantity identifier_list : [ in | out ]
subtype_indication [ := static_expression ]
157 [$ 4.3.2] interface_signal_declaration ::= [signal] identifier_list : [ mode ]
subtype_indication [ bus ] [ := static_expression ]
158 [$ 4.3.2] interface_terminal_declaration ::= terminal identifier_list : subnature_indication
159 [$ 4.3.2] interface_variable_declaration ::= [variable] identifier_list : [ mode ]
subtype_indication [ := static_expression ]
160 [$ 8.9] iteration_scheme ::= while condition | for loop_parameter_specification
119
161 [$ 9.7] label ::= identifier
162 [$ 13.3.1] letter ::= upper_case_letter | lower_case_letter
163 [$ 13.3.1] letter_or_digit ::= letter | digit
164 [$ 11.2] library_clause ::= library logical_name_list ;
165 [$ 11.1] library_unit ::= primary_unit | secondary_unit
166 [$ 7.3.1] literal ::= numeric_literal | enumeration_literal | string_literal | bit_string_literal | null
167 [$ 11.2] logical_name ::= identifier
168 [$ 11.2] logical_name_list ::= logical_name { , logical_name }
169 [$ 7.2] logical_operator ::= and | or | nand | nor | xor | xnor
170 [$ 8.9] loop_statement ::= [ loop_label : ] [ iteration_scheme ] loop
sequence_of_statements end loop [ loop_label] ;
171 [$ 7.2] miscellaneous_operator ::= ** | abs | not
172 [$ 4.3.2] mode ::= in | out| inout | buffer | linkage
173 [$ 7.2] multiplying_operator ::= * | / | mod | rem
174 [$ 6.1] name ::= simple_name | operator_symbol | selected_name | indexed_name | slice_name
| attribute_name
175 [$ 4.8] nature_declaration ::= nature identifier is nature_definition ;
176 [$ 4.8] nature_definition ::= scalar_nature_definition | composite_nature_definition
177 [$ 3.5.2.2] nature_element_declaration ::= identifier_list : element_subnature_definition
178 [$ 4.8] nature_mark ::= nature_name | subnature_name
179 [$ 8.10] next_statement ::= [ label : ] next [ loop_label ] [ when condition ] ;
180 [$ 8.13] null_statement ::= [ label : ] null ;
181 [$ 7.3.1] numeric_literal ::= abstract_literal | physical_literal
182 [$ 4.3.1] object_declaration ::= constant_declaration | signal_declaration |
variable_declaration | file_declaration |
terminal_declaration | quantity_declaration
183 [$ 2.1] operator_symbol ::= string_literal
184 [$ 9.5] options ::= [ guarded ] [ delay_mechanism ]
185 [$ 2.6] package_body ::= package body package_simple_name is
package_body_declarative_part end [
package body ] [ package_simple_name ] ;
186 [$ 2.6] package_body_declarative_item subprogram_declaration |
subprogram_body | type_declaration |
subtype_declaration | constant_declaration |
shared_variable_declaration | file_declaration |
alias_declaration | use_clause |
group_template_declaration |
group_declaration
187 [$ 2.6] package_body_declarative_part ::= { package_body_declarative_item }
188 [$ 2.5] package_declaration ::= package identifier is
package_declarative_part end [ package ] [identifier ] ;
189 [$ 2.5] package_declarative_item ::= subprogram_declaration | type_declaration |
subtype_declaration | constant_declaration |
signal_declaration |
shared_variable_declaration | file_declaration |
alias_declaration | component_declaration |
attribute_declaration | attribute_specification |
disconnection_specification | use_clause |
group_template_declaration |
group_declaration | nature_declaration |
subnature_declaration | terminal_declaration
190 [$ 2.5] package_declarative_part ::= { package_declarative_item }
191 [$ 8.9] parameter_specification ::= identifier in discrete_range
192 [$ 3.1.3] physical_literal ::= [ abstract_literal ] unit_name
193 [$ 3.1.3] physical_type_definition ::= range_constraint units
base_unit_declaration
{secondary_unit_declaration } end units
[physical_type_simple_name ]
194 [$ 1.1.1] port_clause ::= port ( port_list ) ;
195 [$ 1.1.1.2] port_list ::= port_interface_list
120
196 [$ 5.2.1.2] port_map_aspect ::= port map ( port_association_list )
197 [$ 6.1] prefix ::= name | function_call
198 [$ 7.1] primary ::= name | literal | aggregate | function_call |
qualified_expression | type_conversion |
allocator | ( expression )
199 [$ 11.1] primary_unit ::= entity_declaration |
configuration_declaration |
package_declaration
200 [$ 15.4] procedural_declarative_item ::= subprogram_declaration |
subprogram_body | type_declaration |
subtype_declaration | constant_declaration |
variable_declaration | alias_declaration |
attribute_declaration | attribute_specification |
use_clause | group_template_declaration |
group_declaration
201 [$ 15.4] procedural_declarative_part ::= { procedural_declarative_item }
202 [$ 15.4] procedural_statement_part ::= { sequential_statement }
203 [$ 8.6] procedure_call ::= procedure_name [ ( actual_parameter_part ) ]
204 [$ 8.6] procedure_call_statement ::= [ label : ] procedure_call ;
205 [$ 9.2 ] process_declarative_item ::= subprogram_declaration |
subprogram_body | type_declaration |
subtype_declaration | constant_declaration |
variable_declaration | file_declaration |
alias_declaration | attribute_declaration |
attribute_specification | use_clause |
group_template_declaration |
group_declaration
206 [$ 9.2 ] process_declarative_part ::= { process_declarative_item }
207 [$ 9.2 ] process_statement ::= [ process_label : ] [ postponed ] process
[(sensitivity_list ) ] [ is ]
process_declarative_part begin
process_statement_part end [ postponed ]
process [ process_label ] ;
208 [$ 9.2 ] process_statement_part ::= { sequential_statement }
209 [$ 7.3.4] qualified_expression ::= type_mark ' ( expression ) | type_mark ' aggregate
210 [$ 4.3.1.6] quantity_declaration ::= free_quantity_declaration |
branch_quantity_declaration |
source_quantity_declaration
211 quantity_list ::= quantity_name { , quantity_name } | others | all
212 quantity_specification ::= quantity_list : type_mark
213 [$ 3.1] range ::= range_attribute_name | simple_expression direction simple_expression
214 [$ 3.1] range_constraint ::= range range
215 [$ 3.5.2.2] record_nature_definition ::= record nature_element_declaration
{nature_element_declaration } end record
[ record_nature_simple_name ]
216 [$ 3.2.2] record_type_definition ::= record element_declaration
{element_declaration } end record
[ record_type_simple_name ]
217 [$ 7.1] relation ::= shift_expression [ relational_operator shift_expression ]
218 [$ 7.2] relational_operator ::= = | /= | < | <= | > | >=
219 [$ 8.3] report_statement ::= [ label : ] report expression [ severity expression ] ;
220 [$ 8.12] return_statement ::= [ label : ] return [ expression ] ;
221 [$ 3.5.1] scalar_nature_definition ::= type_mark across type_mark through identifier reference
222 [$ 3.1] scalar_type_definition ::= enumeration_type_definition |
integer_type_definition |
floating_type_definition |
physical_type_definition
223 [$ 11.1] secondary_unit ::= architecture_body | package_body
224 [$ 3.1.3] secondary_unit_declaration ::= identifier = physical_literal ;
225 [$ 6.3] selected_name ::= prefix . suffix
121
226 [$ 9.5.2] selected_signal_assignment::= with expression select target <= options
selected_waveforms ;
227 [$ 9.5.2] selected_waveforms ::= { waveform when choices , } waveform when choices
228 [$ 8.1] sensitivity_clause ::= on sensitivity_list
229 [$ 8.1] sensitivity_list ::= signal_name { , signal_name }
230 [$ 8] sequence_of_statements ::= { sequential_statement }
231 [$ 8] sequential_statement ::= wait_statement | assertion_statement |
report_statement |
signal_assignment_statement |
variable_assignment_statement |
procedure_call_statement | if_statement |
case_statement | loop_statement |
next_statement | exit_statement |
return_statement | null_statement |
break_statement
232 [$ 7.1] shift_expression ::= simple_expression [ shift_operator simple_expression ]
233 [$ 7.2] shift_operator ::= sll | srl | sla | sra | rol | ror
234 [$ 7.2] sign ::= + | -
235 [$ 8.4] signal_assignment_statement ::= [ label : ] target <= [ delay_mechanism ] waveform ;
236 [$ 4.3.1.2] signal_declaration ::= signal identifier_list : subtype_indication [signal_kind ] [:= expression ] ;
237 [$ 4.3.1.2] signal_kind ::= register | bus
238 [$ 5.3] signal_list ::= signal_name { , signal_name } | others | all
239 [$ 2.3.2] signature ::= [ [ type_mark { , type_mark } ] [ return type_mark ] ]
240 [$ 7.1] simple_expression ::= [ sign ] term { adding_operator term }
241 [$ 6.2] simple_name ::= identifier
242 [$ 15.1] simple_simultaneous_statement ::= [ label : ] simple_expression ==
simple_expression [ tolerance_aspect ] ;
243 [$ 15.3] simultaneous_alternative ::= when choices => simultaneous_statement_part
244 [$ 15.3] simultaneous_case_statement ::= [ case_label : ] case expression use
simultaneous_alternative
{simultaneous_alternative } end case
[case_label ] ;
245 [$ 15.2] simultaneous_if_statement ::= [ if_label : ] if condition use
simultaneous_statement_part { elsif condition
use simultaneous_statement_part } [ else
simultaneous_statement_part ] end use
[if_label ] ;
246 [$ 15.4] simultaneous_null_statement ::= [ label : ] null ;
247 [$ 15.4] simultaneous_procedural_statement ::= [ procedural_label : ] procedural [ is ]
procedural_declarative_part begin
procedural_statement_part end procedural
[procedural_label ] ;
248 [$ 15] simultaneous_statement ::= simple_simultaneous_statement |
simultaneous_if_statement |
simultaneous_case_statement |
simultaneous_procedural_statement |
simultaneous_null_statement
249 [$ 15] simultaneous_statement_part ::= { simultaneous_statement }
250 [$ 6.5] slice_name ::= prefix ( discrete_range )
251 [$ 4.3.1.6] source_aspect ::= spectrum magnitude_simple_expression , phase_simple_expression
| noise power_simple_expression
252 [$ 4.3.1.6] source_quantity_declaration ::= quantity identifier_list : subtype_indication
source_aspect ;
253 step_limit_specification ::= limit quantity_specification with real_expression ;
254 [$ 13.6] string_literal ::= " { graphic_character } "
255 [$ 4.8] subnature_declaration ::= subnature identifier is subnature_indication ;
256 [$ 4.8] subnature_indication ::= nature_mark [ index_constraint ]
[ tolerance string_expression
across string_expression through ]
257 [$ 2.2] subprogram_body ::= subprogram_specification is
122
subprogram_declarative_part begin
subprogram_statement_part end
[subprogram_kind ] [ designator ] ;
258 [$ 2.1] subprogram_declaration ::= subprogram_specification ;
259 [$ 2.2] subprogram_declarative_item ::= subprogram_declaration |
subprogram_body | type_declaration |
subtype_declaration | constant_declaration |
variable_declaration | file_declaration |
alias_declaration | attribute_declaration |
attribute_specification | use_clause |
group_template_declaration |
group_declaration
260 [$ 2.2] subprogram_declarative_part ::= { subprogram_declarative_item }
261 [$ 2.2] subprogram_kind ::= procedure | function
262 [$ 2.1] subprogram_specification ::= procedure designator [ ( formal_parameter_list ) ] |
[ pure | impure ]
function designator [ ( formal_parameter_list )]
return type_mark
263 [$ 2.2] subprogram_statement_part ::= { sequential_statement }
264 [$ 4.2] subtype_declaration ::= subtype identifier is subtype_indication ;
265 [$ 4.2] subtype_indication ::=[ resolution_function_name ] type_mark [constraint ] [tolerance_aspect]
266 [$ 6.3] suffix ::= simple_name | character_literal | operator_symbol | all
267 [$ 8.4] target ::= name | aggregate
268 [$ 7.1] term ::= factor { multiplying_operator factor }
269 [$ 4.3.1.6] terminal_aspect ::= plus_terminal_name [ to minus_terminal_name ]
270 [$ 4.3.1.5] terminal_declaration ::= terminal identifier_list : subnature_indication
271 [$ 4.3.1.6] through_aspect ::= identifier_list [tolerance_aspect] [ := expression ] through
272 [$ 8.1] timeout_clause ::= for time_expression time_or_real_expression
273 [$ 4.2] tolerance_aspect ::= tolerance string_expression
274 [$ 7.3.5] type_conversion ::= type_mark ( expression )
275 [$ 4.1] type_declaration ::= full_type_declaration | incomplete_type_declaration
276 [$ 4.1] type_definition ::= scalar_type_definition |
composite_type_definition |
access_type_definition | file_type_definition
277 [$ 4.2] type_mark ::= type_name | subtype_name
278 [$ 3.2.1] unconstrained_array_definition ::= array ( index_subtype_definition
{ , index_subtype_definition } ) of element_subtype_indication
279 [$ 3.5.2.1] unconstrained_nature_definition ::= array ( index_subtype_definition
{, index_subtype_definition } ) of subnature_indication
280 [$ 10.4] use_clause ::= use selected_name { , selected_name } ;
281 [$ 8.5] variable_assignment_statement ::= [ label : ] target := expression ;
282 [$ 4.3.1.3] variable_declaration ::= [shared] variable identifier_list : subtype_indication [ := expression ] ;
283 [$ 8.1] wait_statement ::= [ label : ] wait [ sensitivity_clause ] [condition_clause ] [ timeout_clause ] ;
284 [$ 8.4] waveform ::= waveform_element { , waveform_element } | unaffected
285 [$ 8.4.1] waveform_element ::= value_expression [ after time_expression ] |
null [ after time_expression ]
123
Les 55 attributs
La notation (xxx T ? yyy) signifie qu’on applique l’attribut sur un objet de type/famille xxx et qu’il rend
un objet yyy.
Type T ? Type :
T'base
Type T ? Value :
Type T ? Function :
Array A ? Function :
Array A ? Range :
A'range[(N)], A'reverse_range[(N)]
Array A ? Value :
A’length[(N)], A'ascending[(N)]
Signal S ? Signal : (le résultat possède les mêmes attributions qu’uin signal déclaré)
Signal S ? Quantity :
S'ramp([TR[,TF]]),
S'slew([max_rising_slope, [max_falling_slope]])
Signal S ? Fonction :
Entity E ? String :
Nature N ? Type :
N’across, N’through
Nature N ? Terminal :
N’reference
Quantité Q ? Value :
Q’tolerance
124
Quantité Q ? Quantité :
Quantité Q ? Signal :
Q’above(E)
Terminal T ? Quantité :
T’contribution, T’reference
Terminal T ? Value :
T'tolerance
125
Le contenu des paquetages standards
Les paquetages disponibles sont les suivants :
Library STD
STD.STANDARD
STD.TEXTIO
126
procedure READ(L:inout LINE; VALUE: out bit_vector; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out bit_vector);
procedure READ(L:inout LINE; VALUE: out BOOLEAN; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out character; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out character);
procedure READ(L:inout LINE; VALUE: out integer; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out integer);
procedure READ(L:inout LINE; VALUE: out real; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out real);
procedure READ(L:inout LINE; VALUE: out string; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out string);
procedure READ(L:inout LINE; VALUE: out time; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out time);
procedure WRITELINE(file f : TEXT; L : inout LINE);
procedure WRITE(L : inout LINE; VALUE : in bit;JUSTIFIED: in SIDE := right;FIELD: in WIDTH := 0);
procedure WRITE(L : inout LINE; VALUE : in bit_vector; JUSTIFIED: in SIDE := right;
FIELD: in WIDTH := 0);
procedure WRITE(L : inout LINE; VALUE : in BOOLEAN;JUSTIFIED: in SIDE := right;
FIELD: in WIDTH := 0);
procedure WRITE(L : inout LINE; VALUE : in character;JUSTIFIED: in SIDE := right;
FIELD: in WIDTH := 0);
procedure WRITE(L : inout LINE; VALUE : in integer;JUSTIFIED: in SIDE := right;
FIELD:in WIDTH := 0);
procedure WRITE(L : inout LINE; VALUE : in real;JUSTIFIED: in SIDE := right;
FIELD: in WIDTH := 0;DIGITS: in NATURAL := 0);
procedure WRITE(L : inout LINE; VALUE : in string;JUSTIFIED: in SIDE := right;
FIELD:in WIDTH := 0);
procedure WRITE(L : inout LINE; VALUE : in time;JUSTIFIED: in SIDE := right;
FIELD: in WIDTH := 0; UNIT: in TIME := ns);
127
Library IEEE
IEEE.STD_LOGIC_1164
128
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
FUNCTION Is_X ( s : std_ulogic_vector ) RETURN BOOLEAN;
FUNCTION Is_X ( s : std_logic_vector ) RETURN BOOLEAN;
FUNCTION Is_X ( s : std_ulogic ) RETURN BOOLEAN;
IEEE.STD_LOGIC_ARITH
129
FUNCTION "MOD" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "MOD" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "MOD" ( l, r : SIGNED ) RETURN SIGNED;
FUNCTION "MOD" ( l, r : UNSIGNED ) RETURN UNSIGNED;
FUNCTION "REM" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "REM" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "REM" ( l, r : SIGNED ) RETURN SIGNED;
FUNCTION "REM" ( l, r : UNSIGNED ) RETURN UNSIGNED;
FUNCTION "**" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "**" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "**" ( l, r : SIGNED ) RETURN SIGNED;
FUNCTION "**" ( l, r : UNSIGNED ) RETURN UNSIGNED;
FUNCTION "sla" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
FUNCTION "sla" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
FUNCTION "sla" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_ULOGIC_VECTOR ;
FUNCTION "sla" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_LOGIC_VECTOR ;
FUNCTION "sra" (arg1:UNSIGNED; arg2:NATURAL) RETURN UNSIGNED ;
FUNCTION "sra" (arg1:SIGNED; arg2:NATURAL) RETURN SIGNED ;
FUNCTION "sra" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN
STD_ULOGIC_VECTOR ;
FUNCTION "sra" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN
STD_LOGIC_VECTOR ;
FUNCTION "sll" (arg1:UNSIGNED; arg2:NATURAL) RETURN UNSIGNED ;
FUNCTION "sll" (arg1:SIGNED; arg2:NATURAL) RETURN SIGNED ;
FUNCTION "sll" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_ULOGIC_VECTOR ;
FUNCTION "sll" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_LOGIC_VECTOR ;
FUNCTION "srl" (arg1:UNSIGNED; arg2:NATURAL) RETURN UNSIGNED ;
FUNCTION "srl" (arg1:SIGNED; arg2:NATURAL) RETURN SIGNED ;
FUNCTION "srl" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_ULOGIC_VECTOR ;
FUNCTION "srl" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_LOGIC_VECTOR ;
FUNCTION "rol" (arg1:UNSIGNED; arg2:NATURAL) RETURN UNSIGNED ;
FUNCTION "rol" (arg1:SIGNED; arg2:NATURAL) RETURN SIGNED ;
FUNCTION "rol" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_ULOGIC_VECTOR ;
FUNCTION "rol" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_LOGIC_VECTOR ;
FUNCTION "ror" (arg1:UNSIGNED; arg2:NATURAL)
RETURN UNSIGNED ;
FUNCTION "ror" (arg1:SIGNED; arg2:NATURAL) RETURN SIGNED ;
FUNCTION "ror" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_ULOGIC_VECTOR ;
FUNCTION "ror" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL)
RETURN STD_LOGIC_VECTOR ;
FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN;
FUNCTION eq ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION eq ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION eq ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION eq ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION "=" ( l, r : UNSIGNED) RETURN BOOLEAN ;
FUNCTION "=" ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION ne ( l, r : STD_LOGIC ) RETURN BOOLEAN;
FUNCTION ne ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION ne ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION ne ( l, r : UNSIGNED ) RETURN BOOLEAN ;
130
FUNCTION ne ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION "/=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION "/=" ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN;
FUNCTION lt ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION lt ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION lt ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION lt ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION "<" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION "<" ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION gt ( l, r : STD_LOGIC ) RETURN BOOLEAN;
FUNCTION gt ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION gt ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION gt ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION gt ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION ">" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION ">" ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION le ( l, r : STD_LOGIC ) RETURN BOOLEAN;
FUNCTION le ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION le ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION le ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION le ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION "<=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION "<=" ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION ge ( l, r : STD_LOGIC ) RETURN BOOLEAN;
FUNCTION ge ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION ge ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
FUNCTION ge ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION ge ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION ">=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
FUNCTION ">=" ( l, r : SIGNED ) RETURN BOOLEAN ;
FUNCTION "and" (arg1, arg2:SIGNED) RETURN SIGNED;
FUNCTION "and" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
FUNCTION "nand" (arg1, arg2:SIGNED) RETURN SIGNED;
FUNCTION "nand" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
FUNCTION "or" (arg1, arg2:SIGNED) RETURN SIGNED;
FUNCTION "or" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
FUNCTION "nor" (arg1, arg2:SIGNED) RETURN SIGNED;
FUNCTION "nor" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
FUNCTION "xor" (arg1, arg2:SIGNED) RETURN SIGNED;
FUNCTION "xor" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
FUNCTION "not" (arg1:SIGNED) RETURN SIGNED;
FUNCTION "not" (arg1:UNSIGNED) RETURN UNSIGNED;
FUNCTION "xnor" (arg1, arg2:SIGNED) RETURN SIGNED;
FUNCTION "xnor" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
FUNCTION and_reduce(arg : STD_LOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION nand_reduce(arg : STD_LOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION or_reduce(arg : STD_LOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION nor_reduce(arg : STD_LOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION xor_reduce(arg : STD_LOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION xnor_reduce(arg : STD_LOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION and_reduce(arg : UNSIGNED) RETURN STD_LOGIC;
FUNCTION nand_reduce(arg : UNSIGNED) RETURN STD_LOGIC;
FUNCTION or_reduce(arg : UNSIGNED) RETURN STD_LOGIC;
FUNCTION nor_reduce(arg : UNSIGNED) RETURN STD_LOGIC;
FUNCTION xor_reduce(arg : UNSIGNED) RETURN STD_LOGIC;
FUNCTION xnor_reduce(arg : UNSIGNED) RETURN STD_LOGIC;
FUNCTION and_reduce(arg : SIGNED) RETURN STD_LOGIC;
FUNCTION nand_reduce(arg : SIGNED) RETURN STD_LOGIC;
FUNCTION or_reduce(arg : SIGNED) RETURN STD_LOGIC;
131
FUNCTION nor_reduce(arg : SIGNED) RETURN STD_LOGIC;
FUNCTION xor_reduce(arg : SIGNED) RETURN STD_LOGIC;
FUNCTION xnor_reduce(arg : SIGNED) RETURN STD_LOGIC;
FUNCTION and_reduce(arg : STD_ULOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION nand_reduce(arg : STD_ULOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION or_reduce(arg : STD_ULOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION nor_reduce(arg : STD_ULOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION xor_reduce(arg : STD_ULOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION xnor_reduce(arg : STD_ULOGIC_VECTOR) RETURN STD_LOGIC;
FUNCTION maximum ( arg1, arg2 : INTEGER) RETURN INTEGER;
FUNCTION minimum ( arg1, arg2 : INTEGER) RETURN INTEGER;
132
function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "mod" (L: SIGNED; R: INTEGER) return SIGNED;
function "mod" (L: INTEGER; R: SIGNED) return SIGNED;
function ">" (L, R: UNSIGNED) return BOOLEAN;
function ">" (L, R: SIGNED) return BOOLEAN;
function ">" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function ">" (L: INTEGER; R: SIGNED) return BOOLEAN;
function ">" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function ">" (L: SIGNED; R: INTEGER) return BOOLEAN;
function "<" (L, R: UNSIGNED) return BOOLEAN;
function "<" (L, R: SIGNED) return BOOLEAN;
function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "<" (L: INTEGER; R: SIGNED) return BOOLEAN;
function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function "<" (L: SIGNED; R: INTEGER) return BOOLEAN;
function "<=" (L, R: UNSIGNED) return BOOLEAN;
function "<=" (L, R: SIGNED) return BOOLEAN;
function "<=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "<=" (L: INTEGER; R: SIGNED) return BOOLEAN;
function "<=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function "<=" (L: SIGNED; R: INTEGER) return BOOLEAN;
function ">=" (L, R: UNSIGNED) return BOOLEAN;
function ">=" (L, R: SIGNED) return BOOLEAN;
function ">=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function ">=" (L: INTEGER; R: SIGNED) return BOOLEAN;
function ">=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function ">=" (L: SIGNED; R: INTEGER) return BOOLEAN;
function "=" (L, R: UNSIGNED) return BOOLEAN;
function "=" (L, R: SIGNED) return BOOLEAN;
function "=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "=" (L: INTEGER; R: SIGNED) return BOOLEAN;
function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function "=" (L: SIGNED; R: INTEGER) return BOOLEAN;
function "/=" (L, R: UNSIGNED) return BOOLEAN;
function "/=" (L, R: SIGNED) return BOOLEAN;
function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN;
function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN;
function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
function SHIFT_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
function SHIFT_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
function ROTATE_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
function ROTATE_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED;
function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED;
function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED;
function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED;
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
function TO_INTEGER (ARG: SIGNED) return INTEGER;
133
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
function "not" (L: UNSIGNED) return UNSIGNED;
function "and" (L, R: UNSIGNED) return UNSIGNED;
function "or" (L, R: UNSIGNED) return UNSIGNED;
function "nand" (L, R: UNSIGNED) return UNSIGNED;
function "nor" (L, R: UNSIGNED) return UNSIGNED;
function "xor" (L, R: UNSIGNED) return UNSIGNED;
function "xnor" (L, R: UNSIGNED) return UNSIGNED;
function "not" (L: SIGNED) return SIGNED;
function "and" (L, R: SIGNED) return SIGNED;
function "or" (L, R: SIGNED) return SIGNED;
function "nand" (L, R: SIGNED) return SIGNED;
function "nor" (L, R: SIGNED) return SIGNED;
function "xor" (L, R: SIGNED) return SIGNED;
function "xnor" (L, R: SIGNED) return SIGNED;
function RISING_EDGE (signal S: BIT) return BOOLEAN;
function FALLING_EDGE (signal S: BIT) return BOOLEAN;
IEEE.MATH_REAL
134
function ATAN (X : real) return real;
function ATAN2 (X : real; Y : real) return real;
function SINH (X : real) return real;
function COSH (X : real) return real;
function TANH (X : real) return real;
function ASINH (X : real) return real;
function ACOSH (X : real) return real;
function ATANH (X : real) return real;
Library DISCIPLINES
DISCIPLINES.PHYSICAL_CONSTANTS
DISCIPLINES.ELECTROMAGNETIC_SYSTEM
DISCIPLINES.THERMAL_SYSTEM
DISCIPLINES.KINEMATIC_SYSTEM
135
DISCIPLINES.ROTATIONAL_SYSTEM
DISCIPLINES.FLUIDIC_SYSTEM
136
Le corps du paquetage du problème des N-CORPS
137
-- Opérations sur les vector_3D
end;
function "+"(a:Vector_3D,b:Vector_3D) return Vector_3D is
variable loc_v:Vector_3D(b'range);
begin
loc_v.X := a.X + b.X;
loc_v.Y := a.Y + b.Y;
loc_v.Z := a.Z + b.Z;
return loc_v;
end;
138
pos_grav_T := pos_grav_T + Mass(i) * loc(i);
Mass_amas(i) = M_T - Mass(i);
for
end i=Mass'range
loop loop
return F_loc;
end;
139