vhdl
Fonctions de résolution, types non résolus et résolus
Recherche…
Introduction
Les types VHDL peuvent être non résolus ou résolus . Le type de bit
déclaré par le package std.standard
, par exemple, n'est pas résolu tant que le type std_logic
déclaré par le package ieee.std_logic_1164
est résolu.
Un signal dont le type n'est pas résolu ne peut pas être piloté (assigné) par plus d'un processus VHDL alors qu'un signal dont le type est résolu peut le faire.
Remarques
L'utilisation de types résolus devrait être réservée aux situations où l'intention est réellement de modéliser un fil matériel (ou un ensemble de fils) piloté par plus d'un circuit matériel. Le bus de données bidirectionnel d'une mémoire en est un exemple typique: lorsque la mémoire est écrite, c'est le périphérique d'écriture qui pilote le bus, tandis que lorsque la mémoire est lue, c'est la mémoire qui pilote le bus.
L'utilisation de types résolus dans d'autres situations, bien qu'une pratique fréquemment rencontrée, est une mauvaise idée, car elle supprime les erreurs de compilation très utiles lorsque des situations de lecteurs multiples indésirables sont créées accidentellement.
Le ieee.numeric_std
package déclare la signed
et unsigned
types de vecteurs et les opérateurs arithmétiques surchargent sur eux. Ces types sont fréquemment utilisés lorsque des opérations arithmétiques et bit par bit sont nécessaires sur les mêmes données. Les types signed
et unsigned
sont résolus. Avant VHDL2008, l'utilisation de ieee.numeric_std
et de ses types impliquait que des situations de lecteurs multiples accidentelles ne ieee.numeric_std
pas d'erreurs de compilation. VHDL2008 ajoute de nouvelles déclarations de type à ieee.numeric_std
: unresolved_signed
et unresolved_unsigned
(alias u_signed
et u_unsigned
). Ces nouveaux types doivent être préférés dans tous les cas où plusieurs situations de lecteur ne sont pas souhaitées.
Deux processus pilotant le même signal de type `bit`
Le modèle VHDL suivant pilote le signal s
de deux processus différents. Comme le type de s
est bit
, un type non résolu, cela n'est pas autorisé.
-- File md.vhd
entity md is
end entity md;
architecture arc of md is
signal s: bit;
begin
p1: process
begin
s <= '0';
wait;
end process p1;
p2: process
begin
s <= '0';
wait;
end process p2;
end architecture arc;
Compiler, élaborer et simuler, par exemple avec GHDL, déclencher une erreur:
ghdl -a md.vhd
ghdl -e md
./md
for signal: .md(arc).s
./md:error: several sources for unresolved signal
./md:error: error during elaboration
Notez que l'erreur est augmentée même si, comme dans notre exemple, tous les pilotes sont d'accord sur la valeur de conduite.
Fonctions de résolution
Un signal dont le type est résolu a une fonction de résolution associée. Il peut être piloté par plusieurs processus VHDL. La fonction de résolution est appelée pour calculer la valeur résultante lorsqu'un pilote attribue une nouvelle valeur.
Une fonction de résolution est une fonction pure qui prend un paramètre et retourne une valeur du type à résoudre. Le paramètre est un tableau unidimensionnel non contraint d'éléments du type à résoudre. Pour le bit
type, par exemple, le paramètre peut être de type bit_vector
. Au cours de la simulation, la fonction de résolution est appelée au besoin pour calculer la valeur résultante à appliquer à un signal à commandes multiples. Un tableau de toutes les valeurs est transmis à toutes les sources et renvoie la valeur résultante.
Le code suivant montre la déclaration d'une fonction de résolution pour le type bit
qui se comporte comme un câble and
. Il montre également comment déclarer un sous-type résolu de type bit
et comment il peut être utilisé.
-- File md.vhd
entity md is
end entity md;
architecture arc of md is
function and_resolve_bit(d: bit_vector) return bit is
variable r: bit := '1';
begin
for i in d'range loop
if d(i) = '0' then
r := '0';
end if;
end loop;
return r;
end function and_resolve_bit;
subtype res_bit is and_resolve_bit bit;
signal s: res_bit;
begin
p1: process
begin
s <= '0', '1' after 1 ns, '0' after 2 ns, '1' after 3 ns;
wait;
end process p1;
p2: process
begin
s <= '0', '1' after 2 ns;
wait;
end process p2;
p3: process(s)
begin
report bit'image(s); -- show value changes
end process p3;
end architecture arc;
Compiler, élaborer et simuler, par exemple avec GHDL, ne génère pas d'erreur:
ghdl -a md.vhd
ghdl -e md
./md
md.vhd:39:5:@0ms:(report note): '0'
md.vhd:39:5:@3ns:(report note): '1'
Un protocole de communication un bit
Certains dispositifs matériels très simples et peu coûteux, tels que des capteurs, utilisent un protocole de communication à un bit. Une seule ligne de données bidirectionnelle connecte l'appareil à une sorte de microcontrôleur. Il est fréquemment tiré par une résistance de traction. Les appareils en communication pilotent la ligne basse pendant une durée prédéfinie pour envoyer une information à l'autre. La figure ci-dessous illustre ceci:
Cet exemple montre comment modéliser ceci en utilisant le type résolu ieee.std_logic_1164.std_logic
.
-- File md.vhd
library ieee;
use ieee.std_logic_1164.all;
entity one_bit_protocol is
end entity one_bit_protocol;
architecture arc of one_bit_protocol is
component uc is
port(
data_in: in std_ulogic;
set_low: out std_ulogic
);
end component uc;
component sensor is
port(
data_in: in std_ulogic;
set_low: out std_ulogic
);
end component sensor;
signal data: std_logic; -- The bi-directional data line
signal set_low_uc: std_ulogic;
signal set_low_sensor: std_ulogic;
begin
-- Micro-controller
uc0: uc port map(
data_in => data,
set_low => set_low_uc
);
-- Sensor
sensor0: sensor port map(
data_in => data,
set_low => set_low_sensor
);
data <= 'H'; -- Pull-up resistor
-- Micro-controller 3-states buffer
data <= '0' when set_low_uc = '1' else 'Z';
-- Sensor 3-states buffer
data <= '0' when set_low_sensor = '1' else 'Z';
end architecture arc;