vhdl
Upplösningsfunktioner, olösta och lösta typer
Sök…
Introduktion
VHDL-typer kan vara olösta eller lösta . Den bit
som deklareras av std.standard
paketet är till exempel olöst medan std_logic
typen som deklareras av paketet ieee.std_logic_1164
är upplöst.
En signal vilken typ är olöst kan inte drivas (tilldelas) med mer än en VHDL-process medan en signal vilken typ är upplöst kan.
Anmärkningar
Användningen av lösta typer bör reserveras till situationer där avsikten verkligen är att modellera en hårdvarutråd (eller uppsättning ledningar) som drivs av mer än en hårdvarukrets. Ett typiskt fall där det behövs är den dubbelriktade databussen i ett minne: när minnet är skrivet är det skrivanordningen som driver bussen medan när minnet läses är det minnet som driver bussen.
Att använda lösta typer i andra situationer, medan en vanligt förekommande praxis, är en dålig idé eftersom det undertrycker mycket användbara kompileringsfel när oönskade flera frekvensomriktarsituationer av misstag skapas.
Paketet ieee.numeric_std
deklarerar de signed
och unsigned
vektortyperna och överbelaster de aritmetiska operatörerna på dem. Dessa typer används ofta när aritmetiska och bitvisa operationer behövs på samma data. De signed
och unsigned
typerna löses. Tidigare VHDL2008, med hjälp av ieee.numeric_std
och dess typer, antydde således att oavsiktliga flera frekvensomriktarsituationer inte skulle leda till kompilationsfel. VHDL2008 lägger till nya typdeklarationer att ieee.numeric_std
: unresolved_signed
och unresolved_unsigned
(alias u_signed
och u_unsigned
). Dessa nya typer bör föredras i alla fall där situationer med flera enheter inte önskas.
Två processer som kör samma signal av typen "bit"
Följande VHDL modell enheter signal s
från två olika processer. Eftersom typen av s
är bit
, en olöst typ, är detta inte tillåtet.
-- 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;
Att sammanställa, utarbeta och försöka simulera, t.ex. med GHDL, höjer ett fel:
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
Observera att felet tas upp även om, som i vårt exempel, alla förare håller med om körvärdet.
Upplösningsfunktioner
En signal vilken typ är upplöst har en tillhörande upplösningsfunktion . Det kan drivas av mer än en VHDL-process. Upplösningsfunktionen kallas för att beräkna det resulterande värdet varje gång en förare tilldelar ett nytt värde.
En upplösningsfunktion är en ren funktion som tar en parameter och returnerar ett värde av typen att lösa. Parametern är en endimensionell, obegränsad matris med element av typen att lösa. För bit
kan till exempel parametern vara av typen bit_vector
. Under simulering kallas upplösningsfunktionen vid behov för att beräkna det resulterande värdet för att applicera på en multipeldriven signal. Det passeras en matris med alla värden som drivs av alla källor och returnerar det resulterande värdet.
Följande kod visar deklarationen för en upplösningsfunktion för bit
som uppträder som en kabel and
. Det visar också hur man deklarerar en upplöst subtyp av bit
och hur den kan användas.
-- 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;
Att kompilera, utarbeta och simulera, t.ex. med GHDL, ger inte något fel:
ghdl -a md.vhd
ghdl -e md
./md
md.vhd:39:5:@0ms:(report note): '0'
md.vhd:39:5:@3ns:(report note): '1'
Ett kommunikationsprotokoll med en bit
Vissa mycket enkla och billiga hårdvaru-enheter, som sensorer, använder ett en-bitars kommunikationsprotokoll. En enda dubbelriktad datalinje ansluter enheten till en typ av mikrokontroller. Den dras ofta upp av ett dragmotstånd. Kommunikationsenheterna driver linjen låg under en fördefinierad tid för att skicka en information till den andra. Figuren nedan illustrerar detta:
Detta exempel visar hur man modellerar detta med den ieee.std_logic_1164.std_logic
upplösta typen.
-- 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;