Kapitola4
Převody datových typů, konverze
Souhrn
Jazyk VHDL je obecně velmi striktní vzhledem k použití jednotlivých datových typů a nedovoluje nám jednoduše zaměňovat různé datové typy a provádět operace s jinými datovými typy, než jaké jsou pro danou funkci povoleny. V různých knihovnách jazyka VHDL jsou však definovány různé převodní a konverzní funkce, které umožňují mezi sebou některé datové typy v omezené míře převádět.
Jedním z častých požadavků na převod datových typů je převod logického vektoru std_logic_vector na číselný datový typ, např. integer.
Poznámka
Převod std_logic_vector <-> integer je často využíván zejména při realizacích čítačů. Obvykle totiž uvažujeme s výstupem binárního čítače ve tvaru n-bitového logického vektoru. Avšak pro behaviorální popis čítače využíváme často způsob zápisu VHDL kódu, kdy při detekci požadované hrany (vzestupné či sestupné) čítaného signálu inkrementujeme (přičteme +1) do hodnoty čítače. Aritmetická operace sčítání (+1) však není pro logický datový typ std_logic_vector použitelná. Řešením je tedy převod na číselný datový typ, realizace operace přičtení a opět převod zpět na logický vektor.
V standardizované knihovně jazyka VHDL s názvem NUMERIC_STD je definována řada konverzních funkcí určených pro převody logických vektorů na typy signed či unsigned a z nich posléze na číselný typ integer a zpět.
Definice
Datový typ signed a unsigned chápeme sice na jednu stranu jako logický datový typ obsahující vektor logických 1 a 0, ale na druhu stranu se jedná o reprezentaci čísla vyjádřeného ve dvojkové (binární) soustavě. Rozdíl je pak pouze v tom, zda je tato hodnota včetně znaménka (jedna bitová pozice je vyhrazena pro znaménko čísla), v tom případě se jedná o typ signed, nebo zda je hodnota bez znaménka, pak jde o unsigned typ (pro unsigned tedy uvažujeme pouze s nezápornými čísly).
Převody mezi datovými typy std_logic_vector, signed/unsigned na integer můžeme ilustrovat pomocí obrázku 4.
+
4. Ilustrace převodů datových typů std_logic_vector, signed/unsigned a integer
Obr. 4. Ilustrace převodů datových typů std_logic_vector, signed/unsigned a integer
Tyto konverzní funkce můžeme shrnout stručně v tabulce 1 společně s dalšími funkcemi pro převody datových typů.
Tabulka 1. Konverzní funkce pro převody datových typů v jazyce VHDL
Funkce
Zdrojový datový typ
Cílový datový typ
Poznámka
Knihovna NUMERIC_STD
signed(objekt)
std_logic_vector
signed
 
unsigned(objekt)
std_logic_vector
unsigned
 
std_logic_vector(objekt)
signed, unsigned
std_logic_vector
 
to_integer(objekt)
signed, unsigned
integer
 
to_signed(objekt, délka)
integer
signed
délka = celé kladné číslo, počet bitů signed
to_unsigned(objekt, délka)
integer
unsigned
délka = celé kladné číslo, počet bitů unsigned
Knihovna STD_LOGIC_1164
to_stdlogicvector(objekt)
bit_vector, std_ulogic_vector
std_logic_vector
 
to_stdulogicvector(objekt)
bit_vector, std_logic_vector
std_ulogic_vector
 
to_bitvector(objekt)
std_logic_vector, std_ulogic_vector
bit_vector
 
to_bit(objekt)
std_ulogic
bit
 
to_stdulogic(objekt)
bit
std_ulogic
 
Definice
V knihovně NUMERIC_STD nalezneme konverzní funkce pro převody logických vektorů std_logic_vector na číselné typy signed, unsigned a integer.
V knihovně STD_LOGIC_1164 se pak nachází převodní funkce pro konverze logických datových typů, bit, bit_vector, std_logic_vector, std_ulogic a std_ulogic_vector.
Zajímavost
Kromě knihovny NUMERIC_STD pro konverze logických a číselných typů a aritmetické operace s logickými datovými typy lze pro jazyk VHDL nalézt ještě knihovny STD_ARITHSTD_LOGIC_SIGNEDSTD_LOGIC_UNSIGNED, které rovněž obsahují funkce pro převody logických vektorů na číselné datové typy a umožňují s nimi provádět aritmetické operace. Ačkoliv mají i tyto knihovny v názvu „STD“ tedy „Standard“, nebyly nikdy oficiálně v rámci IEEE knihoven standardizovány a nejedná se tedy o standardy jazyka VHDL.
Lze se s nimi i tak setkat v řadě VHDL kódů a jsou rovněž široce využívány. Avšak jejich použití přináší riziko, že mohou být různě upravovány a modifikovány (nejsou standardizovány), a není tak zaručena jejich správná funkčnost. Nedoporučuje se tyto knihovny oficiálně ve VHDL kódech používat a hlavně je potřeba nekombinovat je v rámci jedné entity se standardizovanou knihovnou NUMERIC_STD!
Uveďme si pro příklad dvě ukázky VHDL kódů, ve kterých využijeme převody datových typů.
Příklad
Jako první příklad zvolíme behaviorální popis 8bitového synchronního čítače, který čítá vzestupné hrany hodinového signálu Clock, čítač rovněž obsahuje synchronní způsob resetování. Výstupem čítače je logický vektor o velikosti 8 bitů.
Chování čítače můžeme jednoduše popsat tak, že při detekci vzestupné hrany hodinového signálu Clock přičteme do jeho hodnoty +1. Protože však výstupem má být logický vektor, je potřeba provést konverzi z číselného datového typu (pro čítání hodnot 0 až 7 zvolíme unsigned) na logický vektor.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;
entity citac is port (Clock, Reset : in std_logic; Q : out std_logic_vector (7 downto 0)); end citac;
architecture Behavioral of citac is begin process(Clock) variable count : unsigned(7 downto 0):=(others =>'0'); begin if Clock='1' and Clock'event then if Reset='1' then count :=(others =>'0'); else count := count+1; end if; end if; Q<= std_logic_vector(count); end process; end Behavioral;
Příklad
Jako druhý příklad pro využití převodů datových typů uvedeme realizaci 8bitového registru s funkcí rotace vlevo za použití operátoru rol při detekci vzestupné hrany hodinového signálu Clock. Naším úkolem je vytvořit 8bitový registr s výstupem logického vektoru (std_logic_vector), který při detekci každé vzestupné hrany hodinového signálu Clock provede pomocí operátoru rotace vlevo rol rotaci obsahu registru o 1 pozici vlevo. Hodnota registru je na začátku pevně dána "11111110".
Operátor rotace vlevo – rol – lze však použít pouze pro datový typ bit_vector. Pokud tedy požadujeme výstup registru jako std_logic_vector, je potřeba provést převod datového typu.
entity registr is port (Clock : in std_logic; Data_out : out std_logic_vector (7 downto 0)); end registr;
architecture Behavioral of registr is signal reg : bit_vector (7 downto 0) :="11111110"; begin process(Clock) begin if Clock='1' and Clock'event then reg <= reg rol 1; end if; end process; Data_out <= to_stdlogicvector(reg); end Behavioral;