Utiliser les attributs VHDL 'range, 'length, 'high et 'low pour écrire du code réutilisable, indépendant de la largeur et synthétisable.
Un attribut permet de lire une propriété d'un type ou d'un objet. Pour les bus, il évite de répéter la largeur ou les bornes dans chaque calcul.
signal r_data : std_logic_vector(15 downto
0
);
constant c_WIDTH : natural := r_data'length;
Si r_data passe de 16 à 32 bits, c_WIDTH suit sa nouvelle largeur.
Distinguer les bornes et la direction
Attribut
Signification
'length
Nombre d'éléments
'range
Plage dans le même sens que l'objet
'reverse_range
Plage dans le sens inverse
'high
Indice le plus haut
'low
Indice le plus bas
'left
Indice écrit à gauche de la déclaration
'right
Indice écrit à droite de la déclaration
Avec ce signal :
signal r_data : std_logic_vector(7 downto 0);
'length vaut 8, 'high vaut 7 et 'low vaut 0. 'range conserve la plage 7 downto 0. 'left et 'right suivent l'écriture de la déclaration ; ils ne sont pas nécessairement égaux à 'high et 'low dans cet ordre.
Faire suivre les tailles au code
Une boucle à taille fixe dépend de la déclaration d'origine :
for i in 0 to 7 loop r_next(i) <= i_data(i);end loop;
En utilisant la plage du signal, elle suit sa largeur et sa direction :
for i in i_data'range loop r_next(i) <= i_data(i);end loop;
Vérifie aussi que r_next accepte les indices parcourus. L'attribut adapte la boucle, sans redimensionner automatiquement la destination.
Pour une conversion, prends la largeur de la cible :
w_vec'length remplace ainsi une constante répétée dans le calcul.
Reconnaître les événements et guider la synthèse
'event indique un changement de valeur du signal :
if i_clk'event and i_clk = '1' then -- ...end if;
Pour exprimer un front montant, utilise plutôt la fonction dédiée :
if rising_edge(i_clk) then -- ...end if;
rising_edge reconnaît les transitions valides entre niveaux bas et hauts de std_logic, sans accepter de la même manière un changement depuis une valeur inconnue.
Les attributs de synthèse ont un autre rôle : ils donnent des indications à un outil précis, par exemple pour conserver un signal :
attribute keep : string;attribute keep of w_debug : signal is "true";
Documente l'effet recherché et vérifie le nom, la valeur et la portée acceptés par l'outil. Le résultat synthétisé reste à contrôler.