A VHDL hardver leíró nyelv

Típusok, típuskonstrukciók

Típusszerkezet

A VHDL típusszerkezete az Ada-éhoz hasonlóan épül fel. Az egyes elemi típusok és új típusok deklarációja ugyanúgy történik, mint Ada-ban. Mivel az Ada erős típusosságának megőrzése fontos volt a készítők számára, ezért a szigorú hierarchikus szervezést is megtartották. Ez alatt értem például az altípusok létrehozásának lehetőségét, az operátorok esetleges túlterhelését a package-ek segítségével. Mindezekhez ugyanazon nyelvi eszközök állnak rendelkezésünkre, mint Ada-ban.

Elemi típusok

Az elemi típusok az STD könyvtárban előre megírt STANDARD csomagban találhatók. Az alábbi táblázatban felsorolom a VHDL beépített típusait, amik közül csak néhány lesz, ami nem Ada típus.

TÍPUS JELLEMZŐK
BOOLEAN (FALSE, TRUE)
BIT ('0','1')
BIT_VECTOR BIT típusú elemek tömbje
CHARACTER az összes ASCII-karakter értékét felveheti
STRING CHARACTER típusú elemek tömbje
SEVERITY_LEVEL (NOTE, WARNING, ERROR, FAILURE)
INTEGER implementációtól függő tartományon értelmezett egészek
NATURAL INTEGER altípus a [0,INTEGER’HIGH] tartományban
POSITIVE INTEGER altípus a [1,INTEGER’HIGH] tartományban
REAL implementációtól függő tartományon és pontossággal értelmezett valósok
TIME a tartomány implementáció-függő, a lehetséges nagyságrendjei a femtoszekundumtól az óráig terjednek
FILE_OPEN_KIND,
FILE_OPEN_STATUS
fájl megnyitására vonatkozó típusok

Továbbá használhatjuk a jól ismert access kulcsszót mutatók létrehozására az Ada-ban megszokott szigorú ellenőrzések mellett.

IEEE 1164 típusok

A VHDL fejlesztőkörnyezetek részeként hozzáférünk egy IEEE elnevezésű könyvtárhoz, aminek csomagjai további típusokat definiálnak a fejlesztő számára. E könyvtár szerkezetét az IEEE 1164 kódú szabvány írja le, amit azért hoztak létre, hogy a különböző áramkörökben előforduló logikai értékeket egységesen lehessen kezelni a kód megírásakor. Az IEEE.std_logic_1164 csomag alapvető típusa az std_ulogic, ami kilenc lehetséges értéket vehet fel a következő sorrendben:

LITERÁL ÉRTÉK
'U' meghatározatlan, olyan érték, amit az eszköz működtetésének elején nem láttunk el kezdőértékkel
'X' ismeretlen logikai érték, a valóságban nem létezik, csupán arra használhatjuk, hogy szimuláció során egy-egy figyelmen kívül hagyott tervezési hibát felfedezzünk a megjelenésével; vagy az előállított áramkörben külső körülmények hatására bekövetkező alternatív eseteket tudjuk kezelni (a valóságban ez azt jelenti, hogy ’0’ vagy ’1’ értéket is felvehet)
'0' logikai hamis érték
'1' logikai igaz érték
'Z' magas impedanciát jelző érték, amikor a logikai értéket sem ’0’-ként, sem pedig ’1’-ként nem lehet meghatározni
'W' magas impedanciájú megfelelője az ’X’ értéknek
'L' magas impedanciájú megfelelője az ’0’ értéknek
'H' magas impedanciájú megfelelője az ’1’ értéknek
'-' lényegtelen, azt jelenti, hogy nem vesszük figyelembe az adott helyen megjelenő logikai értéket

Az std_ulogic ’u’ betűje az unresolved (vagyis feloldatlan) szó rövidítése, ami azt jelenti, hogy szükséges megírnunk egy ezeket az értékeket értelmező függvényt (például háromértékű logikához, ahol ’0’, ’1’ és ’Z’ értékeket használhatunk).

Az imént tárgyalt típusból származik az std_logic nevű, szintén a csomagban leírt típus is, ami már megvalósítja az ipari szabványoknak megfelelő értelmezést is. Más altípusokat is találhatunk még itt, amik a kilencelemű értékhalmaz néhány gyakran alkalmazott részhalmazát definiálják. Továbbá az előbbiekből képzett összetett típusokat is tartalmaz az std_logic_1164, amik az std_ulogic_vector és az std_logic_vector.

BIT sztring literálok

Az STD_LOGIC_VECTOR típusú objektumoknak legtöbbször valamilyen a fentebb felsorolt lehetséges karaktereket tartalmazó megfelelő hosszúságú sztringgel adunk értéket. Ez azonban nem mindig kényelmes, és nagyobb méretű tömbök esetén jelentősen csökkentheti az átláthatóságot. Ezért már a legelső szabvány is támogatta a következő literálokat, amik viszont csak számok reprezentálására voltak használhatók:

signal Value : unsigned(7 downto 0);

Value <= "00000000";
Value <= B"0000_0000";	-- bináris ábrázolás (ugyanaz, mint előbb,
			-- de használható az olvasást segítő '_' elválasztó jel)
Value <= X"00";		-- hexadecimális ábrázolás (jóval tömörebb)
Value <= O"0000";	-- oktális ábrázolás (néha kényelmes lehet)

Az IEEE 1076-2008 szabvány még inkább megkönnyíti a bitvektorok értékadásait. Azt is fontos megjegyezni, hogy az alábbi literálok az STD_LOGIC_VECTOR típusú elemeknél használhatók.

variable Reg : std_logic_vector(5 downto 0);

Reg := 6x"0f";	-- a megadott érték 6 bit szélességen ábrázolva,
		-- '0'-kkal kitöltve a nem használt helyiértékeket
Reg := 6x"XF";	-- hasonló az előzőhöz, csak itt: "XX1111"
Reg := 6SX"F";	-- előjeles kiterjesztés (sign extension), tehát: "111111"
Reg := 6Ux"f";	-- előjel nélküli formára való kiegésítés: "001111"
Reg := 6sb"11";	-- a harmadikhoz hasonló, csak bináris számként
		-- értelmezi az értéket: "111111"
Reg := 6uO"7";	-- a negyedikhez hasonló, csak oktális számként
		-- értelmezi az értéket: "000111"

Összetett típusok

downto kulcsszó

Mivel lényegében semmi különbség nincs az összetett típusok konstrukcióját illetően a VHDL és az Ada között, ezért csak azt emelném ki, hogy a VHDL tömbjei indextartományának beállítására használhatjuk a (imin to imax) helyett az (imax downto imin) kifejezést is, ahol az újdonság a downto kulcsszó.

A csökkenő indexelés a hardveres gondolkodás sajátja, mivel általában binárisan ábrázolt számokkal dolgozunk, valamint az ezeket kezelő regiszterekkel és huzalokkal. Az átláthatóság miatt ezért a hagyományos csökkenő helyi értékes ábrázolás sokkal előnyösebb.

Határozatlan méretű típusok

Az IEEE 1076-2008 szabvány már azt is megengedi, hogy a következő módokon egy-egy tömb vagy rekord elemei előre nem meghatározott méretűek legyenek:

type myArrayT is array (natural range <>) of std_logic_vector;

type myRecordT is
record
	a : std_logic_vector;
	b : std_logic_vector;
end record;

Fizikai típusok

Ilyen típussal ellátott objektumok olyan értékeket tartalmaznak, amik valamely fizikai mennyiséget reprezentálnak. Az értékkészletük mindig az egész számok halmaza, amit kiegészíthetünk a különböző mértékegységekre vonatkozó szorzókkal.

Nézzünk egy jellemző példát:

type aramerosseg is range 0 to 1 E9
units
	nA;
	uA = 1000 nA;
	mA = 1000 uA;
	Amp = 1000 mA;
end units;

Ugyanilyen fizikai típus a beépített TIME is.