Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parGosse Larue Modifié depuis plus de 10 années
1
Le VHDL : SOMMAIRE I Introduction II Éléments généraux du langage
III Architecture du langage IV Exemples d’application
2
I INTRODUCTION
3
Le VHDL De nos jours, les circuits numériques de haute performance sont habituellement créés à partir de descriptions en langages de haut niveau. Nous allons maintenant parler de l’un de ces langages, le VHDL
4
Le VHDL: Qu’est-ce que c’est, et à quoi cela sert-il?
VHDL: VHSIC Hardware Description Language VHSIC: Very High Speed Integrated Circuit (projet de grande envergure du DoD (Departement of Defense) Américain, mis en place dans les années ’80 Principe de base: Définir un langage de description de matériel qui puisse être utilisé pour simuler du matériel numérique Extension: Utilisation du même langage pour la synthèse automatique de circuits
5
VHDL: Est-ce le seul HDL?
Il existe plusieurs autres langages de description de matériel, entre autres: Verilog (Très populaire aux États-Unis, utilisé aussi en Europe, au Japon et au Canada) UDL/1 (Utilisé à un certain moment au Japon) Estérel (langage académique – Français) HardwareC (langage académique – Stanford) Verilog est plus simple que le VHDL, mais est un peu moins utilisé
6
Pourquoi utiliser des langages HDL?
Pour accélérer la conception de circuits (raisons économiques) Pour permettre la conception de circuits très complexes (1 milliard de portes logiques d’ici 5 ans) Pour pouvoir représenter les systèmes numériques selon différents axes d’abstraction Pour utiliser et/ou améliorer le code pour des systèmes futures
7
II ELEMENTS GENERAUX DU LANGAGE
8
I LES CLASSES D’OBJETS Le langage vhdl comporte quatre classes d’objets utilisés dans les zones de déclaration des programmes: Les signaux Les variables Les constantes Les fichiers (ne sont pas synthétisables)
9
II NOTION DE SIGNAL Un signal correspond à la
b a s3 z Temps (ns) s4 Un signal correspond à la représentation matérielle du support de l’information en VHDL. L’affectation de signal (a <= ‘0’) permet de faire évoluer au cours du temps les valeurs présentes sur le signal.
10
Exemple d’affectation de signal (utile pour la simulation)
b a s3 z Temps (ns) s4 a<=1 after 4ns,0 after 8ns,1 after 12ns; Attention : Les expressions doivent être ordonnées selon un ordre croissant des délais. Exercice : Écrire b, S1, S2 ,z.
11
Propriétés des signaux
Chaque signal a trois propriétés : son type, sa valeur et sa valeur antérieure. Les signaux sont déclarés dans les entités et la partie déclarative des architectures. Attention, on ne peut pas les déclarer dans un process Les signaux ne reçoivent leur assignation définitive que lorsque le process a fini son exécution.
12
III Les variables Les variables se déclarent dans le domaine séquentiel d’un PROCESS, d’une PROCEDURE ou d’une FONCTION. On peut leur donner une valeur initiale. Cette valeur initiale est attribuée à chaque appel de la PROCEDURE ou de la FONCTION. Elles servent à manipuler des variables temporaires/intermédiaires pour faciliter le développement d'un algorithme séquentiel. Une affectation de variable est immédiate dans un process. Syntaxe : VARIABLE var_name {, var_name} : type [:= value]; Exemple : VARIABLE i : INTEGER RANGE 0 TO 3; -- valeur intiale 0 VARIABLE x : std_ulogic; -- valeur intiale 'U' Assignation de variable: i:=3; x:=0;
14
IV Les constantes Les constantes sont utilisées pour référencer une valeur ou un type spécifique. Elles permettent une meilleur lecture et maintenance d'une source. De tous types, elles sont utilisées dans les architectures ou les package. Syntaxe CONSTANT const_name {, const_name} : type := value; Exemple constant BUS_WIDTH : integer := 8;
15
V La déclaration Generic
La section GENERIC_DECLARATIONS dans l'entête ENTITY permet de définir des paramètres exploitables dans l'architecture. Cette méthode d'écriture permet une maintenance plus aisée. Exemple ENTITY entity_name IS GENERIC(TP : time := 30ns); Port( déclarations); END [entity_name];
16
VII TYPAGE DES OBJETS Le typage des objets permet en premier lieu de
protéger les affectations d’objets en restreignant les possibilités d’affectations aux objets de même type.
17
1 Les TYPES prédéfinis Les types prédéfinis reconnaissent six objets scalaires ayant une valeur unique à chaque instant: Std_logic : représente un élément binaire avec les valeurs '0' , '1' et ‘Z’ (haute impédance); Std_logic_vector : représente un tableau d'éléments binaires ; Boolean : représente une donnée pouvant être TRUE ou FALSE ; Integer : est un entier pouvant aller de –2E32 à (2E32-1), pouvant être comprise entre 2 valeurs limites par la déclaration : integer range mini to maxi. Character : représente un caractère ASCII;
18
2 Le TYPE énuméré (Machine à états)
TYPE permet de définir un type utilisateur auquel on peut assigner un objet. Tous les objets doivent être assignés à un type. Chaque TYPE déclaré doit être unique. Syntaxe TYPE identifier IS (enumeration_type_literals); Exemple TYPE couleur IS (rouge, orange,vert); TYPE op_type IS (opadd, opor, opand, opxor); Il devient alors possible d’utiliser un signal de ce type en le déclarant par : Signal feu1, feu2 : couleur;
19
3 Le TYPE tableau Le type tableau est un groupement de types identiques. Les tableaux peuvent être multidimentionels. Il existe deux sortes de tableaux : Les tableaux avec contrainte (Constrained Array) Ces tableaux sont définis avec des dimensions figées (rangées colonnes). Les tableaux sans contrainte (Unconstrained Array) Ces tableaux sont définis sans préciser les dimensions. Le tableau est donc dynamique. Syntaxe TYPE identifier IS ARRAY [unconstrained_array_definition]; [constrained_array_definition]; Exemple TYPE data_bus IS ARRAY (0 to 31) OF bit; -- tableau de 32 bit TYPE 4x8 IS ARRAY (3 downto 0) OF std_logic_vector (7 downto 0); --tableau de 4 mots de 8 bits TYPE string IS ARRAY (positive RANGE <>) OF character; TYPE bit_vector IS ARRAY (natural RANGE <>) OF bit; TYPE dim2 IS ARRAY (0 TO 7, 0 TO 7) OF bit; -- tableau à deux dimensions
20
4 Le TYPE physique Cette définition de type représente une quantité physique. La base des unités doit être spécifiée. Les valeurs sont calculées à partir de cette base. Syntaxe TYPE identifier IS RANGE implementation_defined; UNITS base_unit_declaration [secondary_unit_declaration] END UNITS; Exemple TYPE time IS RANGE implementation_defined; fs; ps = 1000fs; ns = 1000ps; us = 1000ns; ms = 1000us; sec = 1000ms; min = 60sec; hr = 60min;
21
5 Le TYPE fichier Pour écrire et/ou lire dans un fichier externe, il faut : Insérer la bibliothèque textio : Library std; Use std.textio.all; Déclarer le fichier en précisant son type et le mode d’ouverture (entrée et/ou sortie) : File FILE_R : text is in ’’données.dat’’; File FILE_W : text is out ’’résultats.dat’’; Déclarer une variable ligne de type LINE : Variable L : LINE; Pour lire une ligne dans le fichier, il faut d'abord lire la ligne dans le fichier puis lire la valeur d'une variable R dans la ligne (la valeur lue est convertie automatiquement dans le type de la variable R) : readline(FILE_R, L); read(L, R); Pour écrire, c'est le même procédé, sauf qu'on écrit d'abord la valeur R dans la ligne, puis la ligne dans le fichier : write (L, R); writeline(FILE_W, L); Il existe une fonction endfile(…) qui retourne vrai lorsque le fichier est terminé, et faux sinon. Pour stopper le test_bench, on peut envoyer un message du type : assert FALSE report "fin de fichier" severity failure
22
6 Le TYPE pointeur Ils ne sont pas synthétisables du fait de leur caractère dynamique. Ils sont strictement réservés au domaine fréquentiel, et peuvent être associés soit à une constante soit à une variable, mais pas aux signaux. Syntaxe : TYPE pointeur IS ACCESS typeobjet; Exemple: Variable pt : pointeur; Pt := NEW typeobjet; -- allocation dynamique d’un objet en mémoire. La libération du pointeur se fait avec deallocate(pt)
23
7 Le TYPE structure Les structures permettent de regrouper un ou plusieurs champs de type différents et fournissent un accès au champ par leur nom. Un type record peut être associé à une variable comme à un signal. Exemple: TYPE data IS RECORD Bus1,bus2 : bit; durée : time; Données : integer range 0 to 255; End record; Signal enregistrement1 : data; Enregistrement1.bus1<=‘1’; Enregistrement1 <= (‘0’,’1’,durée,données);
24
8 Les sous-type :SUBTYPE
SUBTYPE est une restriction d’un type à un sous domaine de ce type. Exemple TYPE colors IS (red, yellow, blue, green, black); SUBTYPE primary IS colors RANGE red TO blue; TYPE integer IS RANGE TO ; SUBTYPE absolu IS integer 0 TO ; TYPE area IS ARRAY (natural RANGE <>, natural RANGE <>) OF bit; SUBTYPE small_area IS area (0 TO 10, 0 TO 10);
25
III ARCHITECTURE DU LANGAGE
26
III) Structure d’une description VHDL simple.
Une description VHDL est composée de 2 parties indissociables à savoir : - L’entité (ENTITY), elle définit les entrées et sorties. - L’architecture (ARCHITECTURE), elle contient les instructions VHDL permettant de réaliser le fonctionnement attendu.
27
III.1) Déclaration des bibliothèques.
Toute description VHDL utilisée pour la synthèse a besoin de bibliothèques. L’IEEE (Institut of Electrical and Electronics Engineers) les a normalisées et plus particulièrement la bibliothèque IEEE1164. Elles contiennent les définitions des types de signaux électroniques, des fonctions et sous programmes permettant de réaliser des opérations arithmétiques et logiques,... Library ieee; Use ieee.std_logic_1164.all; Use ieee.numeric_std.all; Use ieee.std_logic_unsigned.all; La directive Use permet de sélectionner les bibliothèques à utiliser.
28
III.2) Déclaration de l’entité et des entrées / sorties (I/O).
Elle permet de définir le NOM de la description VHDL ainsi que les entrées et sorties utilisées, l’instruction qui les définit c’est port : Syntaxe: entity NOM_DE_L_ENTITE is port ( Description des signaux d’entrées /sorties …); end NOM_DE_L_ENTITE; Exemple : entity SEQUENCEMENT is port ( CLOCK : in std_logic; RESET : in std_logic; Q : out std_logic_vector(1 downto 0) ); end SEQUENCEMENT; Remarque : Après la dernière définition de signal de l’instruction port il ne faut jamais mettre de point virgule. L’instruction port . Syntaxe: NOM_DU_SIGNAL : sens type; Exemple: CLOCK: in std_logic; BUS : out std_logic_vector(7 downto 0); On doit définir pour chaque signal : le NOM_DU_SIGNAL, le sens et le type.
29
III.2.1) Le NOM et le SENS du SIGNAL.
Le NOM du signal. Il est composé de caractères, le premier caractère doit être une lettre, sa longueur est quelconque, mais elle ne doit pas dépasser une ligne de code. VHDL n’est pas sensible à la « casse », c’est à dire qu’il ne fait pas la distinction entre les majuscules et les minuscules. Le SENS du signal. - in : pour un signal en entrée. - out : pour un signal en sortie. - inout : pour un signal en entrée sortie - buffer : pour un signal en sortie mais utilisé comme entrée dans la description.
30
III.3) Déclaration de l’architecture correspondante à l’entité : description du fonctionnement.
L’architecture décrit le fonctionnement souhaité pour un circuit ou une partie du circuit. En effet le fonctionnement d’un circuit est généralement décrit par plusieurs modulesVHDL. Il faut comprendre par module le couple ENTITE/ARCHITECTURE. Dans le cas de simples PLDs on trouve souvent un seul module. L’architecture établit à travers les instructions les relations entre les entrées et les sorties. On peut avoir un fonctionnement purement combinatoire, séquentiel voire les deux séquentiel et combinatoire. Exemples : -- Opérateurs logiques de base entity PORTES is port (A,B :in std_logic; Y1,Y2,Y3,Y4,Y5,Y6,Y7:out std_logic); end PORTES; architecture DESCRIPTION of PORTES is begin Y1 <= A and B; Y2 <= A or B; Y3 <= A xor B; Y4 <= not A; Y5 <= A nand B; Y6 <= A nor B; Y7 <= not(A xor B); end DESCRIPTION;
31
IV) Les instructions de base (mode « concurrent »), logique combinatoire.
Qu’est ce que le mode « concurrent » ? Pour une description VHDL toutes les instructions sont évaluées et affectent les signaux de sortie en même temps. L’ordre dans lequel elles sont écrites n’a aucune importance. En effet la description génère des structures électroniques, c’est la grande différence entre une description VHDL et un langage informatique classique. Dans un système à microprocesseur, les instructions sont exécutées les unes à la suite des autres. Avec VHDL il faut essayer de penser à la structure qui va être générée par le synthétiseur pour écrire une bonne description, cela n’est pas toujours évident.
32
Exemple : Pour le décodeur 2 vers 4 de la page 5, l’ordre dans lequel seront écrites
les instructions n’a aucune importance. architecture DESCRIPTION of DEMUX2_4 is begin D0 <= (not(IN1) and not(IN0)); -- première instruction D1 <= (not(IN1) and IN0); -- deuxième instruction D2 <= (IN1 and not(IN0)); -- troisième instruction D3 <= (IN1 and IN0); -- quatrième instruction end DESCRIPTION; L’architecture ci dessous est équivalente : D0 <= (not(IN1) AND not(IN0)); -- première instruction D3 <= (IN1 AND IN0); -- quatrième instruction
33
IV.1) Les opérateurs. IV.1.1) L’affectation simple : <=
Dans une description VHDL, c’est certainement l’opérateur le plus utilisé. En effet il permet de modifier l’état d’un signal en fonction d’autres signaux et/ou d’autres opérateurs. Exemple avec des portes logiques : S1 <= E2 and E1 ; Les valeurs numériques que l’on peut affecter à un signal sont les suivantes : - ‘1’ ou ‘H’ pour un niveau haut avec un signal de 1 bit. - ‘0’ ou ‘L’ pour un niveau bas avec un signal de 1 bit. - ‘Z’ pour un état haute impédance avec un signal de 1 bit. ‘-’ pour un état quelconque, c’est à dire ‘0’ ou ‘1’. Cette valeur est très utilisée avec les instructions : when … else et with …. Select …. - Pour les signaux composés de plusieurs bits on utilise les guillemets " … " , voir les exemples ci dessous : - Les bases numériques utilisées pour les bus peuvent être : BINAIRE, exemple : BUS <= "1001" ; -- BUS = 9 en décimal HEXA, exemple : BUS <= X"9" ; -- BUS = 9 en décimal OCTAL, exemple : BUS <= O"11" ; -- BUS = 9 en décimal Remarque : La base décimale ne peut pas être utilisée lors de l’affectation de signaux. On peut seulement l’utiliser avec certains opérateurs, comme + et – pour réaliser des compteurs
34
Exemple: Library ieee; Use ieee.std_logic_1164.all; entity AFFEC is port ( E1,E2 : in std_logic; BUS1,BUS2,BUS3 : out std_logic_vector(3 downto 0); S1,S2,S3,S4 : out std_logic); end AFFEC; architecture DESCRIPTION of AFFEC is begin S1 <= '1'; -- S1 = 1 S2 <= '0'; -- S2 = 0 S3 <= E1; -- S3 = E1 S4 <= '1' when (E2 ='1') else 'Z'; -- S4 = 1 si E1=1 sinon S4 prend la valeur haute impédance BUS1 <= "1000"; -- BUS1 = "1000" BUS2 <= E1 & E2 & "10"; -- BUS2 = E1 & E2 & 10 BUS3 <= x"A"; -- valeur en HEXA -> BUS3 = 10(déc) end DESCRIPTION;
35
IV.1.2) Opérateur de concaténation : &.
Cet opérateur permet de joindre des signaux entre eux . Exemple : -- Soit A et B de type 3 bits et S1 de type 8 bits -- A = "001" et B ="110" S1 <= A & B & "01" ; -- S1 prendra la valeur suivante après cette affectation -- S1 = " " IV.1.3) Opérateurs logiques. Exemples : S1 <= A sll 2 ; -- S1 = A décalé de 2 bits à gauche. S2 <= A rol 3 ; -- S2 = A avec une rotation de 3 bits à gauche S3 <= not (R); -- S3 = R Remarque : Pour réaliser des décalages logiques en synthèse logique, il est préférable d’utiliser les instructions suivantes : Décalage à droite : -- Si A est de type std_logic_vector(7 downto 0) S1 <= ‘0’ & A(7 downto 1); -- décalage d’un bit à droite S1 <= "000" & A(7 downto 3); -- décalage de trois bits à droite Décalage à gauche : S1 <= A(6 downto 0) & ‘0’; -- décalage d’un bit à gauche S1 <= A(4 downto 0) & "000"; -- décalage de trois bits à gauche Valeur de A Valeur de B "001“ "110“
36
IV.1.4) Opérateurs arithmétiques.
Remarque N°1 : Pour pouvoir utiliser les opérateurs ci-dessus il faut rajouter les bibliothèques suivantes au début du fichier VHDL: Use ieee.numeric_std.all ; Use ieee.std_logic_arith.all ; Exemples : S1 <= A – 3 ; -- S1 = A – 3 -- On soustrait 3 à la valeur de l’entrée / signal A S1 <= S1 + 1 ; -- On incrémente de 1 le signal S1 Remarque N°2 : Attention l’utilisation de ces opérateurs avec des signaux comportant un nombre de bits important peut générer de grandes structures électroniques. S1 <= A * B ;-- S1 = A multiplié par B : A et B sont codés sur 4 bits S2 <= A / B ;-- S2 = A divisé par B : A et B sont codés sur 4 bits
37
VI.1.5) Opérateurs relationnels.
Ils permettent de modifier l’état d’un signal ou de signaux suivant le résultat d’un test ou d’une condition. En logique combinatoire ils sont souvent utilisés avec les instructions : - when … else … - with …. Select ….
38
IV.2) Les instructions du mode « concurrent ».
IV.2.1) Affectation conditionnelle : Cette instruction modifie l’état d’un signal suivant le résultat d’une condition logique entre un ou des signaux, valeurs, constantes. SIGNAL <= expression when condition [else expression when condition] [else expression]; Remarque : l’instruction [else expression] n’est pas obligatoire mais elle fortement conseillée, elle permet de définir la valeur du SIGNAL dans le cas où la condition n’est pas remplie. Exemple N°1 : -- S1 prend la valeur de E2 quand E1=’1’ sinon S1 prend la -- valeur ‘0’ S1 <= E2 when ( E1= ‘1’) else ‘0’; Schéma correspondant :
39
Exemple N°2 : -- Structure évoluée d’un multiplexeur 4 vers 1 S2 <= E1 when (SEL="00" ) else E2 when (SEL="01" ) else E3 when (SEL="10" ) else E4 when (SEL="11" ) else ‘0’;
40
Exemple de systèmes : additionneur 1-bit
In1 Demi-additionneur HA1 Demi-additionneur HA2 In2 s2 C_in Demi-additionneur Somme s3 C_out OR1
41
Exemple d’architecture du demi-additionneur
library IEEE; use IEEE.std_logic_1164.all; entity demi_add is port(a, b: in bit; som, ret: out bit); end demi_add; architecture comportement_concurrent of demi_add is begin som <= (a xor b) ; ret <= (a and b) ; end comportement_concurrent;
42
IV.2.2) Affectation sélective :
Cette instruction permet d’affecter différentes valeurs à un signal, selon les valeurs prises par un signal dit de sélection. with SIGNAL_DE_SELECTION select SIGNAL <= expression when valeur_de_selection, [expression when valeur_de_selection,] [expression when others]; Remarque: l’instruction [expression when others] n’est pas obligatoire mais fortement conseillée, elle permet de définir la valeur du SIGNAL dans le cas où la condition n’est pas remplie. Exemple N°1 : -- Multiplexeur 4 vers 1 with SEL select S2 <= E1 when "00", E2 when "01", E3 when "10", E4 when "11", '0' when others; Remarque: when others est nécessaire car il faut toujours définir les autres cas du signal de sélection pour prendre en compte toutes les valeurs possibles de celui-ci.
43
Schéma correspondant après synthèse:
En conclusion, les descriptions précédentes donnent le même schéma, ce qui est rassurant. L’étude des deux instructions montre toute la puissance du langage VHDL pour décrire un circuit électronique, en effet si on avait été obligé d’écrire les équations avec des opérateurs de base pour chaque sortie, on aurait eu les instructions suivantes : S2 <= (E1 and not(SEL(1)) and not(SEL(0))) or (E2 and not SEL(1) and (SEL(0)) or (E3 and SEL(1) and not(SEL(0))) or (E4 and SEL(1) and SEL(0)); L’équation logique ci-dessus donne aussi le même schéma, mais elle est peu compréhensible, c’est pourquoi on préfère des descriptions de plus haut niveau en utilisant les instructions VHDL évoluées.
44
Exemple : mémoire morte
library IEEE; use IEEE.std_logic_1164.all; entity memoire_morte is port (addr : in std_logic_vector (2 downto 0); reg0, reg1, reg2, reg3,reg4 :in std_logic_vector (31 downto 0); mem1: out std_logic_vector (31 downto 0)); end memoire_morte; architecture comportemental of memoire_morte is begin with addr1 select mem1 <= reg0 when ‘‘000’’, reg1 when ‘‘001’’, reg2 when ‘‘010’’, reg3 when ‘‘011’’, reg4 when others; end comportemental;
45
V) Les instructions du mode séquentiel.
V.1) Définition d’un PROCESS. Un process est une partie de la description d’un circuit dans laquelle les instructions sont exécutées séquentiellement c’est à dire les unes à la suite des autres. Il permet d’effectuer des opérations sur les signaux en utilisant les instructions standard de la programmation structurée comme dans les systèmes à microprocesseurs. L’exécution d’un process est déclenchée par un ou des changements d’états de signaux logiques. Le nom de ces signaux est défini dans la liste de sensibilité lors de la déclaration du process. [Nom_du_process :] process(Liste_de_sensibilité_nom_des_signaux) Begin -- instructions du process end process [Nom_du_process] ; Remarque: Le nom du process entre crochet est facultatif, mais il peut être très utile pour repérer un process parmi d’autres lors de phases de mise au point ou de simulations.
46
Règles de fonctionnement d’un process :
1) L’exécution d’un process a lieu à chaque changement d’état d’un signal de la liste de sensibilité. 2) Les instructions du process s’exécutent séquentiellement. 3) Les changements d’état des signaux par les instructions du process sont pris en compte à la fin du process.
47
Les processus: exemple d’un compteur simple de 8 bits
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; ENTITY compt IS PORT ( h: IN STD_LOGIC; q: OUT INTEGER RANGE 0 TO 7 ); END compt; ARCHITECTURE archi OF compt IS SIGNAL test: INTEGER RANGE 0 TO 7; BEGIN PROCESS WAIT UNTIL h='1'; test <= test+ 1; END PROCESS; q <= test; END archi;
48
V.2) Les deux principales structures utilisées dans un process.
L’assignation conditionnelle if condition then instructions [elsif condition then instructions] [else instructions] end if ; Exemple: if (RESET=’1’) then SORTIE <= ”0000”; L’assignation sélective case signal_de_slection is when valeur_de_sélection => instructions [when others => instructions] end case; Exemple: case SEL is when “000” => S1 <= E1; when “001” => S1 <= ‘0’; when “010” | “011” => S1 <=’1’; -- La barre | permet de réaliser -- un ou logique entre les deux -- valeurs “010” et “011” when others => S1 <= ‘0’; Remarque: ne pas confondre => (implique) et <= (affecte).
49
Exemple : Un décodeur 7 segments
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; ENTITY dec_7seg IS PORT(hex_digit : IN STD_LOGIC_VECTOR(3 downto 0); segment_a, segment_b, segment_c, segment_d, segment_e, segment_f, segment_g : out std_logic); END dec_7seg; ARCHITECTURE a OF dec_7seg IS SIGNAL segment_data : STD_LOGIC_VECTOR(6 DOWNTO 0); BEGIN PROCESS (Hex_digit) -- HEX to 7 Segment Decoder for LED Display BEGIN CASE Hex_digit IS WHEN "0000" => segment_data <= " "; WHEN "0001" => segment_data <= " "; WHEN "0010" => segment_data <= " "; WHEN "0011" => segment_data <= " "; WHEN "0100" => segment_data <= " "; WHEN "0101" => segment_data <= " "; WHEN "0110" => segment_data <= " "; WHEN "0111" => segment_data <= " "; WHEN "1000" => segment_data <= " "; WHEN "1001" => segment_data <= " "; WHEN "1010" => segment_data <= " "; WHEN "1011" => segment_data <= " "; WHEN "1100" => segment_data <= " "; WHEN "1101" => segment_data <= " "; WHEN "1110" => segment_data <= " "; WHEN "1111" => segment_data <= " "; WHEN OTHERS => segment_data <= " "; END CASE; END PROCESS; -- extract segment data and LED driver is inverted segment_a <= NOT segment_data(6); segment_b <= NOT segment_data(5); segment_c <= NOT segment_data(4); segment_d <= NOT segment_data(3); segment_e <= NOT segment_data(2); segment_f <= NOT segment_data(1); segment_g <= NOT segment_data(0); END a;
50
Exemple : MEMOIRE de 2 mots
-- Les adresses 0 et 1 sont accessibles en lectures et en écritures LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; ENTITY memory IS PORT(read_data : OUT std_logic_vector(7 DOWNTO 0); read_address : IN std_logic_vector(2 DOWNTO 0); write_data : IN std_logic_vector(7 DOWNTO 0); write_address : IN std_logic_vector(2 DOWNTO 0); Memwrite : IN std_logic; clock,reset : IN std_logic); END memory; ARCHITECTURE behavior OF memory IS SIGNAL mem0, mem1 : std_logic_vector(7 DOWNTO 0); BEGIN -- Process for memory read operation PROCESS (read_address, mem0, mem1) CASE read_address IS WHEN "000" => read_data <= mem0; WHEN "001" => read_data <= mem1; -- unimplemented memory locations WHEN OTHERS => read_data <= " "; END CASE; END PROCESS; -- Process for memory write operation PROCESS BEGIN WAIT UNTIL clock'event and clock='1'; IF (reset = '1') THEN -- initial values for memory (optional) mem0 <= " "; mem1 <= " "; ELSE -- Write to memory? -- use a flip-flop with an enable for memory IF memwrite = '1' THEN CASE write_address IS WHEN "000" => mem0 <= write_data; WHEN "001" => mem1 <= write_data; -- unimplemented memory locations WHEN OTHERS => NULL; END CASE; END IF; END PROCESS; END behavior;
51
Exemple : MEMOIRE de plusieurs mots
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY bmemory IS PORT(read_data : OUT std_logic_vector(7 DOWNTO 0); read_address : IN std_logic_vector(2 DOWNTO 0); write_data : IN std_logic_vector(7 DOWNTO 0); write_address : IN std_logic_vector(2 DOWNTO 0); Memwrite : IN std_logic; clock : IN std_logic); END bmemory; ARCHITECTURE behavior OF bmemory IS -- definition d’un type de données tableau pour la mémoire TYPE memory_type IS ARRAY (0 TO 7) OF std_logic_vector(7 DOWNTO 0); SIGNAL memory : memory_type; BEGIN -- Lecture de la Mémoire -- Conversion de l’indice de ligne en entier avec CONV_INTEGER read_data <= memory(CONV_INTEGER(read_address(2 DOWNTO 0))); -- Ecriture dans la mémoire ? PROCESS WAIT UNTIL clock'event and clock='1'; IF (memwrite = '1') THEN memory(CONV_INTEGER(write_address(2 DOWNTO 0))) <= write_data; END IF; END PROCESS; END behavior;
52
Exemple mémoire : Utilisation de la bibliothèque de fonction de Max plus + II
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; LIBRARY lpm; USE lpm.lpm_components.ALL; ENTITY memory IS PORT(read_data : OUT std_logic_vector(7 DOWNTO 0); memory_address: IN std_logic_vector(2 DOWNTO 0); write_data: IN std_logic_vector(7 DOWNTO 0); Memwrite : IN std_logic; clock,reset: IN std_logic); END memory; ARCHITECTURE behavior OF memory IS BEGIN data_memory: lpm_ram_dq GENERIC MAP (lpm_widthad => 3, taille des adresses : sur 3 bits lpm_outdata => "UNREGISTERED", lpm_indata => "REGISTERED", lpm_address_control => "UNREGISTERED", -- Reads in mif file for initial data values lpm_file => "memory.mif", lpm_width => 8) PORT MAP (data => write_data, address => memory_address(2 DOWNTO 0), we => Memwrite, inclock => clock, q => read_data); END behavior;
53
Les fichiers .mif : les 12 premières valeurs du sinus
DEPTH= 256; WIDTH= 8; ADDRESS_RADIX = DEC; DATA_RADIX = DEC; CONTENT BEGIN 0 : 127; 1 : 130; 2 : 133; 3 : 136; 4 : 139; 5 : 142; 6 : 145; 7 : 148; 8 : 151; 9 : 154; 10 : 157; 11 : 160; 12 : 163;
54
Une ALU en VHDL LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY ALU IS PORT( Op_code : in std_logic_vector(2 DOWNTO 0); A_input, B_input: in std_logic_vector(7 DOWNTO 0); ALU_output : out std_logic_vector(7 DOWNTO 0)); END ALU; ARCHITECTURE behavior OF ALU IS SIGNAL temp_output: std_logic_vector(7 DOWNTO 0); BEGIN PROCESS (Op_code, A_input, B_input) -- Select Arithmetic/Logical Operation CASE Op_Code (2 DOWNTO 1) IS WHEN "00" => temp_output <= A_input + B_input; WHEN "01" => temp_output <= A_input - B_input; WHEN "10" => temp_output <= A_input AND B_input; WHEN "11" => -- Select Shift Operation IF Op_Code(0) = '1' THEN -- Shift bits left with zero fill using concatination operator Alu_output <= temp_output(6 DOWNTO 0) & '0'; ELSE Alu_output <= temp_output; END IF; END CASE; END PROCESS; END behavior;
55
V. 3) Les autres structures utilisées dans un process
V.3) Les autres structures utilisées dans un process. La commande : For loop LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; ENTITY codage IS PORT ( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); s : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) ); END codage; ARCHITECTURE archi OF codage IS BEGIN PROCESS s(0) <= a(0); FOR i IN 1 TO 3 LOOP S(i)<=(a(i) AND a(i-1)) OR ( NOT a(i) AND NOT a(i-1)); END LOOP; END PROCESS; END archi; Syntaxe FOR paramètre IN intervalle (Ex:0 to 5) LOOP Instructions; END LOOP; Exemple: codage de données: Le cahier des charges est le suivant : s0 = a0 pour i>0 Si = ai . ai /ai . /ai-1
56
V.4 L’instruction « wait »
Il est possible de définir un « process » sans liste de dépendance. Chaque « process » est toujours exécuté au moins une fois, au début En ajoutant des énoncés « wait », il devient possible d’indiquer que le « process » sera réveillé à un certain endroit, selon une certaine condition: wait for time; wait on signal; wait until condition; Exemple de wait et d’attributs: flip-flop library IEEE; use IEEE.std_logic_1164.all; entity dff is port(D, Clk: in std_logic; Q, QN: out std_logic); end dff; architecture comp_dff of dff is constant delai: Time:= 5 ns; begin One_ff: process wait until (Clk’event and Clk = ‘1’); Q <= D after delai; QN <= not D after delai; end process One_ff; end comp_dff;
57
VI Les attributs et les fonctions de conversion
Les attributs permettent d'ajouter des informations supplémentaires à un signal, variable ou un composant. Syntaxe object_name'attribut_name Syntaxe des attributs pour le type ARRAY ou scalaire X'HIGH élément le plus grand ou borne maximale X'LOW élément le plus petit ou borne minimale X'LEFT élément de gauche ou borne de gauche X'RIGHT élément de droite ou borne de droite Syntaxe des attributs pour SIGNAL x'EVENT retourne TRUE si x change d'état x'ACTIVE retourne TRUE si x a changé durant le dernier intervalle x'LAST_EVENT retourne une valeur temporelle depuis le dernier changement de x x'LAST_ACTIVE retourne une valeur temporelle depuis la dernière transition de x x'LAST_VALUE retourne la dernière valeur de x Ces attributs créent un nouveau SIGNAL x'DELAYED(t) crée un signal du type de x retardé par t x'STABLE(t) retourne TRUE si x n'est pas modifié pendant le temps t x'QUIET(t) crée un signal logique à TRUE si x n'est pas modifié pendant un temps t x'TRANSACTION crée un signal logique qui bascule lorsque x est change d'état
58
VI Les attributs et les fonctions de conversion (suite)
-- Les fonctions de conversion de type 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 CONV_INTEGER (ARG: STD_ULOGIC) return INTEGER; FUNCTION CONV_UNSIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return UNSIGNED; FUNCTION CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR; -- Détection des fronts des signaux FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN; FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
59
VII Communication entre processus
Les signaux sont globaux: il est possible à un processus d’accéder (lire et/ou écrire) un signal d’un autre processus La communication entre processus se fait donc à l’aide de signaux Note: on parle ici de processus qui font partie d’une même architecture… Exemple: additionneur 1-bit
60
Exemple de communication entre processus: additionneur 1-bit
In1 Demi-additionneur HA1 Demi-additionneur HA2 In2 s2 C_in Demi-additionneur Somme s3 C_out OR1
61
Exemple de communication entre processus: additionneur 1-bit
library IEEE; use IEEE.std_logic_1164.all; entity add_1_bit is port(In1, In2, C_in: in std_logic; Somme, C_out: out std_logic); end add_1_bit; architecture comp_add of add_1_bit is signal s1, s2, s3: std_logic; constant delai: Time:= 5 ns; begin HA1: process(In1, In2) s1 <= (In1 xor In2) after delai; s3 <= (In1 and In2) after delai; end process HA1; HA2: process(s1, C_in) begin Somme <= (s1 xor C_in) after delai; s2 <= (s1 and C_in) after delai; end process HA2; OR1: process(s2, s3) C_out <= (s2 or s3) after delai; end process OR1; end comp_add;
62
1 Représentation hiérarchique
On peut utiliser VHDL de façon hiérarchique et ainsi simplifier la description d’une machine complexe. Pour cela, on associe entre eux plusieurs composants élémentaires (couples : entité/architecture) dont on connecte les sorties sur les entrées adéquates.
63
Exemple de représentation hiérarchique: un additionneur: portes XOR et AND
library IEEE; use IEEE.std_logic_1164.all; entity one_xor is port(In1, In2 : in std_logic; Z: out std_logic); end one_xor; architecture comp_xor of one_xor is constant delai: Time:= 5 ns; begin z <= (In1 xor In2) after delai; end comp_xor; library IEEE; use IEEE.std_logic_1164.all; entity one_and is port(In1, In2 : in std_logic; Z: out std_logic); end one_and; architecture comp_and of one_and is constant delai: Time:= 5 ns; begin z <= (In1 and In2) after delai; end comp_and;
64
Exemple de représentation hiérarchique: un additionneur: porte OU
library IEEE; use IEEE.std_logic_1164.all; entity one_or is port(In1, In2 : in std_logic; Z: out std_logic); end one_or; architecture comp_or of one_or is constant delai: Time:= 5 ns; begin z <= (In1 or In2) after delai; end comp_or;
65
Exemple de représentation hiérarchique: un additionneur: demi-additionneur
library IEEE; use IEEE.std_logic_1164.all; entity one_half_adder is port(In1, In2 : in std_logic; sum, c_out: out std_logic); end one_half_adder; architecture comp_ha of one_half_adder is -- 1° recensement de tous les composants du schéma component xor_gate port (In1, In2: in std_logic; z: out std_logic); end component; component and_gate -- 2° attribution des circuits à leur ENTITY for XOR1: xor_gate use entity work.one_xor(comp_xor); for AND1: and_gate use entity work.one_and(comp_and); Begin -- 3° affectation des liaisons du schéma aux broches des composants XOR1:xor_gate port map(In1, In2, sum); AND1:and_gate port map(In1, In2, c_out); end comp_ha;
66
2 Les composants Le composant est déclaré dans la zone déclarative de l’architecture dans laquelle il est utilisé. La syntaxe est la suivante : COMPONENT NOM_DU_COMPOSANT Port (entrées,… : in type; sorties : out type) End component; Le composant a un nom propre dans l’architecture. Puis, on indique la localisation (répertoire source) du composant. for C1: NOM_DU_COMPOSANT use entity NOM_REPERTOIRE_COMPOSANT.NOM_ENTITE(NOM_ARCHI); Enfin, on définit les liaisons existantes entre les ports du composants et les connexions de l’architecture. C1 : NOM_DU_COMPOSANT Port map(entrées sorties à utiliser);
67
Exemple de représentation hiérarchique: un additionneur: l’ensemble
library IEEE; use IEEE.std_logic_1164.all; entity one_adder is port(In1, In2, C_in : in std_logic; sum, c_out: out std_logic); end one_adder; architecture comp_add of one_adder is component half_addr port (In1, In2: in std_logic; end component; component or_gate z: out std_logic); for HA1: half_addr use entity work.one_half_adder(comp_ha); for HA2: half_addr use entity work.one_half_adder(comp_ha); for OR1: or_gate use entity work.one_or(comp_or); signal s1, s2, s3: std_logic; begin HA1:half_addr port map(In1, In2, s1, s3); HA2:half_addr port map(s1, C_in, sum, s2); OR1:or_gate port map(s2, s3, c_out); end comp_add;
68
VIII Les Package : fonctions et procédures
PACKAGE déclare une fonction ou une procédure. Le nom défini par PACKAGE BODY doit être le même que celui déclaré par PACKAGE. Syntaxe : PACKAGE package_name IS [type_declaration] [constant_declaration] .. [fonctions] [component_declaration] END [package_name]; PACKAGE BODY packname of package_name IS [type_declaration] [subtype_declaration] [constant_declaration] .. [subprogram_declaration] END [packname];
69
IX Les Fonctions Les FONCTIONS sont des blocs d'instructions qui retournent une valeur unique. Les fonctions peuvent être appelées de différents endroits. Les paramètres passés sont du type IN et les objets de classe SIGNAL ou CONSTANT. On peut déclarer des variables locales à l'intérieur d'une fonction. Ces variables perdent leur valeur à chaque sortie de la fonction et sont initialisées à chaque appel. Une fonction peut être déclarée dans un PACKAGE ou dans le corps d'une ARCHITECTURE. Syntaxe : FUNCTION nom_fonction (liste des entrées ) RETURN type_name IS BEGIN variables; instructions; END nom_fonction;
70
Exemple : utilisation d’une fonction « retard »
LIBRARY ieee; -- déclaration de la fonction USE ieee.std_logic_1164.all; USE work.myfuncs.all; -- on déclare la bibliothèque utilisateur myfuncs PACKAGE myfuncs IS FUNCTION delay(newval : IN std_logic; -- entête de delay delay01 : IN time; -- les paramètres n'ont pas le même nom, c'est l'ordre qui compte delay10 : IN time) RETURN time; -- retourne un nombre de type time END myfuncs; PACKAGE BODY my_funcs of myfuncs IS FUNCTION delay(newval : IN std_logic; -- corps de delay delay01 : IN time; delay10 : IN time) RETURN time; BEGIN CASE newval IS WHEN '0' => RETURN delay01; -- retourne la valeur delay01 WHEN '1' => RETURN delay10; -- retourne la valeur delay10 WHEN OTHERS => IF (delay01 > delay10) THEN -- retourne la plus grande valeur RETURN delay01; ELSE RETURN delay10; END IF; END CASE; END delay; END my_funcs;
71
Exemple : LIBRARY ieee; USE ieee.std_logic_1164.all;
ENTITY nor2 IS GENERIC (tphl : time := 10.0ns; -- déclaration des temps de propagation tplh : time := 15.0ns); PORT (a,b : IN std_logic; z : OUT std_logic); END nor2; ARCHITECTURE behavior OF nor2 IS BEGIN dly: PROCESS(a,b) VARIABLE newstate : std_logic; BEGIN newstate := a NOR b; z <= newstate AFTER delay(a NOR b,tplh,tphl); -- appel de la fonction delay END PROCESS dly; END behavior;
72
Exemple LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY nor2 IS GENERIC (tphlmin, tplhmin: time := 3.0ns; -- déclaration des temps de propagation tphltyp : time := 8.0ns; tplhtyp : time := 6.5ns; tphlmax, tplhmax: time := 13.0ns); PORT (a,b : IN std_logic; z : OUT std_logic); END nor2; ARCHITECTURE behavior OF nor2 IS BEGIN dly0: PROCESS(a,b); BEGIN IF a = '0' AND b = '0' THEN -- il faut résoudre tous les cas puisque tplhtyp < ou > tphltyp z <= '1' AFTER tplhmin; ELSIF a = '0' AND b = '1' THEN z <= '0' AFTER tphlmin; ELSIF a = '1' AND b = '0' THEN ELSIF a = '1' AND b = '1' THEN END IF; END PROCESS dly0; END behavior;
73
X Les procédures Les PROCEDURES sont des blocs d'instructions qui permettent d‘ effectuer des calculs et qui peuvent être appelées de différents endroits. Les paramètres passés sont du type IN, OUT et INOUT et les objets de classe SIGNAL, CONSTANT ou VARIABLE. Le mode par défaut du type IN est de classe CONSTANT. OUT et INOUT sont considérés comme de classe VARIABLE. En fait, le paramètre CONSTANT IN peut être associé avec un signal, variable, constante ou une expression lorsque la procédure est appelée. Une procédure peut être déclarée dans un PACKAGE ou dans le corps d'une ARCHITECTURE. On peut déclarer des variables locales à l'intérieur d'une procédure. Ces variables perdent leur valeur à chaque sortie de la procédure et sont initialisées à chaque appel. Une procédure peut contenir un WAIT sauf si elle est appelée par un PROCESS avec une liste de sensibilité ou depuis une FONCTION. syntaxe PROCEDURE procedure_name (parameter_list) IS BEGIN variables; instructions; END [procedure_name];
74
Exemple : Procédure LIBRARY ieee; -- déclaration de la procédure USE ieee.std_logic_1164.all; PACKAGE myfuncs IS PROCEDURE addparity(VARIABLE d : IN std_logic_vector(7 DOWNTO 0); do, de : OUT std_logic_vector(8 DOWNTO 0)); -- les paramètres n'ont pas le même nom, c'est l'ordre qui compte END myfuncs; PACKAGE BODY myfuncs IS PROCEDURE addparity(VARIABLE d IN std_logic_vector(7 DOWNTO 0); -- corps de la procédure do, de : OUT std_logic_vector(8 DOWNTO 0)) IS -- do et de sont les valeurs de sorties de la procédure VARIABLE temp : std_logic; BEGIN temp := '0'; loop1: FOR i IN 7 DONWTO 0 LOOP temp := temp XOR d(i); END LOOP loop1; de := temp & d; do := NOT temp & d; END addparity; END myfuncs;
75
Exemple LIBRARY ieee; USE ieee.std_logic_1164.all; USE work.myfuncs.all; -- on déclare la bibliothèque utilisateur myfuncs ENTITY parity_add IS PORT (din : std_logic_vector(7 DOWNTO 0); douto, doute : OUT std_logic_vector(8 DOWNTO 0)); END parity_add; ARCHITECTURE behv OF parity_add IS BEGIN PROCESS(din) VARIABLE dintemp : std_logic_vector(7 DOWNTO 0); VARIABLE dptempo,dptempe : std_logic_vector(8 DOWNTO 0); BEGIN dintemp := din; addparity(dintemp,dptempo,dptempe); douto <= dptempo; doute <= dptempe; END PROCESS; END behv;
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.