VHLD

Very High Speed Integrated Circuit (VHSIC) Hardware Description Language (VHDL) Język VHDL jest jednym z nowszych języków opisu i projektowania układów cyfrowych. W lipcu 1983 roku firmy Intermetrics, IBM oraz Texas Instruments rozpoczęły pierwszy etap pracy nad nowym językiem opisu i projektowania układów VLSI. Rok później zaimplementowano dany język, dzięki czemu w grudniu 1985 otrzymano pierwszą wersję narzędzia napisanego w języku Ada dla komputerów klasy VA 11/780 i IBM 370.

Projekt VHDL był częścią programu Departamentu Obrony USA o nazwie VHSIC, którego zadaniem było opracowanie metod projektowania oraz wykorzystanie najbardziej złożonych i bardzo szybkich układów scalonych.W roku 1987 VHDL stał się obowiązującym standardem w dziedzinie języków opisu i projektowania układów VLSI.

Ulepszona wersja języka pojawiła się dopiero w 1993 roku i obecnie jest stosowana przez większość projektantów układów cyfrowych na świecie .

W języku VHDL można reprezentować układy cyfrowe na poziomach: od bramkowego do systemowego. Oznacza to, że najmniejszym elementem naszego projektu jest bramka logiczna. Nie mamy więc dostępu do poziomu analogowego (topografii bramki logicznej).

Właściwości Języka VHDL ( ma typowe cechy języka wysokiego poziomu):

•

wspiera hierarchiczność projektowanego sprzętu,

•

umożliwia opis projektu i jego sprawdzenie w całym procesie jego powstania,

•

umożliwia tworzenie nowych wersji projektowych realizowanych w nowych

•

technologiach na postawie rozwiązań projektowych przechowywanych

•

w bibliotece projektów - jest zatem niezależny od konkretnej technologi , metody

•

projektowania, narzędzi wspomagających projektowanie,

•

umożliwia reprezentację dynamiki układu cyfrowego oraz współbieżnych operacji

•

w sprzęcie - można stworzyć równoważne modele funkcjonalne,

•

ułatwia dokumentowanie projektu, a najlepsze rozwiązania można gromadzić

•

w bibliotekach projektów,

•

ułatwia wymianę informacji między projektantami oraz całymi zespołami

•

projektowymi,

Podstawowym elementem w języku VHDL jest jednostka projektowa , którą można przedstawić w postaci bloku o kilku wejściach i kilku wyjściach. Blok ten realizuję pewną funkcję logiczną lub pewną sekwenkcję logiczną.

Jednostka projektowa definiuje swoje wejścia i wyjścia poprzez deklarację portów w bloku programowym nazywanym ENTITY. A funkcję , którą jednostka ma realizować opisuje się w bloku programowym nazywanym ARCHITECTURE . Blok ten może wykorzystywać równania boolowskie do opisu działania układy oraz bardziej ogólny zapis opisujący działanie jak ma się układ zachowywać . Trzeba pamiętać ,że projekt w VHDL-u dotyczy układów logicznych co oznacza , że każde równanie i każdy opis dotyczy współbieżnej struktury logicznej także nie ma znaczenia kolejność występowania równań czy opisów. W VHDL-u komentarze umieszczane są nie jak w języku C po dwuznaku // , ale po dwuznaku - - ( dwa minusy )

ENTITY może być wspolna dla wielu BLOKOW ARCHTEKTURY.

Przykład dla komparatorwa dwóch liczb 4 bitowych

entity COMP_EQ is

port ( O1 : out std_logic;

IN0 : in std_logic_vector (3 downto 0);

I

N1 : in std_logic_vector (3 downto 0));

end COMP_EQ;

Typy portow :

•

OUT- wyjściowy

•

IN- wejściowy

•

INOUT - dwukierunkowy

•

BUFFER – wyjściowy z możliwością odczytu

Język VHDL jest silnie określony na typy portów, zmiennych, sygnałow i stałych.

TYPY służą do wyrażania wartości obiektow . Co to oznacza?

Możemy porownywać lub przypisywać zmienne i sygnały nawzajem tylko tego samego typu np. integer tylko z integer, bit tylko z bit.

Typy danych:

•

bit

•

bit_vector

•

Boolean

•

std_logic

•

std_logic_vector

•

std_ulogic

•

integer

•

unsigned

•

signed

•

Enumeration

•

character

Można definiować własne typy przykładem może być typ definiowany licznik

type licznik is integer range 0 to 127;

Identyfikatory czyli nazwy zmiennych, stałych, procesow oraz elementow wejść i wyjść mogą się składać z liter, cyfr i znaku _

•

Wielkość liter nie ma znaczenia

•

Nazwa musi się rozpoczynać od litery

•

Nazwa nie powinna być dłuższa niż 16 znakow

Przykład:

Magistrala_16bit: signed; – definicja prawidłowa

16bit_magistrala: signed; – definicja zła

_magistrala16bit: signed; – definicja zła

Sygnały są funkcjami czasu i są stosowane do łączenia ze sobą różnych portów symboli ( to jak linia połączeń w schemacie)

signal nazwa_sygnalu : nazwa_typu [ograniczenie][:= wyrazenie]; Przykłady:

signal zerowanie : bit := ′1′; -- inicjalizacja ′1′

signal wektor : bit_vector(0 to 3) := (′0′,′1′,′1′,′0′); signal zmienna_8bitowa : integer range 0 to 255; -- ograniczenie od 0 do 255

Zmienne stosowane pomocniczo tylko w obrębie procesu lub podprogramu np. do indeksowania lub do łatwiejszego opisu działania układu

variable nazwa_zmiennej : nazwa_typu [ograniczenie][:= wyrazenie]; variable uu : integer range 0 to 127 := 5;

variable pp : integer range 500 downto 5 := 100;

Stałe stosowane pomocniczo

constant nazwa_stalej : typ := wyrazenie;

Przykłady:

constant vector : bit_vector(7 downto 0) := ″11110010″;

S o

ł wa kluczowe

abs

downto

library

postponed

Srl

access

else

linkage

procedure

Subtype

after

elsif

literal

process

Then

alias

end

loop

pure

To

all

entity

map

range

Transport

and

exit

mod

record

Type

architecture

file

nand

register

Unaffected

array

for

new

reject

Units

assert

function

Next

rem

Until

attribute

generate Nor

report

Use

begin

generic

Not

return

Variable

block

group

Null

rol

Wait

body

guarded

Of

ror

When

buffer

if

On

select

While

bus

impure

Open

severity

With

case

in

Or

signal

Xnor

component

inertial

Others

shared

Xor

configuration

inout

Out

sla

constant

is

Package

sll

disconnect

label

Port

sra

Typy boolean czy też bit lub bit_vector nie są często stosowane gdyż nie uwzględniają takich stanow jak wysoka impedancja czy też stan nieokreślony sygnału logicznego dlategonajczęściej stosuje się typy std_ulogic, std_logic, std_logic_vector zdefiniowane w bibliotece:

IEEE.Std_Logic_1164.al

library IEEE;

use IEEE.Std_Logic_1164.al ;

Type std_logic is (

′U′, -- stan niezainicjowany

′X′, -- wymusza stan nieznany

′0′, -- wymusza stan 0

′1′, -- wymusza stan 1

′Z′, -- stan wysokiej impedancji

′W′, --słaby stan nieznany (odczyt)

′L′, --słabe 0 (odczyt), rownoważne połączeniu przez rezystor z masą

′H′, --słabe 1 (odczyt), rownoważne połączeniu przewodu przez rezystor z napięciem zasilania

′-′ -- stan nieokreślony, podobnie jak ′X′);

'U' , 'W' , '-' stany używane do procesow symulacyjnych

ATRYBUTY

Dostarczają dodatkowych informacji o obiektach (np. sygnałach, zmiennych, typach lub komponentach)

Składnia: obiekt’atrybut[(parametr)];

Przykładowe atrybuty:

‘EVENT – rowny TRUE, gdy zachodzi zmiana wartości sygnału,

‘STABLE – rowny TRUE, gdy nie zachodzi zmiana wartości sygnału

‘LEFT - zwraca lewą granicę zakresu

‘RIGHT - zwraca prawą granicę zakresu

‘RANGE - zwraca zakres typu

type licznik is integer range 0 to 127;

Przykłady:

licznik’left = 0

licznik’ right = 127

If Clock’event and Clock = ‘1’ then Q := D;

Style opisu architektury

1.Styl behawioralny – behavioral (opis działania)

•

algorytmiczny opis sekwencji stanow, z użyciem procesu i instrukcji sekwencyjnych

•

przepływowy - opis przepływu danych podczas przetwarzania,

instrukcje wspołbieżne, rownania boolowskie; także opis układow sekwencyjnych z rejestrami – styl RTL – Register Transfer Logic 2.Styl strukturalny

(opis budowy, czyli zapis połączeń komponentow )

Instrukcje wspołbieżne (Concurrent assignment statement)

Przykład projektu wykorzystującego instrukcje wspołbieżne to znaczy takie, ktorych kolejność występowania w projekcie nie wpływa na działanie końcowe układu. (Operator przypisania do sygnału <=).

library ieee;

use ieee.std_logic_1164.all;

entity and_or_4 is

port ( A,B,C,D : in std_logic;

Y0, Y1 : out std_logic);

end and_or_4;

architecture f1 of and_or_4 is

begin

y0 <= a and b and c and d; -- pamiętajmy VHDL nie rozrożnia wielkich Y1 <= A or B or C or D; -- i małych liter

end f1;

Inne instrukcje wspołbieżne:

with - select

with wybor select

sygnal <= wyrazenie1 when wartosc_wyboru1,

sygnal <= wyrazenie2 when wartosc_wyboru2,

........................................................................, sygnal <= wyrazenieN when wartosc_wyboruN,

sygnal <= wyrazenie_koncowe when others;

Przypisanie warunkowe when-else

sygnal <= wyrazenie1 when warunek1A [and | or warunek1B] else wyrazenie2 when warunek2A [and | or warunek2B] else

.......................................................................................

wyrazenieN when warunekNA [and | or warunekNB] else

wyrazenie_koncowe;

Przykład instrukcji wspołbieżnej with – select – dekoder 7-segmentowy library ieee ;

use ieee.std_logic_1164.all;

entity wyswietlacz is

port ( count_in: in std_logic_vector (4 downto 0);

LED: out std_logic_vector (6 downto 0));

end ;

Architecture zachowanie of wyswietlacz is

begin

with count_in Select

LED<=

"1111001" when "0001", --1

"0100100" when "0010", --2

"0110000" when "0011", --3

"0011001" when "0100", --4

"0010010" when "0101", --5

"0000010" when "0110", --6

"1111000" when "0111", --7

"0000000" when "1000", --8

"0010000" when "1001", --9

"0001000" when "1010", --A

"0000011" when "1011", --B

"1000110" when "1100", --C

"0100001" when "1101", --d

"0000110" when "1110", --E

"0001110" when "1111", --F

"1000000" when others; --0

end zachowanie

Przykład instrukcji wspołbieżnych with – select oraz when- else multiplekser entity multiplekser is -- jednostka o nazwie 'multiplekser'

port( i0,i1,i2,i3 : in bit; -- deklaracja wejść

s1,s0 : in bit; -- deklaracja wejść sterujących

Y :out bit); -- deklaracja wyjścia

end multiplekser;

architecture cialo of multiplekser is -- architektura o nazwie 'opis' opisująca jednostką multiplekser

signal wybor : integer range 0 to 3; -- deklaracja sygnału pomocniczego o nazwie 'wybor'

-- 'wybor' jest liczba całkowita z zakresu od 0 do 3

begin

with wybor select

Y <= i0 when 0,

i1 when 1,

i2 when 2,

i3 when others;

wybor <=

0 when s1='0' and s0='0' else

1 when s1='0' and s0='1' else

2 when s1='1' and s0='0' else

3;

end cialo;

Przykład realizacji 8-bitowego rejestru dwukierunkowego-

instrukcje wspołbieżne when- else

library ieee;

use ieee.std_logic_1164.all;

entity dataexch is

port ( busAdata : INOUT std_logic_vector (7 downto 0);

busBdata : INOUT std_logic_vector (7 downto 0);

busCdata : INOUT std_logic_vector (7 downto 0);

busDdata : INOUT std_logic_vector (7 downto 0);

oe0, oe1 : IN std_logic)

end dataexch;

architecture behave of dataexch is

begin

busAdata <= busBdata when oe0 = '1' else "ZZZZZZZZ"; busBdata <= busAdata when oe0 = '0' else "ZZZZZZZZ"; busCdata <= busDdata when oe1 = '1' else "ZZZZZZZZ"; busDdata <= busCdata when oe1 = '0' else "ZZZZZZZZ"; end behave;

Instrukcja procesu – process - stosowana jako instrukcja wspołbieżna zawiera w sobie instrukcje sekwencyjne to znaczy takie, ktorych kolejność występowania ma wpływ na realizacje układu. Niekiedy process wykorzystuje się również gdy kolejność występowania nie ma wpływu na działanie układu , ale ułatwia to opis układu.

[etykieta_procesu:] process [(lista_wrazliwosci)][is][czesc_deklaracyjna]

begin

{instrukcje_sekwencyjne;}

end process [etykieta_procesu];

Lista wrażliwości zawiera etykiety sygnałow, ktore powodują wykonanie instrukcji sekwencyjnych wewnątrz procesu, gdy tylko ktorykolwiek z nich zmieni wartość. Lista ta jest opcjonalna, lecz gdy jej nie ma, to musi być wprowadzona wewnątrz procesu sekwencyjna instrukcja czekania wait. Etykieta procesu służy tylko do polepszenia czytelności zapisu. W części deklaracyjnej mogą być umieszczone deklaracje typow (type), stałych (constant) i zmiennych lokalnych (variable).

Procesy nie mogą być zagnieżdżane.

INSTRUKCJE SEKWENCYJNE

•

Służą do opisu procesow oraz podprogramow (procedury, funkcje) :

•

Przypisanie <=

•

Wywołanie procesu

•

przypisanie do zmiennej (:=)

•

instrukcja warunkowa if-then-else

•

instrukcja wyboru case

•

instrukcja czekania wait

•

instrukcja pętli loop i związane instrukcje exit i next instrukcja pusta null

•

instrukcja testowa assert

If-then-else

Sekwencyjny odpowiednik wspołbieżnej instrukcji przypisania warunkowego when-else, ktorej nie można stosować w obrębie procesu ani podprogramu.

Składnia:

if warunek1 then {instrukcja sekwencyjna1;}

elsif warunek2 then {instrukcja sekwencyjna2;}

elsif warunek3 then {instrukcja sekwencyjna2;}

........................................................................

else {instrukcja sekwencyjnaN;}

end if;

Wynik warunku jest typu boolean (false lub true) . Gdy warunek jest spełniony (true), to wykonywana jest sekwencja instrukcji następująca bezpośrednio po słowie then. W

przeciwnym razie (else) wykonywana jest inna sekwencja albo sprawdzany jest kolejny warunek (elsif warunek then) i tak dalej.

Sprawdzanie warunkow następuje kolejno, a więc kolejność warunkow określa odpowiednio priorytet.

Przykład komparatora dwóch liczb 4 bitowych

entity COMP is

port (O1 : out std_logic;

O2 : out std_logic;

IN0 : in std_logic_vector (3 downto 0);

IN1 : in std_logic_vector (3 downto 0)); end COMP;

architecture IMP_COMP of COMP is begin

F_COM : process (IN0,IN1)

begin -- process FUNCTION_GT

if IN0 > IN1 then

O1 <= '1';

O2 <= '0':

elsif IN0 < IN1 then

O1 <= '0';

O2 <= '1':

else

O1 <= '0';

O2 <= '0':

end if;

end process F_COM;

end IMP_COMP;

case

Odpowiednik wspołbieżnej instrukcji przypisania selektywnego with-select-when.

Składnia:

case wyrazenie is when wybor1 => {instrukcja sekwencyjna1;}

when wybor2 => {instrukcja sekwencyjna2;}

....................................................................

when wyborN => {instrukcja sekwencyjnaN;}

when others => {instrukcja sekwencyjnaK;}

end case;

Wybor jest pojedynczą wartością wyrażenia albo grupą takich wartości.

Przy opisie należy wymienić wszystkie wzajemnie wyłączające się wartości, albo dla wartości nieużywanych wprowadzić zapis

when others => sekwencja_instrukcji;

lub

when others => null; -- brak działania

Sprawdzanie wartości wyboru następuje rownolegle (jednocześnie), czyli żadna z nich nie ma priorytetu względem innych .

Przykład multipleksera 2 wejsciowego (a,b) z sygnałem wyboru s library ieee ;

use ieee.std_logic_1164.all;

entity mux2x1vhd is

port ( z: out std_logic;

a, b, s: in std_logic );

end ;

architecture mux2x1_arch of mux2x1vhd is

begin

process (s, a, b)

begin

case s is

when '0' =>

z <= a;

when '1' =>

z <= b;

when others =>

z <= 'X';

end case ;

end process ;

end mux2x1_arch;

Przykład demultipleksera 8- wyjściowego z trzema sygnałami enable .E3 aktywny '1' ,a N_E2 i N_E1 aktywne '0'

loop

Pętla loop umożliwia zapis powtarzania sekwencji instrukcji.

Wyrożniamy trzy rodzaje pętli: for, while i pętle nieskończone

Jeśli liczba obiegow pętli jest z gory znana, stosujemy instrukcję for-loop

[etykieta:] for parametr in zakres loop

{instrukcja sekwencyjna;}

end loop [etykieta];

parametr określa zakres i kierunek indeksowania (to lub downto).

Przykład, XOR poszczegolnych bitow wektora A i C można opisać:

for x in 0 to A′length - 1 loop

B(i) <= A(i) xor C(i); -- B zawiera xor-a bitow A i C

end loop;

Indeks i nie musi być odrębnie deklarowany i jest rozpoznawany wyłącznie w obrębie tej instrukcji. Atrybut ′length umożliwia identyfikację długości wektora.

Jeśli liczba iteracji zależy od wyniku sprawdzania warunku przed powtorzeniem pętli, to stosuje się instrukcję while-loop

[etykieta:] while warunek loop

{instrukcja sekwencyjna;}

end loop [etykieta];

Instrukcja exit[etykieta_petli][when warunek];

służy do wyjścia z pętli, jeśli warunek jest spełniony. Można zrezygnować z opcji

[when warunek], ale oznacza to bezwarunkowe wyjście z pętli przy pierwszym napotkaniu słowa exit podczas wykonywania instrukcji.

Warunek można też wprowadzić stosując instrukcję warunkową if-then: if warunek then exit;

end if;

Instrukcja next [etykieta_petli][when warunek];

służy do zakończenia wykonywania bieżącej iteracji pętli i przejście do następnej, jeśli warunek jest spełniony. Jednocześnie indeks pętli zwiększa się o jeden.