Vous êtes sur la page 1sur 139

VHDL-AMS

Un langage pour l'électronique du futur


Norme IEEE 1076-1999

Yannick HERVE

Docteur en informatique et électronique,


Agrégé de génie électrique,
Ancien élève de l'Ecole Normale Supérieure,
Maître de Conférences à l'Université Louis Pasteur de Strasbourg
herve@erm1.u-strasbg.fr
Présentation du plan de l’ouvrage et des choix éditoriaux

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.

Coordonnées de l’association BEAMS :


Si vous voulez plus de précisions sur l’utilisation des techniques de haut niveau dans la conception de systèmes
industriels vous pouvez prendre contact avec l’association universitaire BEAMS (BEhAvioral Modelisation of
Systems) dont l’auteur est membre fondateur. Ses membres sont disposés à effectuer des formations, des
démonstrations et à intervenir dans les entreprises qui se posent des questions à ce sujet. (beams@ixl.u-
bordeaux.fr )

BEAMS, Laboratoire de Micro électronique IXL,


Université Bordeaux I,
351, Cours de la Libération,
33405 Talence Cedex.

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.

Petite digression : Peut-on dire « Electronique numérique » / « Electronique analogique » ?

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.

1.2 L’industrie électronique


1.2.1 Le processus de conception

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é.

MARKETING / R&D / PRODUCTION

Idées nouveaux produits


Première sélection : quelques idées
Concept précisé (tests) et Evaluation marché potentiel (segments/cibles)
Etudes de faisabilité (temps/compétences/outil industriel)
Orientations sur le marketing associé (image/volume/…) Comptes prévisionnels
Etudes de marché
Etudes techniques
Etudes des coûts de production et de distribution
Comptes d’exploitation prévisionnels / Aspects juridiques / normatifs
Test sur prototypes /présérie
Mise au point produit final
Gamme / Prix / Distribution / Communication
Plan de lancement : distribution / logistiques
[Marché test]
Calendrier production / Budgets / Formation force de vente
Plan d’action commerciale / Lancement
Spécifications générales (marketing)
Etablissement d’un cahier des charges précis
Validation client (interne ou externe)
Découpe architecturale (métiers)
Définition sous-projets et plannings
Sous projets : Phase de conception (référencement achats)
Réception et validation sous-projets
Intégration et tests (re-design éventuel)
Etudes d’industrialisation
Développement ou adaptation de l’outil industriel
Présérie / Analyse / réglages
Achats / sous traitants / tests de production
Lancement fabrication cadence réduite
Lancement pleine charge
Retour client / Maintenance outil

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 :

Maîtrise des temps, des coûts par les délais


Adéquation de description avec les partenaires et les sous-traitants
Produire juste par construction (plus de prototype / pas d’itération)
Fournir les outils pour l ’ingénierie simultanée
Gérer les immenses volumes de données techniques
Le volume est multiplié par 10 à chaque étape
Réutilisabilité
Intellectual Property : acheter ailleurs ce qui coûte moins cher qu’à développer
Testabilité
Analyses poussées (stress, fiabilité, thermique, …)
Production automatique d’outils (tests, prog machines, ...)

1.2.2 Le flot de conception CI [CAE]

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)

1.2.3 Méthodologie générale : les grandes tendances

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.

[CF] Cahier des charges formel et simulable

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.

[TD] Conception descendante ou top-down

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).

[MA] Multi abstraction

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é !

[SE] Simulation environnementale

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].

[SH] Support de la hiérarchie de conception

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]

[SL] Synthèse logique et description de haut niveau

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.

[PF] Preuve formelle

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.

[CM] Conception mixte

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 faut pouvoir simuler conjointement le logiciel et le matériel le supportant.

[GD] Gestion de données et de documentation technique

L’environnement de conception doit assurer la gestion de la documentation technique et administrative associée


au projet. Il doit assurer l’unicité des documents, la gestion des versions et la sécurité des sauvegardes.
L’assurance qualité, et la certification associée, peut alors se baser sur ces possibilités pour progresser.

[VT] Vérification et tests

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.

Petite digression : Vérification des systèmes

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.

[OU] Outil unique

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.

[IC] Ingénierie concurrente

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.

1.3 Les nouveaux besoins

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.

1.4 L'importance d'un standard

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.

Petite digression : Normalisation IEEE

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.

Petite digression : Les groupes de pression en normalisation

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.

2.2 Qu'est ce qu'un Langage de Description de Matériel (ou HDL) ?

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.

2.3 Les limitations des outils existants et propriétaires

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.

2.4 Quelques outils en décembre 2000

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)

2.5 VHDL-AMS : Les possibilités et les limitations

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.

2.6 VHDL-AMS : Avantages et inconvénients

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.

Procédure itérative : (emploi d’une liste d ’événement (EL) et de signaux datés)


Mise à jour de l ’EL classée par date
Extraction des signaux ayant le t mini
Avancée de l’horloge de simulation
Réveil et simulation des process dépendants
Production de nouveaux événements
Production d ’un LSP (Logic Simulation Point)

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)

Procédure itérative : (calcul matriciel d ’ordre élevé !)


Mise en équation : jeu d’équations différentielles non linéaires sous forme matricielle
Choix du nouveau t (assisté par la valeur du jacobien)
Discrêtisation par application d’une méthode d’intégration : jeu d’équations aux différences NL
x(t+d) = fNL (x(t),x ’(t),p(t)) avec x(t) le vecteur des inconnues et p(t) les excitations
Linéarisation (Newton ou équivalent) : jeu d’équations aux différences linéaires
Résolution (gauss seidel ou équivalent)
Vérification de la convergence
Si convergence : Production d ’un ASP
Sinon changer t et recommencer

Petite digression : les analyses classiques de SPICE

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.

VHDL-AMS n’est bien entendu valablement utilisé qu’en tenant compte de


toutes ses possibilités. Les utilisations opérationnelles du langage seront
présentées dans le chapitre 5.

Les exemples donnés sont de deux types :


- Ceux répondant à la norme mais ne pouvant être compilés à cause des
manques de couverture des outils actuels
- Les exemples n’utilisant pas forcément toutes les possibilités de la norme
mais pouvant être exploités sur les outils existants.

Tous les exemples sont disponibles dans le CD-ROM.


Les outils utilisés représentent l’état de l’art en décembre 2000. Les évolutions
dans ce domaine sont rapides et les outils disponibles à la date de lecture de cet
ouvrage ne peuvent qu’être plus performants. (couverture de la grammaire
notamment).
Un langage est une construction complexe définie par un ensemble de mots-clés
et une grammaire. Son utilisation et ses limitations sont définies dans le manuel
de référence du langage (le LRM de la norme) [LRM] et une fois la première
approche réussie grâce à cet ouvrage, ce sera le seul document contractuel, la
seule source de précisions officielles. Le lecteur se reportera utilement à ce
document (épais et très indigeste) pour un complément d’informations.

On trouvera, sur le CD-ROM et en annexe, une grammaire complète et une liste


des fonctions normalisées. Les fichiers au format HTML (une version
interactive) faciliteront la prise en main du langage

16
Chapitre 3 : Présentation générale du langage

3.1 Structure d'un modèle

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.

Ouverture de bibliothèques (LIBRARY)


Déclarations d’utilisation du contenu des bibliothèques ouvertes (USE)
Spécification d’entité (ENTITY)
Définition des paramètres génériques (GENERIC)
Définition des ports de connexion possibles (PORT)
Signal (in/out) support des informations à événements discrets
Quantity (in/out) support des informations signal-flow
Terminal support des connexions « kirchoff »
Corps de l’entité
Ensemble d’instructions passives

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;

ARCHITECTURE archi1 OF exemple IS


TYPE list_ex IS (el1,el2,el2);
CONSTANT cst1 : list_ex, k:REAL;
SIGNAL sig1 : BIT, sig2 :INTEGER, sig3 : REAL;
QUANTITY vbias ACROSS ibias THROUGH vp TO vm;
QUANTITY free_quant : REAL;
BEGIN
u1:ENTITY model_externe(archi_du_modele) -- Instanciation de composant
GENERIC MAP(100.0e3,5.0) PORT MAP(vp,vm,sig1);

free_quant == 3.0*sinus( k * now ); -- Instruction simultanée


ibias == free_quant’dot;

sig_ext <= ‘0’ after tplh ; -- Instruction concurrente

p1:PROCESS -- Process (inst.concurrente)


variable x : real := 5.5;
BEGIN
wait on sig3 until sig2 > 3 for 25 ms;
x := 2*x ;
sig_ext <= sig3 after 1 ms;
END PROCESS p1;

END ARCHITECTURE archi1;


Fig. 3.1 : Exemple purement illustratif de modèle VHDL-AMS

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 hiérarchie de conception permet de définir un testbench constitué d’instructions concurrentes ou simultanées


et d’instanciation de composants. Cette définition est récursive puisque les composants sont eux-mêmes définis
par les mêmes constructions. Les constituants terminaux de la hiérarchie ne peuvent être définis que par des
instructions « exécutables », c’est à dire des instructions simultanées et/ou concurrentes.

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.

3.3 Structuration en bibliothèque


Les outils de conception basés sur VHDL-AMS sont organisés autour de bibliothèques. La norme définit que la
bibliothèque de travail est nommée WORK. Ce nom est logique et le nom physique dépend de l’organisation des
informations prévue par les concepteurs de l’outil sur la machine et son système d’exploitation. Les autres
bibliothèques disponibles sont appelées bibliothèques de ressources.

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)

3.4 Identificateurs et littéraux

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.

Quatre entiers 1345, 1_345, 1e6, 1E6


Trois réels 1345.3, 1_345.1, 1.0e2

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).

2#01101# est un entier qui vaut 13


7#03630# un entier exprimé en base 7
16#FF3A# idem en base 16
2#01101.0# est un réel qui vaut 13.0
16#FF.4A#e12 un autre réel en notation scientifique

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’)

3.5 Typage fort

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).

Il existe aussi des pointeurs (access) et des fichiers (file).

L’utilisateur peut définir des types et des sous types à sa convenance.

3.5.1 Déclarations des scalaires

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.

Le type suivant est un énuméré de trois valeurs :

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.

Entiers : TYPE index IS RANGE -3 TO 27 ;


TYPE rev_index IS RANGE 27 DOWNTO -3 ;
Flottants : TYPE ex_real IS RANGE -3.0 TO 27.0 ;

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é.

Physique : TYPE distance IS RANGE 0 TO 1e16


UNITS A ;
nm = 10 A ;
mil = 254_000 A ;
inch = 1_000 mil ;
ft = 12 inch ;
yd = 3 ft ;
cm = 10e7 nm ;
END UNITS ;

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 :

35 yd + 547 cm + 17 inch sera calculée en Angströms


(35 yd + 547 cm)/mil sera calculée en mils.
(103 nm) / nm est un entier
I * nm transforme un entier I en nm

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.

3.5.2 Déclaration des composites

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.

TYPE int_vec IS ARRAY(3 to 45) of integer ;

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

TYPE real_vec IS ARRAY(natural range <>) of real ;

Le type suivant est un tableau d’indice énuméré qui contient des entiers.

TYPE enum_vec IS ARRAY(enum_type) of integer ;

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.

TYPE enum_vec IS ARRAY(natural range <>, enum_type) of real_vec ;

B/ Enregistrements

Ce type permet de rassembler plusieurs valeurs de types différents appelées champs.


On pourra accéder aux valeurs par notation pointée. Ces types ne peuvent contenir des fichiers.

TYPE record_ex IS RECORD


champ_1 : bit ;
champ_2 : real ;
autre_champ : enum_type ;
END RECORD;

Si A est de type record_ex, on accède aux champs par :

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, ….

3.5.3 Déclarations fichiers et pointeurs

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).

La déclaration type fichier a la forme suivante :

TYPE file_type IS FILE OF string ;

Les fonctions de manipulation de l’information sont définies dans le paquetage STANDARD


(read / write /file_open / endfile / file_close)

La définition des pointeurs est de la forme

TYPE index IS natural RANGE 0 TO 15 ;


TYPE index_ptr IS ACCESS index ;

Déclaration d’un nouveau pointeur

NEW index_ptr ;

Si IPtr est de type index_ptr alors IPtr.all a la valeur de l’objet pointé.

3.5.4 Types prédéfinis par la norme

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.

integer TYPE integer IS RANGE integer’low to integer’high;


real TYPE real IS RANGE real’low to real’high ;

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 ;

Petite digression : le type IEEE 1164

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 :

SUBTYPE identifier IS [resolution_fonction_name] type [contraintes] [TOLERANCE string] ;

Par exemple :

SUBTYPE signal_value IS real RANGE -15.0 to 15.0 ;

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 prédéfinis par la norme sont les suivants :

natural : SUBTYPE natural IS integer RANGE 0 to integer’high;


positive : SUBTYPE positive IS integer RANGE 1 to integer’high;

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) ;

3.5.6 Initialisation des objets

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 :

signal A : bit ; -- A vaut ‘0’


signal A : bit := ‘1’; -- A vaut ‘1’
variable B : boolean ; -- B vaut false
quantity Q : real ; -- Q vaut 0.0

Un type peut être incomplètement défini, le compilateur attendra le dernier moment pour reporter l’erreur.

TYPE cell ; -- type incomplètement défini


TYPE link IS ACCESS cell ;
TYPE cell is record -- définitions récursive de type
value : index ;
succ : link ;
END RECORD ;

Petite digression : le coût des erreurs

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.

3.5.7 Agrégat s, Expressions qualifiées, Conversion de types

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) ;

ou si S1 est un vecteur de « bits :

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 :

Qualified_expression : := type_mark’(expression) | type_mark’aggregate

Par exemple : S <= bit_vector’« 00110 » ;

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)

Avec R une variable de type REAL R := real(3) ;


Avec I une variable de type INTEGER I := integer(3.0) ;
R := real(I) ;

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.

On remarquera la différence minime (’) entre l’expression qualifiée et la conversion de type.

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.

3.6 Les 6 classes d’objets

Les objets permettent de transporter l’information dans les modèles. Il existe 6 classes d’objets :

CONSTANT valeur fixe connue à l’élaboration


VARIABLE connue dans le monde séquentiel, dynamique
modifiée par affectation de variable ( := )
SIGNAL connu dans le monde concurrent, statique
permet de transporter l’information à temps discret
modifié par affectation de signal ( <= )
TERMINAL permet de définir les connexions à temps continu
QUANTITY de branch, libre (branch/free) ou source
permet de transporter l’information à temps continu
participe aux instructions simultanées ( == )
FILE objet permettant d’effectuer les entrées sorties «informatiques »

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 :

CONSTANT pi : real := 3.141592 ;


CONSTANT clock_period : time := 20 ns ;

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.

CONSTANT cst_val : integer := 40 * N ;

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 :

CONSTANT cst_val : integer ;

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 :

VARIABLE phase : real := 124.0 ;


VARIABLE clock_period : time := 20 ns ;
VARIABLE var1: integer := function_d_init(…) ;

L’affectation et la modification des variables se fait par l’intermédiaire de :=

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.

SHARED VARIABLE phase : real := 124.0 ;

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.

Petite digression : variables paratagées et déterminisme

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 :

P1 lit A, P1 écrit A, P2 lit A puis P2 écrit A : A = 11


P2 lit A, P2 écrit A, P1 lit A puis P1 écrit A : A = 25
P1 lit A, P2 lit A puis P1 écrit A puis P2 écrit A : A=5
P1 lit A, P2 lit A puis P2 écrit A puis P1 écrit A : A=9
….
Le fonctionnement est passablement erratique. Comment prévoir quoi que ce soit s’il y a plusieurs centaines de
processus et plusieurs dizaines de variables partagées ? On est en présence d’un fonctionnement non-
déterministe, ce qui n’est vraisemblablement pas l’objectif d’une modélisation de matériel en vue de sa
fabrication !

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).

signal_declaration ::= SIGNAL signal_name : [fonc_resolution] type


[contraintes][REGISTER|BUS][:= init_value];

SIGNAL Inport,outport : bit_vector(1 to 7) ;


SIGNAL S : integer ;

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

Inport <= Outport ;


S <= 3 after 15 ns;

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 :

terminal_declaration ::= terminal identifier_list : subnature_indication ;

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

TERMINAL vp,vm : electrical ;

Il est possible de définir des vecteurs ou des record de nature.

NATURE elec_vec IS ARRAY(natural RANGE <>) of electrical ;

NATURE elec_bus IS RECORD


Strobe : electrical ;
Data : elec_vec(7 downto 0) ;
END RECORD ;

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.

Une quantité libre (Free Quantity) n ’est pas attachée à un TERMINAL.

QUANTITY Q : real := expression_init;

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.

Une quantité de branche (Branch Quantity) est associée à un terminal

QUANTITY [across_aspect] [through_aspect] terminal_aspect ;

QUANTITY V12 across I1 through t1 to t2 ; définit la tension et le courant entre T1 et T2


QUANTITY V1,V2 across t1; définit deux alias pour la tension entre T1 et la référence
QUANTITY I1,I2 through t1; définit deux branches entre T1 et la référence

Exemples d’association de quantités et de terminaux :

Soient les déclarations :


terminal t1,t2 : electrical ;
terminal t3, t4 : electrical_vector (1 to 5);

Alors quantity v12 across i1, i2 through t1 to t2 ;


définit une tension et deux courants

Alors quantity v31 across i3 through t3 to t2 ;


définit 5 tensions V31(i)avec un point commun t2
et 5 courants i3(i)convergents sur t2

Alors quantity v24 across i4 through t2 to t4 ;


définit 5 tensions v24(i) avec un point commun t2
et 5 courants i4(i) divergents depuis t2

Alors quantity v34 across i5 through t3 to t4 ;


définit 5 tensions v34(i) et 5 courants i5(i)

Il existe aussi des quantités implicites qui sont créées par l’environnement sans déclaration préalable :

Si on a QUANTITY Q : real := expression;


Alors Q’dot (la dérivée) et Q’integ (l’intégrale depuis 0 jusqu’au temps courant)
existent toujours et sont créées si besoin

Pour QUANTITY QV : real_vector (3 downto 0) ;


Q’dot, Q’integ sont valides et représentent un vecteur de dérivés et d’intégrales.

3.7 Sémantique de connexion

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.

GENERIC : constantes passées à l ’élaboration (et valeurs par défaut)


PORTS : classe, type et mode des connexions (et éventuellement valeurs par défaut)

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 différents comportements possibles (port par port) sont :

event driven : port de classe signal


signal flow : port quantity ou terminal à une seule quantité
conservatif : port terminal et deux quantités définies

3.7.1 Connexion de type « event driven »

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.

Avec : ENTITY source IS


GENERIC ( k : integer := 3) ;
PORT (SIGNAL a : in real; b : out real);
-- a et b sont les ports formels
END;
ARCHITECTURE pulse OF sources IS
BEGIN

END;

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 »

3.7.2 Connexions de type « signal flow »

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.

Avec : ENTITY block1 IS


PORT (QUANTITY a : in real; b : out real);
END;

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 »

3.7.3 Connexions de type conservatif

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

Petite digression : Pourquoi les terminaux n’ont-ils pas de mode ?

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.

3.7.4 Connexions hybrides


Il est possible de définir des entités ayant tous les aspects définis ci-dessus. Chaque classe de port ne pourra être
connectée qu’avec les ports compatibles mais la cohabitation doit être prise en charge par le
compilateur/simulateur. La description suivante est donc possible :

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

relationnels : = , /= , < , <= , > , >=


s ’appliquent à tout sauf fichiers, résultat de type BOOLEAN

addition : +, -, &
& : concaténation sur type STRING

signe : +, -

multiplication : *, /, mod, rem


mod = modulo
rem = reminder

divers : **, abs, not

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.

3.9 Instructions du langage

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.

3.9.1 Instructions séquentielles

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 :

Avec : VARIABLE V : real ;


VARIABLE T1,T2 : real_vector(1 to 12) ;
VARIABLE T2 : real_ vector(1 to 5) ;
On a : V := f (Variable|Signal|Q uantité) fonction appliquée à la valeur des objets
T1 := T2;
T1(1 to 5) := T3 ;
T3 := (1.0, 2, 2.3 , others => 0.0) ;

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.

La structure générale d’une affectation de signal est la suivante :

[label :] target <= [transport | [reject time ] inertial] waveform ;

32
avec : target ::= name | aggregate
avec : waveform ::= wf_element {,wf_element} | unaffected
avec : wf_element : := value_expression [after time_expression]

Dans sa forme la plus simple l’affectation s’écrit, par exemp le :

S <= ’0’ after 3 ns; -- inertiel par défaut

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’.

Notion de transaction et d’événement, si S vaut x et y différent de x, à To:


alors S <= y after 3 ns; provoque un événement (event)
mais S <= x after 3 ns; provoque une transaction sans événement

Notion de pilote (driver) :


S <= x after 5 ns; ne modifie pas la valeur de S mais range (x , 5 ns) dans le pilote du signal
S sera éventuellement modifiée quand l’horloge avancera à to+ 5 ns

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à.

lab:(S1,S2)<= (’0’,’1’) after 3 ns, (’1’, ’0’) after 10 ns;

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 :

lab1: Cible <= Source;

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 :

lab1: Cible <= valeur after Td;

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 :

(To’, x) est postérieur à (To, y) si To’ est supérieur à To (quelquesoient x et y)


et (To, x) est postérieur à (To,y) si x > y.

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.

Transport : target <= transport waveform ;


Toutes les transactions non abandonnées seront acceptées dans le driver.

Filtrage par Inertie implicite: target <= inertial valeur after Td ;


C’est le mécanisme qui était défini dans VHDL’87. Les impulsions contenues dans le pilote qui
présentent une largeur inférieure ou égale à Td (celui du premier élément d’onde) sont filtrées. Ce
mécanisme qui voulait modéliser simplement l’inertie des systèmes numériques présente des
incohérences graves ; On relie ici le retard à la bande passante alors qu’aucune raison physique ne
permet de le faire (exemple : Une télévision de standard SECAM repose sur une ligne à retard (à
ultrasons) de 64 microsecondes et doit passer des signaux de 13,5MHz ; comment relier le retard et la
bande passante ?) Il faut éviter d’utiliser ce mécanisme difficile à justifier. C’est malheureusement le
mode par défaut pour garder la compatibilité avec les anciennes versions.

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).

Exemple : Un signal entier a le driver suivant (value - time stamp)

To : 3 / 5 - 10 ns / 1 - 12 ns / 0 - 15 ns

Les résultats des affectations suivantes :

S <= transport 1 after 13 ns, 5 after 15 ns, 4 after 22 ns ;


Résultat : To : 3 / 5 - 10 ns / 1 - 12 ns / 5 - 15 ns / 4 - 22 ns (le 1 – 13 ns : une transaction abandonnée)

S <= reject 2 ns inertial 1 after 13 ns, 5 after 15 ns, 4 after 22 ns ;


Résultat : To : 3 / 5 - 10 ns / 4 - 22 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 :

wait [on signal_list] [until bool_cond] [for time] ;

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.

Les formes simplifiées suivantes sont courantes :

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;

Petite digression : Temps de simulation ou temps d’exécution

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.

D/ Exécution conditionnelle ou sélective

VHDL-AMS propose deux mécanismes d’exécution conditionnelle ou sélective dont la syntaxe est explicite :

[label:]if cond_bool then


{séquence instructions séquentielles}
[elsif cond2 then
{séquence instructions séquentielles}]
[else
{séquence instructions séquentielles}]
end if ;

[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

L’exécution itérative peut se mettre sous les formes suivantes :

[label:][schéma d ’itération] loop


{séquence instructions séquentielles}
end loop [label] ;

Avec les mécanismes d’itérations suivants :

Boucle infine : loop


N :=N+1;
end loop;

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.

Conditionnelle : [label :] while conditions loop


{séqu. Instr. Séqu.}
[[exit_label :] exit [loop_label] when cond_bool ;]
end loop ;

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).

for i in A’range loop


{séqu. Instr. Séqu.}
end loop ;

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 :

[label :] assert cond_bool [report string_expression] [severity note|warning|error|failure] ;

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 :

assert teff < tsetup report «Set up violé» severity error ;

La forme simplifiée permet d’omettre la condition pour forcer la rapport à la console :

[lab:]report expr [severity note|warning|error|failure] ;

3.9.2 Instructions concurrentes


Les instructions concurrentes servent à traiter l’information à temps discret. Elles sont éventuellement évaluées
à chaque point de simulation logique en fonction de leur sensibilité à l’événement courant.

A/ Process (instruction concurrente utilisateur)

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 :

[label :][postponed]process -- postponed vu plus tard au 4.8


{zone de déclaration / pas de signaux}
begin
{sequ. Instr. Sequ.}
end [postponed] process [label] ;

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.

[label :] Process(signal_liste) -- liste de sensibilité (PLUS DE WAIT POSSIBLE)


{zone de déclaration}
begin
{sequ. Instr. Sequ. sans wait}
end process [label] ;

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 ;

Avec : input1 (in) et loc_sign (signal local) de type bit


sortie (out) de type integer

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

Notion de processus équivalent d’une instruction concurrente

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.

La forme simple de l’affectation concurrente s’écrit :

[label:] nom_ou_agregat <= [options] waveform ;

avec : options ::= [guarded] [transport | [reject time ] inertial]

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.

La forme conditionnelle s’écrit :

[label:] nom_ou_agregat<=[options] waveform1 when cond1 else


waveform2 when cond2 else
...
waveformN when condN ;

et a le processus équivalent suivant :

[label :] process (signaux dans waveformx, condx)


begin
if cond1 then
nom_ou_agregat <= [options] waveform1 ;
elsif cond2 then

elsif condN then
nom_ou_agregat <= [options] waveformN ;
end if ;
end process;

et la forme sélective s’écrit :

[label:] With expression select


nom_ou_agregat <= [options] waveform1 when list1,
...
waveformN when listN ;

avec le processus équivalent :

[label :] process (signaux dans waveformx, listx)


begin
case expression is
when list1 => nom_ou_agregat <= [options] waveform1 ;

when listN => nom_ou_agregat <= [options] waveformN ;
end case ;
end process;

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.

[lab:] [postponed]assert cond_bool [report expression] [severity note|warning|error|failure] ;

Process équivalent de cette instruction :

[lab:] [postponed] Process (signaux_de la conditions)


begin
assert cond_bool [report expression] [severity note|warning|error|failure] ;
end process [lab] ;

3.9.3 Instructions simultanées


Les instructions simultanées servent à traiter l’information à temps continu. Elles doivent être évaluées à chaque
point de simulation temporelle (ASP).

A/ Instruction simultanée simple

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.

[label :] [pure | impure] f == g [TOLERANCE string];

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 :

Q**2 + Y ’dot == sqr(Y) - Q ’integ ;


C*U == Q ;
Q == I’integ;

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

B/ Instruction simultanée conditionnelle

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) ;

C/ Instruction simultanée sélective

La forme sélective de l’instruction est la suivante :

label : CASE expr USE


WHEN value1 => {instruction(s) simultanée(s)}
WHEN value2 => {instruction(s) simultanée(s)}

END CASE label

D/ Procedural

Le PROCEDURAL permet de fabriquer un « Simultaneous Statement » à partir d’actions séquentielles. Toutes


les instructions séquentielles sont disponibles à l’exception du WAIT, du break et de l’affectation de signal. La
zone de déclaration est réévaluée à chaque ASP. Dans un PROCEDURAL les quantités sont traitées comme des
variables et le signe de l’affectation est := .

[label :] PROCEDURAL [IS]


{declaration_part}
BEGIN
{sequential_statement}
END PROCEDURAL [label]

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.

3.9.4 Instanciation de composants

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 :

label : entity nom_du_compo(archi_compo)


[generic map (formal => actual)]
[port map(formal => actual)];

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

Avec ce modèle disponible dans work :


entity nandg is
generic (tp : time := 1 ns);
port (in1,in2 : bit ; outp : out bit);
end entity;

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.

3.10 Notion d'attributs prédéfinis

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.

Array ? range : A’range


Rend la description d’indice : avec VARIABLE A :bit_vector(3 to 7), A’range rend 3 to 7
Array ? value : A’length
Rend la taille d’un tableau : avec VARIABLE A :bit_vector(3 to 7), A’length rend 5
Signal ? signal : S’delayed(T)
Rend un signal décalé de T
Signal ? signal : S’stable(T)
Rend un signal vrai si S est stable depuis au moins T
Signal ? signal : S’quiet(T)
Rend un signal vrai si la dernière transaction sur S est datée de plus de T
Signal ? fonction : S’event
Rend un booléen : vrai si il a eu un événement sur S dans ce cycle
Signal ? fonction : S’last_event
Rend le temps depuis lequel il y eu un événement sur S
Signal ? fonction : S’last_value
Rend la dernière valeur (précédente) de S
Quantité ? quantité : Q’dot
Rend la derivée de Q
Quantité ? quantité : Q’integ,
Rend l’intégrale depuis t = 0 jusqu’au temps courant de Q
Quantité ? signal : Q’above(E)
Rend un signal qui est vrai si Q est au-dessus de E, faux sinon
Nature ? terminal : N’reference
Rend le terminal de référence de la nature N
Nature ? type : N’across
Rend le type ACROSS de la nature N
Nature ? type : N’through
Rend le type THROUGH de la nature N
Terminal ? quantité : T’contribution
Rend la valeur de la contribution (THROUGH) du terminal T dans l’équation de nœud
Terminal ? quantité : T’reference
Rend la quantité ACROSS définie entre T et la référence

3.11 Synchronisation des noyaux

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.

Break on S; -- version simple

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) ;

-- l’analogique pilote le numérique


architecture ideal of comparator is
quantity vin across vp to ref;
begin
dout <= vin’above(seuil);
end architecture ideal ;

-- le numérique pilote l’analogique


architecture ideal of ADC is
quantity Vout across Iout through tout to ref;
begin
Break on Sin ;
Vout == Sin ;
end architecture ideal ;
Fig 3.11-A : Exemple de synchronisation des noyaux

3.12 Critère de solvabilité

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 :

Le nombre d’équations simultanées


doit être égal au nombre de quantités THROUGH
augmenté du nombre de quantités FREE
et du nombre de quantité d’interface en mode OUT.

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.

-- Générateur de tension parfait


entity Vdc is
generic (dc: REAL);
port (terminal p, m: electrical);
end entity Vdc;

architecture Bad of Vdc is -- NE COMPILE PAS


quantity v across p to m; -- NE COMPILE PAS
begin -- NE COMPILE PAS
v == 5.0; -- NE COMPILE PAS
end architecture Bad; -- NE COMPILE PAS

architecture Good of Vdc is -- Compile


quantity v across i through p to m; -- i ne sert qu’au critêre
begin
v == 5.0;

43
end architecture Good;
Fig 3.12 : Exemple pour le critêre de solvabilité

3.13 Zones de déclaration et de visibilité des objets

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)

Constantes, Signaux, Quantités, Procédures, Types et sous-types, Variables partagées,


Composants (4.12), Terminaux

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;).

3.14 Premiers exemples

3.14.1 Porte NAND

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;

3.14.3 Résistance, Condensateur, Inductance

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;

3.14.4 RLC série, RLC parallèle

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;

3.14.6 Diode paramétrée [DAC]

La diode est construite sur les équations suivantes :

I d ? I s .(e (vd ? rs.Id )/(n.vt) ? 1)

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;

ARCHITECTURE level0 OF diode IS


quantity Vd across id,ic through anode to cathode;
quantity qc : charge;
constant vt : real := 0.0258;
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);
END ARCHITECTURE level0;

3.14.7 Diode paramétrée : modèle électrothermique [DAC]

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;

ARCHITECTURE level0 OF diodth IS


quantity Vd across id,ic through anode to cathode;
quantity temp across power through thermal_ref to junction;
quantity qc : charge;
quantity vt : voltage;

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 :

Le reste des instructions :


Alias, attribute, block, disconnect, function, generate, group, procedure, component.

Précisions sur les instructions :


Postponed, guarded, buffer, bus, pure, impure, register, return, tolerance, limit, noise, spectrum.

Autres unités de conception :


Package, (package)body, configuration.

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.

4.2 Alias et attribut utilisateur

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.

ALIAS nouveau_nom : type_ou_subtype IS nom_de_lobjet ;

exemple : variable s_m:bit_vector(7 downto 0);


alias sign : bit is s_m(7);
alias module : bit_vector(0 to 6) is s_m(6 downto 0);

alias STD_BIT is STD.STANDARD.BIT ;

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.

attribute num_pin, valeur : integer -- déclaration


attribute num_pin of vcc : signal is 14; -- spécification
attribute num_pin of others : signal is 0;
attribute valeur of all:entity is 14;

Alors : vcc’num_pin vaut 14


x’num_pin vaut 0 si x est diférent de vcc

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).

Attribute Mapping of JMP [return OpCod]:literal « 001 » ;


Alias GOTO IS JMP[return OpCod];

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 structure de groupe :

group pin2pin is (signal,signal) ; -- deux signaux


group resource is (label <>) ; -- ensemble de label
group diff_c is (group <>) ; -- groupe de groupe

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.

label: block [condition de guard] [IS] -- condition booléenne


[en_tête généricité et ports]
[déclarations locales/ sauf variables]
begin
{instructions concurrentes ou simultanées}
end block [label];

block1: block clock ’event and clk=’1’ -- condition booléenne


begin
a <= guarded b after 3 ns ;
c <= guarded d;
end block block1;

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.

label : if cond_bool generate


{instr. Concurrentes/simultanées/instanciation}
end generate [label] ;

label : for identif in intervalle generate


{instr. Concurrentes/simultanées/instanciation}
end generate [label] ;

Exemple d’un registre à décalage N bits :

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;

architecture structural of adderN is


component adder
port (a,b,cin : in bit; sum, cout : out bit);
end component;
signal carry : std_logic_vector(0 to N);
begin
carry(0) <= cin;
gen: for I in 1 to N generate
add: adder port map(a(I),b(I),carry(I-1),sum(I),carry(I));
end generate;
end structural;
Fig 4.5-B : Instanciation de N additionneurs (N inconnu à la compilation)

4.6 Sous-pogrammes : Fonction et procedure

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.

déclaration ::= procedure proc1 ( {liste paramètres} ); |


[pure|impure] function func1 ( {liste paramêtres} ) return type;

paramètre ::= classe {nom} : [mode] type [:= default_val]


Les paramètres peuvent ne pas être passés au moment de l’appel

Les paramètres ont des modes qui dépendent de leur classe :

procedure : constant (in), variable (in,out,inout), signal(in,out,inout), file

51
function : constant (in), signal(in), file

La spécification permet de décrire effectivement le corps du sous programme.

spécification ::= procedure proc1 ( {liste paramètres} ) is


{déclarations locales}
begin
{seq. statement}
end ; |
[pure|impure] function func1 ( {liste paramêtres} ) return type is
{declarations locales}
begin
{seq. statement}
return result;
end ;

Attention : Les drivers des signaux sont passés complètement.


Les attributs signaux ou quantités sont interdits à l ’intérieur des sous programmes.
Les sous programmes peuvent contenir des instructions WAIT.
Les quantités sont traitées comme des variables (même en appel concurrent).
Dans une fonction il y a une erreur si le mot clé END est atteint.
La récursivité est supportée.

Les fonctions sont surchargeables, c’est à dire redéfinissables avec le même nom avec un autre prototype
(nouvelle interface ou nouveaux types)

opérateur «+» redéfini peut s’appeler :


a := c + d;
ou a := «+»(c,d);

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.

Attribute Builtin of « or » [MVL, MVL return MVL]:function is TRUE ;

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.

4.7 Domaine d'analyse et quantité source

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 :

if DOMAIN = quiescent_domain use


...
elsif DOMAIN = time_domain use
...
else
...
end use;

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 :

Source == source_tran + source_ac + source_noise ;

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.

quantity i through p to m; -- définition d’une quantité de branche


quantity ac : real spectrum 1.0, 0.0; -- source spectrale avec ampl. et phase constantes
quantity nois_src : real noise 4.0 * amb_temp * K/R; -- bruit : spectre d’ampl. dépend température
...
i == V/R + ac + nois_src ;

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.

Une source de fréquence peut avoir un comportement fréquentiel complexe.

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 ;

-- amb_temp est une variable partagée


{library clause}
ENTITY R_noise IS
generic (R_value : real := 1_000.0)
port (TERMINAL vp,vm:electrical);
END;

ARCHITECTURE equ OF R_noise IS


QUANTITY V ACROSS I THROUGH vp TO vm;
QUANTITY nois_src : real noise 4.0 * amb_temp * K/R_value;
BEGIN
V == R_value * I + noise_src;
END;
Fig 4.7 : Modèle de résistance avec bruit

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.

Limit Q :real with 2.0/freqmax ; (valable en analyses TRAN et AC)

Cette instruction n’est pas supportée par les outils actuels.

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.

[label :] postponed process …


[label :] postponed S <= ‘0’ after 3 ns ;
[label :] postponed assert . . .;

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.

subtype displacement is real tolerance « def_displ » ;


subnature elec2 is electrical tolerance « def_displ_ac » across « def_displ_th » through ;

m2 * x2’dot’dot == -f(x2-x1) tolerance « def_displ » ;

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.

4.10 Compléments sur la déclaration des signaux et signaux résolus

4.10.1 Signaux résolus

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) :

type bit4 is (’0’, ’1’, ’X’, ’Z’);


type bit4_v is array(natural range<>)of bit4;
function reso_f (s : bit4_v) return bit4;
subtype res_bit is reso_f bit4;

54
Le signal suivant sera alors résolu :

signal A : res_bit [register|bus] ;

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).

-- comportement d’un bus tri-state


function reso_f (s : bit4_v) return bit4 is
variable result : bit4 := ‘Z’;
variable x : integer := 0;
begin
for i in s’range loop
if s(i) /= ‘Z’ then
result := s(i);
x := x+1;
end if;
end loop;
case x is
when 0|1 => return result;
when others => return ‘X’;
end case;
end reso_f;
Fig 4.10.1 : Exemple de fonction de résolution

Petite digression : std_ulogic vd std_logic

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.

Petite digression : du danger des signaux résolus

Les débutants se disent : « je mets des signaux résolus partout ainsi je ne risquerai pas de conflit ».

C’EST TRES DANGEREUX

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.

4.10.1 Compléments sur la déclaration des signaux

La déclaration complète d’un signal s’écrit avec les options suivantes :

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 :

REGISTER : garde la dernière valeur rendue par la fonction de résolution


BUS : rend la valeur de la fonction de résolution appelée avec une entrée vide,
ce comportement doit être prévu par le programmeur dans la fonction de résolution

Une affectation est gardée (GUARDED) si le mot-clé GUARDED apparaît dans l ’affectation :

A <= guarded B after 3 ns;

On a alors 4 cas possibles :

signal non gardé / affectation non gardée


affectation classique
signal non gardé / affectation gardée
if GUARD=true then A <= . . . End if;
signal gardé / affectation non gardée
INTERDIT
signal gardé / affectation gardée
if GUARD=true then a <= . . .
Else déconnexion End if

La déconnexion d’un signal est spécifiée par l’instrution DISCONNECT :

disconnect nom_de_signal:type after time;

disconnect a,b:integer after 5 ns;


disconnect others:integer after 15 ns;
disconnect all:real after 20 ns;

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;

PACKAGE BODY bit_vector_ops IS


type internal is (ceci, pas, exporte);
FUNCTION "+"(left, right : bit_vector) RETURN bit_vector IS
VARIABLE carry : bit := '0';
BEGIN
FOR i IN result'reverse_range LOOP
. . .
END LOOP;
RETURN result;
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.

(1) Déclaration de composant : COMPONENT


(2) Instanciation du composant
Description structurelle = netlist de composants virtuels
(3) Configuration : instance de COMPONENT ? entité(archi)

(1) et (2) Généralisation à compiler une seule fois


(3) Spécialisation : applicable sans recompiler

Il existe deux méthodes de configuration :

Embarquée dans l ’architecture :


for lab_inst:nom_instance use lib_nam.entity(archi);
(voir 4.12.2)
Par unité de conception : la seule correcte

4.12.1 Configuration comme une unité de conception

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;

architecture rtl of adder is


begin
sum <= (a xor b) xor cin;
cout <= (a and b) or (cin and a) or (cin and b);
end rtl;
Fig 4.12-A : Modèle disponible

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;

architecture structural of adder4 is

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.

Si la hiérarchie était plus profonde on pourrait imbriquer :


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.

4.12.2 Configuration embarquée dans l’architecture

58
La norme fournit un raccourci d’écriture permettant d’embarquer la configuration dans l ’architecture.

architecture structural of adder4 is


-- étape (1)
component compo1
port (x,y,z : in bit; v,t : out bit);
end component;
signal carry : bit_vector(0 to 4);
-- étape (3)
for all: compo1 use entity work.adder(rtl)
port map (a=>x, b=>y, cin=>z, sum=>v, cout=>t);
begin
carry(0) <= cin;
-- étape (2)
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));
. . .
end structural;

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).

4.13 Le reste des attributs

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.

4.13.1 La liste exhaustive

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.

Type T ? Type : T'base


Seulement disponible comme préfixe d’un autre attribut (T’base’left par exemple)
Rend le type de base de T
Type T ? Value : T'left
Rend le borne gauche de T
Type T ? Value : T'right
Rend la borne droite de T
Type T ? Value : T'high
Rend la plus grande borne de T
Type T ? Value : T'low
Rend la plus petite borne de T
Type T ? Value : T'ascending
Vrai si le type est croissant
Type T ? Function : T'image(X)
Transforme le littéral X de T en chaîne de caractère
Type T ? Function : T'value(X)
Transforme la chaîne de caractère X dans le littéral de T
Type T ? Function : T'val(X)
Rend le littéral de l’énuméré qui est à la position X
Type T ? Function : T'pos(X)
Rend la position dans l’énuméré du littéral X
Type T ? Function : T'succ(X)
Rend le successeur de la position X dans l’énuméré T
Type T ? Function : T'pred(X)

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

Type adr is integer range 7 downto 0 ;

adr'left = 7
adr’right = 0
adr’low = 0
adr’high = 7

type MVL4 is (‘U’, ‘0’, ‘1’, ‘Z’) ;

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’

time’image(5 ns) = « 5000000 fs »


time’value(« 250 ms ») = 250 ms
time’val(634) = 634 fs
time’pos(2 ps) = 2000

type word is bit_vector(31 downto 0) ;


type memory is array (7 downto 0) of word ;
variable mem : memory ;

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

Signal S ? Signal : S’delayed[(T)]


Signal S ? Signal : S’stable[(T)]
Signal S ? Signal : S’quiet[(T)]
Signal S ? Signal : S'transaction
Ce signal de type bit est inversé à chaque fois qu’il y a une transaction sur S
Signal S ? Quantity : S'ramp([TR[,TF]])
Voir 4.13.2
Signal S ? Quantity : S'slew([max_rising_slope, [max_falling_slope]])
Voir 4.13.2
Signal S ? Fonction : S’event
Signal S ? Fonction : S'active
Ce booléen est vrai quand le signal S est actif (événement dans ce cycle)
Pour un signal composite, il suffit qu’une des composantes soit active
Signal S ? Fonction : S’last_event
Signal S ? Fonction : S'last_active
Rend le temps écoulé depuis le dernier événement
Signal S ? Fonction : S’last_value
Signal S ? Fonction : S'driving
Ce booléean est faux si le driver de S est vide
Signal S ? Fonction : S'driving_value
Valeur courante du driver de S dans le process courant
Entity E ? String : E'simple_name
Rend une chaîne de caractère contenant le nom de l’entité nommée
(entity | architecture | configuration | procedure | function | package | type | subtype
| constant | signal | variable | component | label | literal | units | group | file | nature | subnature
| quantity | terminal)
Entity E ? String : E'instance_name
Rend une chaîne décrivant le chemin décrivant la hiérarchie en partant de la racine de l’entité
nommée, incluant les entité instanciées.
Entity E ? String : E'path_name
Rend une chaîne décrivant le chemin décrivant la hiérarchie en partant de la racine de l’entité
nommée, excluant les entité instanciées.
Nature N ? Type : N’across
Nature N ? Type : N’through
Nature N ? Terminal : N’reference
Quantité Q ? Value : Q’tolerance
Rend la chaîne de caractère caractérisant la tolérance de Q
Quantité Q ? Quantité : Q’dot
Quantité Q ? Quantité : Q’integ
Quantité Q ? Quantité : Q'delayed(T)
Rend une quantité égale à Q mais décalée de T
Quantité Q ? Quantité : Q'zoh(T[,initial,delay])
Voir 4.13.2
Quantité Q ? Quantité : Q'ltf(num,den)
Voir 4.13.2
Quantité Q ? Quantité : Q'ztf(num,den,T[,initialelay])
Voir 4.13.2
Quantité Q ? Quantité : Q’slew([max_ris_slope,[max_fal_slope]])
Voir 4.13.2
Quantité Q ? Signal : Q’above(E)
Terminal T ? Quantité : T’contribution
Terminal T ? Quantité : T’reference
Terminal T ? Value : T'tolerance
Rend la chaîne de caractère caractérisant la tolérance de T

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.

Cet attribut est un des supports de l’interaction numérique-analogique.

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

Q'zoh(T[,initial,delay]): échantillonneur bloqueur.

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

Si num et den sont deux vecteurs de réels avec


num = (a 0 ,a1 ,a2 ,…,an )
den = (b 0 ,b 1 ,b 2 ,…,b n ) avec b 0 !=0

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) ;

représente la sortie temporelle du système excitée par Q.

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])

4.14 Les paquetages standards et utiles

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 :

Library STD,WORK ; use STD.STANDARD.all ;

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.

4.15 Utilisation par un simulateur des modèles VHDL-AMS

4.15.1 Compilation, élaboration, exécution, exploitation

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.

Compilation : Analyse syntaxique et sémantique

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

Simulation : (la plupart du temps, deux noyaux de simulation)


Vérifie les contraintes dynamiques de valeur
Rapporte les REPORT et pilote le simulateur avec le SEVERITY
Vérifie les boucles infinies des process, contrôle la convergence
Tient compte des BREAK

Exploitation : Tracé des chronogrammes, tracé des x(t),


Auto-test des modèles

4.15.2 Cycles de simulation

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.

Tc = 0.0 / Frequency = 0.0


Valeurs initiales des signaux et quantités
Exécute tous les PROCESS
(1) Exécute le solveur analogique : trouve point DC
Mise à jour des signaux
Exécute les PROCESS sensibles a ces signaux
Reste-il des événements dans la queue ?
Si OUI : retour en (1)
Quiescent state : Mise à jour du signal DOMAIN
Time_domain ou Frequency_domain simulation ?
Simulation dans le domaine temporel
(2) Extraire premiers événements de la liste
Avancer Tn à cette date
(3) Simuler analogique jusqu’ à Tn’ (proche de Tn) avec un pas déterminé par la convergence
Tn’ peut être < Tn à cause des Q’above(E)
avec plusieurs ASP qui ne coïncident pas forcément avec Tn
Tc = Tn : si Tc = time’high ou simulation_time alors END
Mise à jour des signaux
Exécution des PROCESS sensibles a ces signaux
Reste-il des événements dans la queue ou il y a t il un BREAK ?
Si OUI : Tn=Tc, retour en (3) [delta-cycle]
Si NON : retour en (2)
Simulation dans le domaine fréquentiel
Ne concerne que la partie continue (linéarisée)
Résolution d’un jeu d’équations algébriques linéaires à chaque point fréquentiel
Fig 4.15.2 : Cycle de simulation simplifié

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 ;

Si DOMAIN =quiescent_domain (recherche du point de fonctionnement DC)

BREAK [for selector_quantity] use quantity_name => expression ;

Sinon après une discontinuité

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;

architecture One of Capacitor is


quantity v across i through p to m;
begin
i == C * v’dot;
-- à l’initialisation = ic remplace v’dot == 0.0 si IC à été défini
break v => ic when ic /= REAL’low;
end architecture One;

architecture Two of Capacitor is


quantity v across i through p to m;
quantity q : charge;
begin
q == c * v;
i == q’dot;
-- à l’initialisation v = ic remplace q’dot == 0.0 si IC à été défini
break for q use v => ic when ic /= REAL’low;
end architecture Two;
Fig 4.15.3-A : Exemple d’initialisation de la charge d’un condensateur à T = 0.0

architecture ideal of ball is


quantity v:velocity;
quantity s:displacement;
constant G:real:= 9.31;
constant fric :real := 0.1;
begin
break v => 0.0, s => 10.0; -- conditions intiales à T=0.0
break v => -v when not s’above(0.0);
s ’dot == v;
if s’above(0.0) use V’dot == -G - v**2 * fric;
else V’dot == -G + v**2 * fric;
end use ;
end architecture ideal ;

65
Fig 4.15.3-B : Balle bondissante / Mise à jour des conditions initiales après discontinuité

4.16 Grammaire BNF interactive

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.

4.17.1 Modèle piloté par FSM : comparateur avec hystérésis [DAC]

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

Fig 4.17-A : Graphe de transfert du comparateur à hystéresis.

dout=’1’ one vin>vhi


vin<vhi
vin>vhi
unsta timeout unkn dout=’X’
vin<vlo
Vin>vlo
dout=’0’ zero
o vin<vlo

Fig 4.17-B : Graphe de fluence (bubble diagram) du comparateur à hystéresis.

library IEEE, Disciplines;


use IEEE. std_ logic_ 1164.all;
use Disciplines. electrical_ system. all;
entity ComparatorHyst is
generic (vlo, vhi: REAL; -- thresholds
timeout: DELAY_ LENGTH);
port (terminal ain, ref: electrical;
signal dout: out std_ logic);
end entity ComparatorHyst;

architecture Hysteresis of ComparatorHyst is


type states is (unknown, zero, one, unstable);
quantity vin across ain to ref;
function level( vin, vlo, vhi: REAL) return states is
begin
if vin < vlo then return zero;
elsif vin > vhi then return one;
else return unknown;
end if;
end function level;
begin

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.

4.17.2 Modèle analogique discontinu : Thyristor idéal

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.

library IEEE, Disciplines;


use IEEE. math_ real. all;
use Disciplines. electrical_ system. all;
entity Scr is
generic (von : voltage := 0.7; -- Turn on voltage
ihold : current := 0.0; -- Holding current
iss : REAL := 1.0e- 12);-- Saturation current
port (terminal anode, cathode, gate: electrical);
end entity Scr;

architecture Ideal of Scr is


quantity vscr across iscr through anode to cathode;
quantity vcntl across gate to cathode;
signal ison: BOOLEAN;
constant vt: REAL := 0.0258; -- thermal voltage
begin
process
variable off: BOOLEAN := true;
begin
ison <= not off;
case off is
when true => wait until vcntl’Above( von) and vscr’Above(
0.0);
off := false;
when false => wait until not (vcntl’Above( von)
or iscr’Above( ihold));
off := true;
end case;
end process;

if ison use iscr == iss * (exp( vscr/ vt) - 1.0);


else iscr == 0.0;
end use;

68
break on ison;
end architecture Ideal;
Fig 4.17.2 : Thyristor parfait

4.17.3 Ligne de transmission

L’écriture des équations d’une ligne de transmission est directe.

-----------------------------
-- ligne de transmission
-----------------------------
entity ligne is
generic (td, z0: real);
port (terminal t1, t1r, t2, t2r: electrical);
end ligne;

architecture t_ligne of ligne is


terminal t1x, t2x : electrical; -- 2 noeuds internes
quantity v1r across t1 to t1r;
quantity v1x across i1x through t1 to t1x;
quantity v1xr across t1x to t1r;
quantity v2r across t2 to t2r;
quantity v2x across i2x through t2 to t2x;
quantity v2xr across t2x to t2r;
begin
v1xr == v2r'delay(td) + z0 * i2x'delay(td);
v2xr == v1r'delay(td) + z0 * i1x'delay(td);
end t_ligne;
Fig 4.17.3 : Lignes de transmission

4.17.4 Transistor bipolaire

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;

architecture SEG of transistor_NPN is


quantity vbe across ib through b to e;
quantity vce across ic through c to e;
constant rb:real:=50.0;
begin
break on vbe'above(vd0), vce'above(vd0);

if not(vbe'above(vd0)) use -- bloque vbe<vd0


ib == 0.0;
ic == 0.0;
else

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;

architecture EBERS_MOLL of BJT is


constant ElectronCharge : real := 1.6021892E-19;
constant Boltzmann : real := 1.380662E-23;
constant Vth : real := Boltzmann * Temperature / ElectronCharge;
-- la temperature etant definie dans le generic
quantity Vbc across Ibc through base to collector;
quantity Vbe across Ibe through base to emitter;
quantity Itc through collector to emitter;
begin
-- equation de la jonction collecteur
Ibc == Is0 / Br * exp( Vbc / ( Nr * Vth ));
-- equation de la jonction emetteur
Ibe == Is0 / Bf * exp( Vbe / ( Nf * Vth ));
-- equation de courant de transport
Itc == Ibe * Bf - Ibc * Br;
end EBERS_MOLL;
Fig 4.17.4-B : Modèle Ebers-Moll d’un transistor bipolaire

4.17.5 Boucle à verrouillage de phase

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.

A/ Le VCO : description comportementale

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;

B/ Le comparateur analogique : description comportementale

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;

architecture Behavior of AnalogComparator is


quantity DeltaV across Pve_T to Nve_Y; -- tension differentielle
begin
Vout <= `1' when DeltaV'above(0.0)
else `0' when not DeltaV'above(0.0);
end architecture Behavior;

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;

architecture Behavior of RSFF is


signal loc_q,loc_qb :bit := ‘0’ ;
begin
loc_Q <= SB nand loc_QB after DelayQ;
loc_QB <= RB nand loc_Q after DelayQB;
Qb <= loc_qb;
Q <= loc_q;
end architecture Behavior;

entity PhaseDetector is
port(In1,In2 : BIT;
Up,Down : out BIT);
end entity PhaseDetector;

architecture Structure of PhaseDetector is


signal UpB,DownB,TQ,SUp,RDown,BQB,M : bit; -- signaux internes utilises.
component RSFF is -- il faut declarer les composants utilises.
port(SB,RB: in BIT;
Q,QB: BIT);
end component RSFF;
begin
-- definition des signaux internes utilises
SUp <= M and TQ;
RDown <= M and BQB;
M <= not( TQ and UpB and DownB and BQB);
-- Instanciations directe

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;

architecture Circuit of AnalogFilter is


terminal Vc1_T,Vc2_T :electrical; -- noeud interne
quantity Isource through Vc1_T to ground; -- source de courant
begin
-- equations modelisant le comportement des sources de courant.
if Up = `1' and Down = `0' use
Isource == 100E-6; -- 100mA
elsif Up = `0' and Down = `1' use
Isource == -100E-6; -- -100ma
else
Isource == 0.0; -- no current;
end use;
-- les composants suivants ont ete decrit precedemment.
C1: capacitor generic map (100E-12) port map(Vc1_T,ground);
R1: resistor generic map (100E3) port map(Vc1_T,Vfilter);
R2: resistor generic map (10E3) port map(Filter_T,Vc2_T);
C2: capacitor generic map (3.3E-9) port map(Vc2_T,ground);
end architecture Circuit;

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;

architecture Behavioral of Counter is


begin
-- declare a process with a variable to memorise counter state
process(Input) -- process is triggered by an input event
variable CurrentCount : natural := 0; -- count memory
begin
if Input='1' then -- a rising edge occured
CurrentCount := (CurrentCount+1) mod Count;
-- flip the output every Count/2 pulses
if CurrentCount < Count/2 then output <= `0' after Delay;
else Output <= `1' after Delay;
end if;
end if;
end process;
end architecture Behavioral;

72
F/ PLL structurelle

entity PLLFrequencyMultiplier is
port(terminal InWave_T,OutWave_T: electrical);
end entity PLLFrequencyMultiplier;

architecture MixedSignal of PLLFrequencyMultiplier is


signal Vcomparator,Up,Down,Vcounter,VCO_D : BIT; -- signaux internes
terminal Filter_T,VCO_T : electrical; -- terminaux internes
quantity Filter_V across FilterT to ground;
quantity VCO_V across VCO_T to ground;
-- Toutes les déclarations de comosants peuvent être « cachées »
-- dans un paquetage
component AnalogComparator is
port(terminal Pve_T,Nve_T: electrical;
signal Vout : out BIT );
end component;
component PhaseDetector is
port(In1,In2 : BIT;
Up,Down : out BIT );
end component;
component AnalogFilter is
port (signal Up,Down: bit; -- signaux d'entrees
terminal Filter_T: electrical ); -- sortie analogique
end component;
component VCO is
port(quantity Vin : in voltage;
terminal Out_T : electrical);
end component;
component Counter is
port (Input : in BIT;
Output : out BIT);
end component;
begin
Comparator_L: AnalogComparator
port map (Pve_T=>InWave_T, Nve_T=>ground, Vout=>Vcomparator);
PhaseDetector_L: PhaseDetector
port map (In1=>Vcomparator, In2=>Vcounter, Up=>Up, Down=>Down);
Filter_L: AnalogFilter
port map (Up=>Up, Down=>Down, Filter_T=>Filter_T);
VCO_L: VCO
port map ( Vin=>VCO_V, Out_T=>VCO_T);
-- conversion de la sortie analogique du VCO en numerique.
VCO_D <= `0' when VCO_V'above(2.5) -- logic threshold 2.5V
else `1' when not VCO_V'above(2.5);
Counter_L: Counter port map (Input=>VCO_D, Output=>Vcounter);
end architecture MixedSignal;

73
Chapitre 5 : Utilisation industrielle

5.0 Les ressources internet


On pourra récupérer des modèles et des documentations sur VHDL-AMS en tapant ce mot-clé dans n’importe
quel moteur de recherche. La difficulté est de trier les réponses en fonction de leur date. En effet, il reste
beaucoup de documents fossiles sur le WEB qui datent d’avant la normalisation ou qui présentent des travaux
incomplets. Il faut alors se méfier et le point d’entrée le plus fiable reste www.vhdl.org/analog.

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.

5.1 Bonnes méthodes et habitudes

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.

LIBRARY IEEE;use ieee.math_real.all;


entity x is port (a,b :std_ulogic; c : OUT std_ulogic); end;
architecture z OF x is
begin c <= a after 3 ns when (b’event and b=‘1’) else unaffected;
end;
architecture z2 of x is
begin
process
begin
wait until b=‘1’;
c <= a after 3 ns;
end process;
end;
ARCHITECTURE z3 OF x IS
BEGIN
process
begin
wait until b=‘1’;
c<=a after 3 ns;
end process;
end;
Fig 5.1-A : Mauvaise présentation de code

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.

Un module/modèle/composant ne doit être livré


ou utilisé qu’une fois rigoureusement testé et validé

5.1.3 Généricité, configuration et generate


VHDL-AMS met à notre disposition des constructions puissantes. Elles ne sont pas toujours supportées p ar les
outils et sont donc mal connues. De ce fait elles sont rarement utilisées par les concepteurs. Ce n’est qu’en
connaissant son outil et le langage dans les moindres détails qu’on pourra en tirer le meilleur avantage. Des
discussions avec des équipes de conception industrielle ont montré que c’est rarement le cas.

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.

Penser à l’avenir plutôt qu’au présent


en écrivant des modèles génériques

Par exemple :

a <= b after 3 ns ; pas réutilisable

generic(tpd : time:=3 ns);


a <= b after tpd ; réutilisable

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.

configuration test_adder4 of adder4 is


for structural
for all: compo1
use entity work.adder(rtl)
generic map (td => 12 ns, tr => 22 ns);
port map (a=>x, b=>y, cin=>z, sum=>v, cout=>t);
end for;
end test_adder4;
Fig 5.1.3 : La configuration comme support de la rétro-annotation

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).

5.3 Testbenchs avancés

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

Générateurs de Système Acquisition


signaux matériel sous ou
programmable Test (DUT) Visu

CI : testeur sous
pointes ou JTAG
Analyse Rapport de test
De données Ou Décision
(GO/NOGO)

Fig 5.3-A : Matériel sous test (Device Under Test : DUT)

Les modèles seront soumis à un environnement simulé reprenant les mêmes fonctionnalités.

Testbench : modèle instanciant le DUT et les utilitaires de test

Cahier des Contrôle


Charges du test du test
Chronogramme
(FSM) Spectres

Modèle de Modèle sous Acquisition


générateur de Test (DUT) ou
signaux Visu

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;

architecture bhv of Step_meas is


signal stim_val : real := Tlow;
signal rt_10 : real := -1.0; -- temp pour 10%
constant Tstep:real:= Thigh - Tlow;
constant Th0_1:real:= DUTgain*(Tlow+ 0.1 * Tstep);
constant Th0_9:real:= DUTgain*(Tlow+ 0.9 * Tstep);
begin
stim_val <= Thigh after real2time(Tstart);
T_out == Stim_val ’RAMP(Trt,Trt);
measure_rt : process -- recherche la passage à 10% et à 90%
begin
wait until DOMAIN = time_domain;
wait until T_in’above(Th0_1) and NOW <= Tend;
rt_10 <= NOW;
wait until T_in’above(Th0_9) and NOW <= Tend;
rt_val <= NOW - rt_10;
end process measure_rt;
end architecture bhv;

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.

5.4 Intellectual property

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.

5.7 Liaison avec la fabrication

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,
…).

5.8 Synthèse logique et VHDL'93

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

6.1.1 Equations aux dimensions

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.

6.1.2 Equations aux dérivées partielles

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)

6.1.3 Sémantique de connexion

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

6.2.0 Erreurs très communes

A/ Transaction plutôt qu’événement

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

B/ Mécanismes temporels mal compris

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

C/ La mécanique des variables et des signaux

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

Ce fonctionnement permet des raccourcis d’écriture. Si dans un process on trouve

A<=B ;
B<= A ;

On effectue l’échange de A et B sans intermédiaire.

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 ;

package body MVL4 is


“=”(A,B :X01Z) return boolean is
begin
if A=B then return true ;
else return false ;
end if ;
end ;
end ;
Fig 6.2.0-G : Surcharge explosive

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 =.

package body MVL4 is


“=”(A,B :X01Z) return boolean is
type table is array (X01Z,X01Z) of boolean;
constant tdv :table((true,false,false,false),
(false,true,false,false),
(false,false,true,false),
(false,false,false,true)) ;
begin
return tdv(A,B) ;
end ;
Fig 6.2.0-H : Surcharge raisonnable

6.2.1 Relations avec l'algorithme de simulation

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 ;

6.2.2 Manque de WAIT

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

break on Q'above(X) implique Q==X

provoque une instabilité du simulateur (Q oscille autour de X).

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;

-- LEVEL_0, et LEVEL_1 NE FONCTIONNENT PAS


-- CE MODELE NE FONCTIONNE PAS
-- Swith parfait commandé en tension
architecture level_0 of diode is
quantity v across i through vp to vm;
begin
break on v'above(0.0);
if v'above(0.0) use
V == 0.0;
Else
I == 0.0;
end use;
end;

-- CE MODELE NE FONCTIONNE PAS


-- Commande en tension avec seuil et pas de résitance interne
architecture level_1 of diode is
quantity v across i through vp to vm;
begin
break on v'above(vs);
if v'above(vs) use
V == vs;
Else
I == 0.0;
end use;
end;

-- 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;

Fig 6.2.3-A : Le piège du seuil

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;

-- CETTE ARCHITECTURE NE SIMULE PAS


architecture Bad of limiter is
quantity vin across inp to inm;
quantity vout across iout through outp to outm;
begin
if vout > limit use
vout == limit;
elsif vout < -limit use
vout == -limit;
else
vout == gain*vin;
end use;
end architecture simult;

-- CETTE ARCHITECTURE FONCTIONNE


architecture Good of limiter is
quantity vin across inp to inm;
quantity vout across iout through outp to outm;
begin
break on vin’above(limit/gain), vin’above(-limit/gain) ;
if vin’above(limit/gain) use
vout == limit;
elsif not vin’above(-limit/gain) use
vout == -limit;
else
v == gain*vin;
end use;
end architecture simult;

Fig 6.2.3-B : Autre illustration du piège du seuil

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;

-- Ce modèle ne compile pas (critère de convergence)


architecture basic_1 of aop is
quantity vs across vout to ground;
quantity vepsilon across vp to vn;
begin
vs == model.gain * vepsilon;
-- limitation de la valeur de sortie aux valeurs des alimentations
if (vs >= model.vmax) use
vs == model.vmax;
end use;
if (vs <= model.vmin) use
vs == model.vmin;
end use;
end basic_1;

-- Ce modèle ne fonctionne pas (piège du seuil / pas de break)


architecture basic_2 of aop is
quantity vs across i through vout to ground;
quantity vepsilon across vp to vn;
begin
-- limitation de la valeur de sortie aux valeurs des alimentations
if (vs >= model.vmax) use vs == model.vmax;
elseif (vs <= model.vmin) use vs == model.vmin;
else
vs == model.gain * vepsilon;
end use;
end basic_2;

-- Ce modèle fonctionne mais est conceptuellement faux


-- car il laisse vloc atteindre des valeurs impossibles dans
-- la réalité où aucun signal ne peut dépasser les alims
architecture basic_good of aop is
quantity vs across i through vout to ground;
quantity vepsilon across vp to vn;
quantity vloc:real
begin
vloc == model.gain * vepsilon
-- limitation de la valeur de sortie aux valeurs des alimentations
break on vloc’above(model.vmax), vloc’above(model.vmin) ;
if vloc’above(model.vmax) use vs == model.vmax;
elseif not vloc’above(model.vmin) use vs == model.vmin;
else vs == vloc ;
end use;
end basic_2;

Fig 6.2.3-C : Piège du seuil dans les modèles d’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.

6.3 Erreurs méthodologiques, faux gains de temps


L’utilisation d’un langage de haut niveau performant n’empêche pas de se poser des questions de méthodologie.
De mauvaises habitudes peuvent cacher de faux gains de temps qui seront d’autant plus difficile à combler que
l’environnement est complexe et un mauvais choix pris au commencement d’une étude peut être très difficile à
rattraper dans la suite.

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 développement sans analyse


Se lancer tête baissée sur l’outil de modélisation sans une réflexion préalable profonde mène
souvent à la mise à la poubelle des premiers développements pour repartir sur des bases
saines.
Les débutant, par la nouveauté et la puissance de l’outil, oublient souvent de faire fonctionner
leur cerveau pour analyser les besoins, peser les choix avant de coder les modèles.
L’interdépendance entre toutes les tâches dans l’ingénierie simultanée rend les erreurs de choix
très dommageable pour tout le projet qui peut avoir des tâches en avance de phase (le routeur
de PCB doit refaire son travail parce que vous n’avez pas défini un boîtier ayant assez de
pattes)

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.

Ne pas confronter au monde réel


Faire confiance au simulateur (notamment analogique) sans confronter le modèle à la réalité est
source de beaucoup d’erreurs. Notre civilisation, mais aussi les modes d’enseignements,
s’orientent vers le virtuel. Les systèmes à concevoir sont bien réels et leurs modèles doivent en
tenir compte (Un physicien simulant une de ses théories et trouvant un résultat loin de ce qui se
passe dans la réalité ne peut pas en déduire que le monde réel à un bug ! )

Ne pas utiliser toutes les possibilités de l ’outil


Dans beaucoup d’endroits on constate que les outils puissants qui sont mis à disposition ne sont
que très sous employés. C’est de la responsabilité du concepteur d’analyser les possibilités qui
s’offrent à lui pour pouvoir les exploiter à fond.

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 disponibles peuvent de classer en plusieurs catégories :

Les outils intégrés dans un environnement industriel de conception assisté par ordinateur

- ADV_MS de ANACAD, intégré à MENTOR-GRAPHICS


http://www.mentor.com/ams/simulation.html
- SMASH de DOLPHIN INTEGRATION
http://www.dolphin.fr

Les outils indépendants d’un environnement de CAO

- TheHDL de ANALOGY (automobile, électromagnétique, électrotechnique)


http://www.analogy.com
- FTL Systems VHDL-AMS Compiler/Simulator – Supporte le parallélisme (AURIGA)
http://www.ftlsystems.com
- hAMSter (High performance AMS tool for Engineering and Research ) PC – 495$
http://www.hamster-ams.com
- Microcosm Technologies (MOEMS)
http://www.memcad.com

Les outils universitaires

- SEAMS de l’université de Cincinnati (avec support du parallélisme)


http://www.ececs.uc.edu/~dpl
- Convertisseur SPICE vers VHDL-AMS
http://www.ececs.uc.edu/~mayilad/translator.html

Les utilitaires permettant de fabriquer des environnements

- IVE - Infineon Technologies VHDL-AMS Environment


http://herkules.informatik.tu-chemitz.de/ive
- LEDA VHDL-AMS Front-end tools
http://www.leda.fr (problème d’accès à cette adresse)

Les utilitaires universitaires

- University of Southhampton VHDL-AMS Analyzer (en ligne)


http://www.syssim.ecs.soton.ac.uk/vhdl-ams/web-parser/web-form.html
- University of Frankfurt Java VHDL-AMS Parser
http://www.vhdl-ams.de/Tools/body_tools.html

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.

7.1 ADV-MS de ANACAD (version v1.1_1.1)

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.

La conception VHDL-AMS se fait dans l’environnement ELDO de ANACAD assisté du compilateur et du


simulateur v-system de MODEL-TECHNOLOGY. Le « parsing » du code es t assuré par l’outil de la société
française LEDA.

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.

Ce qui n’est pas supporté

Types composites : record, multidimensional arrays, quantity and terminal arrays


Type résolus utilisateur
Procedural
Quantity ports
Initialization and break : break list (pas de conditions initiales en DC ou après une discontinuité)
Appel concurrent de procédure
NOISE sources
Fichiers
T ’contribution
CONFIGURATION
Disconnection, registers, buses, guarded signals
Shared variables and file objects
Alias
Attributs utilisateurs
Unaffected
Generate
Null simultaneous statement
Group
Open : les ports doivent être connectés
S ’driving, S ’driving_value
Postponed processes

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

SPECTRUM sources : magnitude/phase statiques


Les conditional simultaneous statements doivent être équilibrés (if cond use … else … end use;)
Dans un ASSERT le severity est obligatoire (non documenté)
assert A = ‘ 1 ’ report « A est faux » ; ne marche pas
assert A = ‘ 1 ’ report « A est faux » severity note ; marche
Fig 7.1 : Les limitations de ADV_MS 1.1_1.1 de ANACAD

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

7.2 SMASH-AMS (version 4.9.12)

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).

Ce qui n’est pas supporté

Q’slew (non documenté)


Les ports vectoriels ou record (non documenté)
Spectrum
Noise
Limit
‘LTF
‘ZTF
Generate conditionnel
Partie instructions de l’entité
Sous-programmes déclarés dans des sous programmes
Déclaration de signal dans les paquetages
Attributs
Fonction de résolution utilisateur
Disconnect
Fichiers
Shift (operateurs)
T’POS(X), T’VAL(X), T’SUCC(X), T’PRED(X), T’LEFTOF(X), T’RIGHTOF(X)
S’DELAYED(T), S’TRANSACTION, S’DRIVING, S’DRIVING_VALUE

Fig 7.2 : Les limitations de SMASH 4.2.12 de DOLPHIN

L’instruction BREAK est supportée dans une forme quasiment complète.

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.

8.1.2 Le détecteur et son environnement

Phénomènes physiques pris en charge dans le modèle :

Dans ce modèle Ce qui n’est pas pris en compte


Caractéristiques du matériau (gap) Vraies dimensions 3D
Epaisseur (Géométrie 1D) Production de paires
Température constante Dépôt en nuage
Champ électrique constant Modification du champ électrique par les charges
Statistique de l’absorption Champ électrique Non uniforme
Compton / Photo electric distribution Trajectoire des photons secondaires
Photon secondaire (nombre et énergie) Interactions secondaires
Dépôt d’énergie uniforme Piégeage = f(champ)
Théorème de RAMO (électrodes infinies) Diffusion
Piégeage sans dépiégeage Empilement intra détecteur
Pas d’empilement dans le détecteur Bruit intrinsèque
Fig 8.1.2 : Portée du modèle

8.1.3 Le code du modèle

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.

1 library disciplines; use disciplines.Electromagnetic_system.all;


2 ENTITY shaper is
3 Generic (tau : real := 1.0e-6);
4 port(terminal inpinp,inpinm,outpin: electrical);
5 END;
6
7 library disciplines; use disciplines.Electromagnetic_system.all;
8 library ieee; use ieee.math_real.all;
9 ARCHITECTURE archi1 OF shaper IS
10 Quantity iin through inpinp to inpinm;
11 Quantity vout across outpin;
12 BEGIN
13 -- fabrication d'impulsions filtrees
14 1000.0*iin == (tau*tau)*vout'dot'dot + 2.0 * tau * vout'dot +
15 vout;
END;
Fig 8.1.4-B : Description comportementale d’un Shaper

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.

1 library disciplines; use disciplines.Electromagnetic_system.all;


2 library ieee; use ieee.math_real.all;
3 entity spectro is
4 generic (analysis_time : time := 100 ms;
5 channel_nb : integer := 100;
6 ampl_max : real := 1.0);
7 port (terminal inpin:electrical;
8 signal spectre : out real := 0.0);
9 end ;
10
11 library disciplines; use disciplines.Electromagnetic_system.all;
12 library ieee; use ieee.math_real.all;
13 architecture algo of spectro is
14 signal watchdog : boolean := false;
15 quantity vtest across inpin;
16 type integer_vector is array(natural range <>) of integer;
17 begin
18 process
19 begin
20 wait for analysis_time;
21 watchdog <= not watchdog;
22 end process;
23
24 process
25 variable spectre_res : integer_vector(0 to channel_nb-1) := (others
26 => 0);
27 variable index_tab : integer;
28 begin
29 wait on vtest'dot'above(0.0),watchdog;
30 if watchdog'event then
31 -- affichage
32 for i in 0 to channel_nb-1 loop
33 spectre <= real(spectre_res(i));
34 wait for 1 us;
35 end loop;

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;

Fig 8.1.4-C : Vue algorithmique du spectromètre

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;

Fig 8.1.4-D : Netlist structurelle

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

Fig 8.1.5-B : Impulsions après le Shaper (avec empilement)

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).

8.2.2 Code source

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;

-- Calcule la masse totale

99
function sigma(a:real_vector) return real;

-- opérations arithmétiques sur les types locaux


function "*"(a:real_vector,b:V_Vector_3D) return Vector_3D;
function "*"(a:real, b:real_vector) return real_Vector;
function "*"(a:real_vector, b:real_vector) return real_Vector;
function "*"(a:real, b:Vector_3D) return Vector_3D;
function "+"(a:V_Vector_3D,b:V_Vector_3D) return V_Vector_3D;
function "+"(a:Vector_3D,b:Vector_3D) return Vector_3D;
function "-"(a:Vector_3D,b:Vector_3D) return Vector_3D;
function "/"(a:Vector_3D,b:real) return Vector_3D;
function "/"(a:real_vector, b:real) return real_Vector;

function force(M_T:real, Mass:real_vector, Loc:V_Vector_3D)


return V_vector_3D;
end package;
Fig 8.2-A : Le paquetage d’utilitaires pour les N-corps

Le corps du paquetage est disponible en annexe.

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).

8.3 Automate cellulaire

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

architecture Cellular_automata of Space_2D_time is


signal XY real_vector(1 to N, 1 to M);
signal clock:bit;;
begin

clock <= not clock after 1 ms;

block (clock'event and clock='1')


begin
-- Excitation par les bords
for j=1 to M generate
xy(0,j) <= K;
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;

-- Fonctionnement du réseau logique


for i=1 to N-1 generate
for j=1 to M-1 generate
-- Cette ligne donne la fonction de l’automate
XY(i,j) <= (xy(i-1,j)+xy(i+1,j)+xy(i,j-1)+xy(i,j+1))/4.0;
end generate;
end generate;
end;

end;

Fig 8.3 : Modèle générique d’un automate cellulaire

8.4 Réseaux de plots résistifs

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 ;

Architecture Struct of N-plots is


Terminal V:electrical vector(1 to n, 1 to m); -- les terminaux internes
begin
for i=1 to m generate –- résistances horizontales (haut et du bas)
R_H: entity R(equ) generic map(Alea_r) port map(vp,v(1,i));
R_H: entity R(equ) generic map(Alea_r) port map(v(n,i),vm);
end generate;
for i=1 to m generate –- résistances horizontales internes
for j=1 to n generate
R_H: entity R(equ) generic map(Alea_r) port map(v(j,i),v(j,i+1));
end generate;
end generate;

for i=1 to n generate –- résistances verticales


for j=0 to m-1 generate
R_V: entity R(equ) generic map(Alea_r) port map(v(i,j),v(i,j+1));
end generate;
end generate;
end;
Fig 8.4 : Modèle d’un NM plots

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).

8.5 Résolution d’équations aux dérivées partielles

Ce modèle n’est pas compilable avec les outils disponibles.

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;

architecture PDE of Space_2D_time is


quantity XY, dXY_dx, dXY_dy real_vector(1 to N, 1 to M);
begin

-- 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;

-- réseau analogique (discrétisation spatiale)


for i=1 to N-1 generate
for j=1 to M-1 generate
dXY_dx == DERIV_x(XY) ;
dXY_dy == DERIV_y-XY) ;
XY(i,j) == PDE(XY,dXY_dx,dXY_dy) ;
end generate;
end generate;

end;
Fig 8.5 : Résolution par VHDL-AMS de PDE

8.6 Convertisseur Analogique numérique de type Delta-Sigma

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;

architecture num of modulator is


quantity vin across T_in;
signal SS_int:real:=0.0;
begin

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;

architecture beh_anal of modulator is


quantity vin across T_in;
quantity vmem,vint : real;
signal LocQ : boolean;
begin

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;

Fig 8.6-B : Code source du modulateur Delta-Sigma

8.7 Exemple d’étude d’un système intégré

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.

Fig 8.7-A : Schéma de principe de la chaîne de mesure

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;

-- Architecture purement fonctionnelle


-- C'est dans le testbench que l'on tient compte de l'orientation
-- du capteur par rapport au champ magnétique

Architecture CdC of system is


quantity champ across B;
signal clk16, clk2 : std_ulogic := '0';
constant gain : real := 127.0 / 0.005;
begin

-- Pas de limitation de la bande passante à 500Hz


-- dans cette version
-- champ_limited == champ'ltf(num/den);

clk2_out <= clk2;

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;

-- On ne simule pas le retard entrée-sortie dû au décalage


-- dans les parties numériques (CAN et filtre numérique)

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.

-- L'architecture CDC_STRUCT est un structurel de chacun des objets


-- sous leur forme la plus simple possible

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

gck : entity gene_clock(cdc) port map (clk128,clk16,clk2);


Cpt : entity capteur(cdc) port map (B,T1);
Cmp : entity compens(cdc) port map (clk128,on_off,t2,t4,vref);
Pre : entity preampli (cdc) port map (t1,gnd,t2);
Amp : entity ampli(cdc) port map (t2,t3,t4);
Flt : entity filtre(cdc) port map (t4,t5);
CAN : entity delta_sigma(cdc) port map (t5,s1,clk128);
S2U : entity conversion(cdc) port map (clk2,s1,s2);
P2S : entity para2serie(cdc)
Port map(clk16,s2,serial_out,clk2_out,strobe);

parallel_out <= s2;


end;

Fig 8.7-C : Code source du système sous forme structurelle

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)

[ANA] Modeling in analog design


Edited by J.M.Bergé, Oz Levia, J.Rouillard, Kluwer, ISBN 0-7923-9569-7

[CAE] CAE : A survey of standards, trends and tools


Stephan A.Ohr, Wiley, ISBN : 0-471-6336-6

[DAC99] Tutorial VHDL-AMS au cours de la 36ème Design Automation Conference


Ernst Christen et al., New Orleans, june 21-25, 1999

[LRM] 1076.1-1999 IEEE Standard VHDL Analog and Mixed-Signal Extensions


320 pages [0-7381-1640-8], commandable sur http://www.vhdl.org/analog/

[MAST] Modeling with an Analog Harware Descrition Language


H.Alan Mantooth, Mike Fiegenbaum, Kluwer, ISBN 0-7923-9516-6

[MHDL] Analog Modeling using MHDL


David L.Rhodes, In [ANA], pp 47-92

[ROAD] International Technology Roadmap for Semiconductors


1999 Edition, Semiconductor Industry Association
http://publi.itrs.net/files/1999_SIA_Roadmap/Home.htm

[SMASH] Documentaiton de SMASH 4.9.12 de DOLPHIN INTEGRATION

[SPICE1] Spice : A guide to Circuit Simulation Analysis usin Pspice


Paul W. Tuinega, Prentice Hall, ISBN 0-13-834607-0

[VHDL-A] Design Objectives and Rationales


C.J Richard Shi, A.Vachoux, In [ANA], pp 1-45

[VHDL1] VHDL : Du langage à la modélisation


R.Airiau, J-M. Bergé, V.Olive, J.Rouillard
CNET/ENST, Presses Polytechniques et Universitaires Romandes
ISBN : 2-88074-191-2

[VHDL2] VHDL : Du langage à la modélisation


J-M. Bergé, V.Olive, J.Rouillard
CNET/ENST, Presses Polytechniques et Universitaires Romandes
ISBN : 2-88074-361-3

[VHDL3] The student’s guide to VHDL


Peter Ashenden, Hartcourt Publisher, ISBN 1-55860-520-7

[VHDL4] VHDL for programmable logic


Kevin Shakill, Addisson Wesley, ISBN 0-201-89573-0

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.

Firmware : Logiciel embarqué permettant de commander le matériel

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.

FSM : (Finite state machine) Machine d’états finie ou automate

HDL : (Harware Description Language) Langage de description de matériel, nom


générique pour tous les formats ASCII permettant cette tâche. Un HDL est de plus ou
moins haut niveau. Les formats graphiques (schémas, graphes de fluence) ne sont pas
normalement classés dans cette catégorie.

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é.

Mécatronique : Discipline technique faisant cohabiter la mécanique et l’électronique.

Netlist : (ou liste d’équipotentielles) C’est la description, la plupart du temps en ASCII, de


l’interconnexion de primitives permettant l’échange d‘informations entre les différents
outils. Le langage original de SPICE est basé est la description d’une netlist. Il existe
des formats normalisés comme EDIF 2.0.0. VHDL est de plus en plus utilisé pour
cette tâche.

PAL : (Programmable Array Logic) Petit composant programmable à deux couches de


logiques (OU programmable, ET fixe) , ancêtre des FPGA.

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

Compilateur/simulateur SMASH de DOLPHIN Integration


Exemples
Fichiers d’aide (grammaire BNF, Listes des ressources normalisées)
Support de cours au format Power Point ? ? ?
PDF du DAC 99

Niveaux d'abstraction

Avec : ODE : Ordinary Differential Equation


DAE : Difference Alegebraic Equations

Niveau d’abstraction Comportement Structure


Système Spécification, Modèles statistiques Processeurs, mémoires
Algorithme Programmation impérative Structures de données, fonctions
RTL (transfert de registre) Process, Prog. Déclarative ALU, multiplexeurs, registres
Logique Réseau d’équations booléennes Portes
Interrupteurs Réseau d’équations discrêtes Transistors en commutation
Circuit Réseau d’ODE, Réseau de DAE Transistor, R,C,L, Sources …
Fig B-1 : Les niveaux d’abstraction en modélisation de systèmes

Niveau d’abstraction Comportement Structure


Système DAE non conservatives Schémas blocs physiques
Fonctionnel Flot de signal/Fonctions de transfert Schémas blocs fonctionnels
Comportemental DAE conservatives Multi-ports
Circuit ODE conservatives Primitives (R,C, L, …)
Fig B-2 : Les niveaux d’expression en temps continu

113
Liste des 108 mot-clés de VHDL-AMS

Mots clefs introduits dans :


VHDL 87 (IEEE 1076.1987) - pas de note
VHDL 93 (IEEE 1076.1993) - noté (93) [connu aussi sous VHDL 92]
VHDL-AMS (IEEE 1076.1999) - noté (99)

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)

::= affectation d'un règle à son nom


[xx] xx est optionel
{yy} yy se répète N fois avec N éventuellement nul
x|y choix (OU) entre x et y

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 ;) :

alias_declaration Entity_declaration Return_statement


architecture_body exit_statement Secondary_unit_declaration
assertion_statement file_declaration Selected_signal_assignment
attribute_declaration free_quantity_declaration Shared_variable_declaration
attribute_specification full_type_declaration Signal_assignment_statement
block_configuration generate_statement Signal_declaration
block_header generic_clause Simple_simultaneous_statement
block_statement group_declaration Simultaneous_case_statement
branch_quantity_declaration group_template_declaration Simultaneous_if_statement
break_statement if_statement Simultaneous_null_statement
case_statement incomplete_type_declaration Simultaneous_procedural_statement
component_configuration library_clause Source_quantity_declaration
component_declaration loop_statement Step_limit_specification
component_instantiation_statement nature_declaration Subnature_declaration
concurrent_assertion_statement next_statement Subprogram_body
concurrent_break_statement null_statement Subprogram_declaration
concurrent_procedure_call_statement package_body Subtype_declaration
concurrent_signal_assignment_statement package_declaration Terminal_declaration
conditional_signal_assignment port_clause Type_declaration
configuration_declaration procedure_call_statement Use_clause
configuration_specification process_statement Variable_assignment_statement
constant_declaration report_statement Variable_declaration
disconnection_specification Wait_statement
element_declaration

LA GRAMMAIRE (285 règles)

1 [$ 13.4] abstract_literal ::= decimal_literal | based_literal


2 [$ 3.3] access_type_definition ::= access subtype_indication
3 [$ 4.3.1.6] across_aspect ::= identifier_list [tolerance_aspect] [:=expression ]
4 [$ 4.3.2.2] actual_designator ::= expression | signal_name | variable_name | file_name | terminal_name |
quantity_name | open
5 [$ 7.3.3] actual_parameter_part ::= parameter_association_list
6 [$ 4.3.2.2] actual_part ::= actual_designator | function_name (actual_designator) | type_mark
(actual_designator)
7 [$ 7.2] adding_operator ::= + | - | &
8 [$ 7.3.2] aggregate ::= ( element_association { , element_association } )
10 [$ 4.3.3] alias_declaration ::= alias alias_designator [ : subtypealias_indication ] is name [ signature ] ;
11 [$ 4.3.3] alias_designator ::= identifier | character_literal | operator_symbol
12 [$ 4.3.3] alias_indication ::= subtype_indication | subnature_indication
13 [$ 7.3.6] allocator ::= new subtype_indication | new qualified_expression
14 [$ 1.2] architecture_body ::= architecture identifier of entity_name is

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 :

T'left, T'right, T'high, T'low, T'ascending

Type T ? Function :

T'image(X), T'value(X), T'val(X), T'pos(X), T'succ(X),


T'pred(X), T'leftof(X), T'rightof(X)

Array A ? Function :

A’left[(N)], A’right[(N)], A’high[(N)], A’low[(N)]

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é)

S’delayed[(T)], S’stable[(T)], S’quiet[(T)], S'transaction

Signal S ? Quantity :

S'ramp([TR[,TF]]),
S'slew([max_rising_slope, [max_falling_slope]])

Signal S ? Fonction :

S’event, S'active, S’last_event, S'last_active,


S’last_value, S'driving, S'driving_value

Entity E ? String :

E'simple_name, E'instance_name, E'path_name

Nature N ? Type :

N’across, N’through

Nature N ? Terminal :

N’reference

Quantité Q ? Value :

Q’tolerance

124
Quantité Q ? Quantité :

Q’dot, Q’integ, Q'delayed(T), Q'zoh(T[,initial,delay]),


Q'ltf(num,den), Q'ztf(num,den,T[,initial,delay]),
Q'slew([max_rising_slope, [max_falling_slope]])

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 : STANDARD


Library STD : TEXTIO
Library IEEE : STD_LOGIC_1164
Library IEEE : STD_LOGIC_ARITH
Library IEEE : NUMERIC_BIT (pour la synthèse)
Library IEEE : NUMERIC_STD (pour la synthèse)
Library IEEE : MATH_REAL
Library DISCIPLINES : PHYSICAL_CONSTANTS
Library DISCIPLINES : ELECTROMAGNETIC_SYSTEM
Library DISCIPLINES : THERMAL_SYSTEM
Library DISCIPLINES : KINEMATIC_SYSTEM
Library DISCIPLINES : ROTATIONAL_SYSTEM
Library DISCIPLINES : FLUIDIC_SYSTEM

Library STD

STD.STANDARD

TYPE BOOLEAN IS (FALSE,TRUE);


TYPE BIT IS ('0', '1');
TYPE CHARACTER ...
TYPE SEVERITY_LEVEL IS (NOTE, WARNING, ERROR, FAILURE);
TYPE INTEGER IS RANGE -2147483648 TO 2147483647;
TYPE REAL IS RANGE -1.0E38 TO 1.0E38;
TYPE TIME IS RANGE - 2**62 -2**62 TO 2**62 - 1 + 2**62 UNITS FS;
PS = 1000 FS; NS = 1000 PS; US = 1000 NS; MS = 1000 US; SEC = 1000 MS; MIN = 60 SEC;
HR = 60 MIN;
END UNITS;
TYPE DOMAIN_TYPE IS (QUIESCENT_DOMAIN, TIME_DOMAIN, FREQUENCY_DOMAIN);
SIGNAL DOMAIN: DOMAIN_TYPE:=QUIESCENT_DOMAIN;
SUBTYPE DELAY_LENGTH IS TIME RANGE 0 FS TO TIME'HIGH;
IMPURE FUNCTION NOW RETURN DELAY_LENGTH;
IMPURE FUNCTION NOW RETURN REAL;
FUNCTION FREQUENCY RETURN REAL;
SUBTYPE NATURAL IS INTEGER RANGE 0 TO INTEGER'HIGH;
SUBTYPE POSITIVE IS INTEGER RANGE 1 TO INTEGER'HIGH;
TYPE REAL_VECTOR IS ARRAY (NATURAL RANGE <>) OF REAL;
TYPE STRING IS ARRAY (POSITIVE RANGE <>) OF CHARACTER;
TYPE BIT_VECTOR IS ARRAY (NATURAL RANGE <>) OF BIT;
TYPE FILE_OPEN_KIND IS (READ_MODE, WRITE_MODE, APPEND_MODE);
TYPE FILE_OPEN_STATUS IS (OPEN_OK, STATUS_ERROR, NAME_ERROR, MODE_ERROR);
ATTRIBUTE FOREIGN:STRING;

STD.TEXTIO

type LINE is access string;


type TEXT is file of string;
type SIDE is (right, left);
subtype WIDTH is natural;
file input : TEXT open READ_MODE is "STD_INPUT";
file output : TEXT open WRITE_MODE is "STD_OUTPUT";
procedure READLINE(file f: TEXT; L: inout LINE);
procedure READ(L:inout LINE; VALUE: out bit; GOOD : out BOOLEAN);
procedure READ(L:inout LINE; VALUE: out bit);

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

TYPE std_ulogic IS ('U','X','0','1','Z','W','L','H','-' );


TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;
FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic;
SUBTYPE std_logic IS resolved std_ulogic;
TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;
SUBTYPE X01 IS resolved std_ulogic RANGE 'X' TO '1'; -- ('X','0','1')
SUBTYPE X01Z IS resolved std_ulogic RANGE 'X' TO 'Z'; -- ('X','0','1','Z')
SUBTYPE UX01 IS resolved std_ulogic RANGE 'U' TO '1'; -- ('U','X','0','1')
SUBTYPE UX01Z IS resolved std_ulogic RANGE 'U' TO 'Z'; -- ('U','X','0','1','Z')
FUNCTION "and" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
FUNCTION "nand" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
FUNCTION "or" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
FUNCTION "nor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
FUNCTION "xor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
FUNCTION "xnor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
FUNCTION "not" ( l : std_ulogic ) RETURN UX01;
FUNCTION "and" ( l, r : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "and" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION "nand" ( l, r : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "nand" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION "or" ( l, r : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "or" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION "nor" ( l, r : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "nor" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION "xor" ( l, r : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "xor" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION "xnor" ( l, r : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "xnor" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION "not" ( l : std_logic_vector ) RETURN std_logic_vector;
FUNCTION "not" ( l : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION To_bit ( s : std_ulogic; xmap : BIT := '0') RETURN BIT;
FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR;
FUNCTION To_bitvector ( s : std_ulogic_vector; xmap : BIT := '0') RETURN BIT_VECTOR;
FUNCTION To_StdULogic ( b : BIT ) RETURN std_ulogic;
FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector;
FUNCTION To_StdLogicVector ( s : std_ulogic_vector ) RETURN std_logic_vector;
FUNCTION To_StdULogicVector ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
FUNCTION To_StdULogicVector ( s : std_logic_vector ) RETURN std_ulogic_vector;
FUNCTION To_X01 ( s : std_logic_vector ) RETURN std_logic_vector;
FUNCTION To_X01 ( s : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION To_X01 ( s : std_ulogic ) RETURN X01;
FUNCTION To_X01 ( b : BIT_VECTOR ) RETURN std_logic_vector;
FUNCTION To_X01 ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
FUNCTION To_X01 ( b : BIT ) RETURN X01;
FUNCTION To_X01Z ( s : std_logic_vector ) RETURN std_logic_vector;
FUNCTION To_X01Z ( s : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION To_X01Z ( s : std_ulogic ) RETURN X01Z;
FUNCTION To_X01Z ( b : BIT_VECTOR ) RETURN std_logic_vector;
FUNCTION To_X01Z ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
FUNCTION To_X01Z ( b : BIT ) RETURN X01Z;
FUNCTION To_UX01 ( s : std_logic_vector ) RETURN std_logic_vector;
FUNCTION To_UX01 ( s : std_ulogic_vector ) RETURN std_ulogic_vector;
FUNCTION To_UX01 ( s : std_ulogic ) RETURN UX01;
FUNCTION To_UX01 ( b : BIT_VECTOR ) RETURN std_logic_vector;
FUNCTION To_UX01 ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
FUNCTION To_UX01 ( b : BIT ) RETURN UX01;

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

TYPE SIGNED IS ARRAY (Natural RANGE <>) OF STD_LOGIC ;


TYPE UNSIGNED IS ARRAY (Natural RANGE <>) OF STD_LOGIC ;
FUNCTION std_ulogic_wired_or ( input : std_ulogic_vector ) RETURN std_ulogic;
FUNCTION std_ulogic_wired_and ( input : std_ulogic_vector ) RETURN std_ulogic;
FUNCTION to_integer ( arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
FUNCTION to_integer ( arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
FUNCTION to_integer ( arg1 : STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL;
FUNCTION to_integer ( arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL;
FUNCTION to_integer ( arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER;
FUNCTION conv_integer ( arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
FUNCTION conv_integer ( arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
FUNCTION conv_integer ( arg1 : STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL;
FUNCTION conv_integer ( arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL;
FUNCTION conv_integer ( arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER;
FUNCTION to_stdlogic ( arg1 : BOOLEAN ) RETURN STD_LOGIC;
FUNCTION to_stdlogicvector ( arg1 : INTEGER; size : NATURAL ) RETURN STD_LOGIC_VECTOR;
FUNCTION to_stdulogicvector ( arg1 : INTEGER; size : NATURAL ) RETURN STD_ULOGIC_VECTOR;
FUNCTION to_unsigned ( arg1 : NATURAL; size : NATURAL ) RETURN UNSIGNED;
FUNCTION conv_unsigned ( arg1 : NATURAL; size : NATURAL ) RETURN UNSIGNED;
FUNCTION to_signed ( arg1 : INTEGER; size : NATURAL ) RETURN SIGNED;
FUNCTION conv_signed ( arg1 : INTEGER; size : NATURAL ) RETURN SIGNED;
FUNCTION zero_extend ( arg1 : STD_ULOGIC_VECTOR; size : NATURAL )
RETURN STD_ULOGIC_VECTOR;
FUNCTION zero_extend ( arg1 : STD_LOGIC_VECTOR; size : NATURAL )
RETURN STD_LOGIC_VECTOR;
FUNCTION zero_extend ( arg1 : STD_LOGIC; size : NATURAL ) RETURN STD_LOGIC_VECTOR;
FUNCTION zero_extend ( arg1 : UNSIGNED; size : NATURAL ) RETURN UNSIGNED;
FUNCTION sign_extend ( arg1 : SIGNED; size : NATURAL ) RETURN SIGNED;
FUNCTION "+" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC;
FUNCTION "+" ( arg1, arg2 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "+" ( arg1, arg2 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "+" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED ;
FUNCTION "+" ( arg1, arg2 : SIGNED ) RETURN SIGNED ;
FUNCTION "-" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC;
FUNCTION "-" ( arg1, arg2 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "-" ( arg1, arg2 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "-" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED;
FUNCTION "-" ( arg1, arg2 : SIGNED ) RETURN SIGNED;
FUNCTION "+" ( arg1 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "+" ( arg1 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "+" ( arg1 : UNSIGNED ) RETURN UNSIGNED;
FUNCTION "+" ( arg1 : SIGNED ) RETURN SIGNED;
FUNCTION "-" ( arg1 : SIGNED ) RETURN SIGNED;
FUNCTION "*" ( arg1, arg2 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "*" ( arg1, arg2 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "*" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED ;
FUNCTION "*" ( arg1, arg2 : SIGNED ) RETURN SIGNED ;
FUNCTION "abs" ( arg1 : SIGNED) RETURN SIGNED;
FUNCTION "/" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
FUNCTION "/" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
FUNCTION "/" ( l, r : UNSIGNED ) RETURN UNSIGNED;
FUNCTION "/" ( l, r : SIGNED ) RETURN SIGNED;

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;

Paquetage pour la synthèse logique


IEEE.NUMERIC_STD (implémente les mêmes fonctions que le paquetage suivant
mais avec une autre définition des types SIGNED et UNSIGNED)
constant CopyRightNotice: STRING:= "Copyright 1995 IEEE. All rights reserved.";
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;

Paquetage pour la synthèse logique


IEEE.NUMERIC_BIT

constant CopyRightNotice: STRING:= "Copyright 1995 IEEE. All rights reserved.";


type UNSIGNED is array (NATURAL range <> ) of BIT;
type SIGNED is array (NATURAL range <> ) of BIT;
function "abs" (ARG: SIGNED) return SIGNED;
function "-" (ARG: SIGNED) return SIGNED;
function "+" (L, R: UNSIGNED) return UNSIGNED;
function "+" (L, R: SIGNED) return SIGNED;
function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "+" (L: INTEGER; R: SIGNED) return SIGNED;
function "+" (L: SIGNED; R: INTEGER) return SIGNED;
function "-" (L, R: UNSIGNED) return UNSIGNED;
function "-" (L, R: SIGNED) return SIGNED;
function "-" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "-" (L: SIGNED; R: INTEGER) return SIGNED;
function "-" (L: INTEGER; R: SIGNED) return SIGNED;
function "*" (L, R: UNSIGNED) return UNSIGNED;
function "*" (L, R: SIGNED) return SIGNED;
function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "*" (L: SIGNED; R: INTEGER) return SIGNED;
function "*" (L: INTEGER; R: SIGNED) return SIGNED;
function "/" (L, R: UNSIGNED) return UNSIGNED;
function "/" (L, R: SIGNED) return SIGNED;
function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "/" (L: SIGNED; R: INTEGER) return SIGNED;
function "/" (L: INTEGER; R: SIGNED) return SIGNED;
function "rem" (L, R: UNSIGNED) return UNSIGNED;
function "rem" (L, R: SIGNED) return SIGNED;
function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "rem" (L: SIGNED; R: INTEGER) return SIGNED;
function "rem" (L: INTEGER; R: SIGNED) return SIGNED;
function "mod" (L, R: UNSIGNED) return UNSIGNED;
function "mod" (L, R: SIGNED) return SIGNED;

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

constant MATH_E : real := 2.71828_18284_59045_23536;


constant MATH_1_E: real := 0.36787_94411_71442_32160;
constant MATH_PI : real := 3.14159_26535_89793_23846;
constant MATH_1_PI : real := 0.31830_98861_83790_67154;
constant MATH_LOG_OF_2: real := 0.69314_71805_59945_30942;
constant MATH_LOG_OF_10: real := 2.30258_50929_94045_68402;
constant MATH_LOG2_OF_E: real := 1.44269_50408_88963_4074;
constant MATH_LOG10_OF_E: real := 0.43429_44819_03251_82765;
constant MATH_SQRT2: real := 1.41421_35623_73095_04880;
constant MATH_SQRT1_2: real := 0.70710_67811_86547_52440;
constant MATH_SQRT_PI: real := 1.77245_38509_05516_02730;
constant MATH_DEG_TO_RAD: real := 0.01745_32925_19943_29577;
constant MATH_RAD_TO_DEG: real := 57.29577_95130_82320_87685;
attribute FOREIGN : string;
function SIGN (X: real ) return real;
function CEIL (X : real ) return real;
function FLOOR (X : real ) return real;
function ROUND (X : real ) return real;
function FMAX (X, Y : real ) return real;
function FMIN (X, Y : real ) return real;
procedure UNIFORM (variable Seed1,Seed2:inout integer; variable X:out real);
function SRAND (seed: in integer ) return integer;
attribute FOREIGN of SRAND : function is "C_NATIVE";
function RAND return integer;
attribute FOREIGN of RAND : function is "C_NATIVE";
function GET_RAND_MAX return integer;
attribute FOREIGN of GET_RAND_MAX : function is "C_NATIVE";
function SQRT (X : real ) return real;
function CBRT (X : real ) return real;
function "**" (X : integer; Y : real) return real;
function "**" (X : real; Y : real) return real;
function EXP (X : real ) return real;
function LOG (X : real ) return real;
function LOG (BASE: positive; X : real) return real;
function SIN (X : real ) return real;
function COS ( X : real ) return real;
function TAN (X : real ) return real;
function ASIN (X : real ) return real;
function ACOS (X : real ) return 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

constant physical_Q:real := 1.602_177_33e-19;


constant physical_C:real := 2.997_924_58e8;
constant physical_K:real := 1.380_658e-23;
constant physical_H:real := 6.626_075_5e-34;
constant physical_epsilon0:real := 8.854_187_817e-12;
constant physical_mu0:real := 4.0e-7 * ieee.math_real.math_pi;
constant physical_celsius0:real := 273.15;
attribute symbol: string;

DISCIPLINES.ELECTROMAGNETIC_SYSTEM

subtype current is real tolerance "default_current";


attribute symbol of current:subtype is "A";
subtype charge is real tolerance "default_charge";
attribute symbol of charge:subtype is "C";
subtype emf is real tolerance "default_emf";
attribute symbol of emf:subtype is "V";
subtype flux is real tolerance "default_flux";
attribute symbol of flux:subtype is "Wb";
subtype mmf is real tolerance "default_mmf";
attribute symbol of mmf:subtype is "A*turn";
nature electrical is emf across current through electrical_ground reference;
nature magnetic is mmf across flux through magnetic_ground reference;

DISCIPLINES.THERMAL_SYSTEM

subtype temperature is real tolerance "default_temperature";


attribute symbol of temperature:subtype is "K";
subtype thermal_power is real tolerance "default_thermal_power";
attribute symbol of thermal_power:subtype is "W";
nature thermal is temperature across thermal_power through thermal_ground reference;

DISCIPLINES.KINEMATIC_SYSTEM

subtype displacement is real tolerance "default_displacement";


attribute symbol of displacement:subtype is "m";
subtype velocity is real tolerance "default_velocity";
attribute symbol of velocity:subtype is "m/s";
subtype acceleration is real tolerance "default_acceleration";
attribute symbol of acceleration:subtype is "m/s**2";
subtype impulse is real tolerance "default_impulse";
attribute symbol of impulse:subtype is "m/s**3";
subtype force is real tolerance "default_force";
attribute symbol of force:subtype is "N";
nature kinematic is displacement across force through kinematic_ground reference;
nature kinematic_v is velocity across force through kinematic_v_ground reference;

135
DISCIPLINES.ROTATIONAL_SYSTEM

subtype angle is real tolerance "default_angle";


attribute symbol of angle:subtype is "rad";
subtype angular_velocity is real tolerance "default_angular_velocity";
attribute symbol of angular_velocity:subtype is "rad/s";
subtype angular_acceleration is real tolerance "default_angular_acceleration";
attribute symbol of angular_acceleration:subtype is "rad/s**2";
subtype angular_force is real tolerance "default_angular_force";
attribute symbol of angular_force:subtype is "N/m";
nature rotational is angle across angular_force through rotational_ground reference;
nature rotational_omega is angular_velocity across angular_force through
rotational_omega_ground reference;

DISCIPLINES.FLUIDIC_SYSTEM

subtype pressure is real tolerance "default_pressure";


attribute symbol of pressure:subtype is "Pa";
subtype flow is real tolerance "default_flow";
attribute symbol of flow:subtype is "m**3/s";
nature fluidic is pressure across flow through fluidic_ground reference;

136
Le corps du paquetage du problème des N-CORPS

Package body N_corps_pak is

-- Calcule la masse totale


function sigma(a:real_vector) return real is
variable b:real := 0.0;
begin
for i in a'range loop
b := b + a(i);
end loop;
return b;
end ;

function "*"(a:Real_vector,b:V_Vector_3D) return Vector_3D is


variable loc_v:Vector_3D;
begin
for i in a'range loop
loc_v(i).X := a(i) * b(i).X;
loc_v(i).Y := a(i) * b(i).Y;
loc_v(i).Z := a(i) * b(i).Z;
end loop;
return lov_c;
end;

function "+"(a:V_Vector_3D,b:V_Vector_3D) return V_Vector_3D is


variable loc_v:V_Vector_3D(b'range);
begin
for i in a'range loop
loc_v(i).X := a(i).X + b(i).X;
loc_v(i).Y := a(i).Y + b(i).Y;
loc_v(i).Z := a(i).Z + b(i).Z;
end loop;
return lov_c;
end;

function "*"(a:real, b:real_vector) return real_Vector is


variable loc_v:real_vector(b'range);
begin
for i in b'range loop
loc_v(i) := a * b(i);
return loc_v;
end;

function "/"(a:real_vector, b:real) return real_Vector is


variable loc_v:real_vector(a'range);
begin
for i in b'range loop
loc_v(i) := a(i) / b;
return loc_v;
end;

function "*"(a:real_vector, b:real_vector) return real_Vector is


variable loc_v:real_vector(b'range);
begin
for i in b'range loop
loc_v(i) := a(i) * b(i);
return loc_v;

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;

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;

function "/"(a:Vector_3D,b:real) return Vector_3D is


variable loc_v:Vector_3D(a'range);
begin
loc_v.X := a.X / b;
loc_v.Y := a.Y / b;
loc_v.Z := a.Z / b;
return loc_v;
end;

function "*"(a:real, b:Vector_3D) return Vector_3D is


variable loc_v:Vector_3D(b'range);
begin
loc_v.X := a * b.X;
loc_v.Y := a * b.Y;
loc_v.Z := a * b.Z;
return loc_v;
end;

-- la fonction calcule le centre de gravité total


-- et pour chaque cortps : la masse influente
-- Pour chaque corps : le centre de gravité de l'amas influent
-- sa distance et le veceur direction objet amas
-- Le module de la force
-- Sa projection sur la direction

function force(M_T:real, Mass:real_vector, Loc:V_Vector_3D)


return V_vector_3D;
Constant G:real := 6.67E-11; -- Constante gravitationnelle
variable F_mod:real_vector(1 to N); -- module de la force
-- force appliquée, position de l'amas influent
variable F_loc, pos_amas, Dir_amas : V_Vector_3D;
-- distance à l'amas, masse de l'amas
variable Dist, Mass_amas : real_vector(1 to N);
-- position centre de gravité total
variable pos_grav_T : vector_3D := (0.0, 0.0, 0.0);
begin
-- calcul de la position du centre
-- de gravité total multiplié par M_T
-- et de la masse de l'amas influençant M(I)

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

-- POUR CHAQUE CORPS :


-- Calcul du centre de gravité de l'amas influent
-- Calcul de la distance à l'amas influent
-- Calcul du vecteur direction à l'amas

for i in Mass'range loop


Pos_amas(i) := (Pos_grav_T - M(i) * Loc(i))/
Mass_amas(I);
Dist(i) := sqr((loc(i).X-pos_amas(i).x)**2+(loc(i).y-
pos_amas(i).y)**2+(loc(i).z-pos_amas(i).z)**2)
Dir_amas(i) := (Pos_amas(i) - Loc(i)) / Dist(i);
end loop;

-- calcul du module de la force


F_mod := G * ( Mass_amas * Mass ) / Dist ** 2;

-- Projection de la force sur la direction


F_loc := F_mod * Dir;

return F_loc;
end;

end package body ;

139

Vous aimerez peut-être aussi