vhdl
Resolutiefuncties, onopgeloste en opgeloste typen
Zoeken…
Invoering
VHDL-typen kunnen onopgelost of opgelost zijn . De bit
van de aangegeven soort std.standard
package bijvoorbeeld is onopgelost terwijl de std_logic
type uit de aangegeven ieee.std_logic_1164
pakket opgelost.
Een signaal van welk type niet is opgelost kan niet worden aangestuurd (toegewezen) door meer dan één VHDL-proces, terwijl een signaal van welk type kan worden opgelost.
Opmerkingen
Het gebruik van opgeloste typen moet worden voorbehouden aan situaties waarin het de bedoeling is om een hardwaredraad (of een reeks draden) te modelleren die wordt aangestuurd door meer dan één hardwarecircuit. Een typisch geval waar dit nodig is, is de bidirectionele gegevensbus van een geheugen: wanneer het geheugen wordt geschreven, is het het schrijfapparaat dat de bus aandrijft, terwijl wanneer het geheugen wordt gelezen, het geheugen de bus aandrijft.
Het is een slecht idee om opgeloste typen in andere situaties te gebruiken, maar het is een slecht idee omdat het zeer nuttige compilatiefouten onderdrukt wanneer per ongeluk ongewenste situaties met meerdere schijven worden gecreëerd.
Het pakket ieee.numeric_std
declareert de signed
en unsigned
signed
ieee.numeric_std
en overbelast de rekenkundige operatoren daarop. Deze typen worden vaak gebruikt wanneer rekenkundige en bitgewijze bewerkingen op dezelfde gegevens nodig zijn. De signed
en unsigned
typen zijn opgelost. Eerdere VHDL2008, met gebruik van ieee.numeric_std
en zijn typen, impliceerde dus dat onbedoelde meervoudige ieee.numeric_std
geen compilatiefouten zouden veroorzaken. VHDL2008 voegt nieuwe soort verklaringen ieee.numeric_std
: unresolved_signed
en unresolved_unsigned
(aliassen u_signed
en u_unsigned
). Deze nieuwe typen verdienen de voorkeur in alle gevallen waarin meerdere aandrijfsituaties niet gewenst zijn.
Twee processen sturen hetzelfde signaal van het type `bit` aan
De volgende VHDL model drives signaal s
uit twee verschillende processen. Omdat het type s
bit
, een onopgelost type, is dit niet toegestaan.
-- 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;
Compileren, uitwerken en proberen te simuleren, bijvoorbeeld met GHDL, werpen een fout op:
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
Merk op dat de fout wordt opgeworpen, zelfs als, zoals in ons voorbeeld, alle bestuurders het eens zijn over de rijwaarde.
Resolutie functies
Een signaal van welk type is opgelost heeft een bijbehorende resolutiefunctie . Het kan worden aangestuurd door meer dan één VHDL-proces. De resolutiefunctie wordt opgeroepen om de resulterende waarde te berekenen wanneer een bestuurder een nieuwe waarde toekent.
Een resolutiefunctie is een pure functie die één parameter gebruikt en een waarde retourneert van het type dat moet worden opgelost. De parameter is een eendimensionale, niet-beperkte reeks elementen van het type dat moet worden opgelost. Voor het type bit
kan de parameter bijvoorbeeld van het type bit_vector
. Tijdens simulatie wordt de resolutiefunctie opgeroepen wanneer dat nodig is om de resulterende waarde te berekenen voor toepassing op een meervoudig aangestuurd signaal. Het krijgt een reeks van alle waarden doorgestuurd die door alle bronnen worden aangestuurd en retourneert de resulterende waarde.
De volgende code toont de declaratie van een oplossingsfunctie voor het type bit
dat zich gedraagt als een bedrade and
. Het laat ook zien hoe een opgelost subtype van het type bit
kan worden bit
en hoe het kan worden gebruikt.
-- 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;
Compileren, uitwerken en simuleren, bijvoorbeeld met GHDL, levert geen fout op:
ghdl -a md.vhd
ghdl -e md
./md
md.vhd:39:5:@0ms:(report note): '0'
md.vhd:39:5:@3ns:(report note): '1'
Een één-bit communicatieprotocol
Sommige zeer eenvoudige en goedkope hardware-apparaten, zoals sensoren, maken gebruik van een één-bit communicatieprotocol. Een enkele bidirectionele datalijn verbindt het apparaat met een soort microcontroller. Het wordt vaak omhoog getrokken door een pull-up weerstand. De communicerende apparaten drijven de lijn laag voor een vooraf gedefinieerde duur om informatie naar de andere te verzenden. De onderstaande afbeelding illustreert dit:
Dit voorbeeld laat zien hoe u dit modelleert met het opgeloste type 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;