CAD Języki opisu sprzętu VHDL rawski@tele.pw.edu.pl http://rawski.zpt.tele.pw.edu.pl/
Języki opisu sprzętu System cyfrowy może być opisany na różnych poziomach abstrakcji i z wykorzystaniem różnych sposobów reprezentacji. Wraz z postępem procesu projektowego może to ulegać zmianie. Wymagany jest sposób reprezentacji projektowanego systemu tak, by można było wymieniać informacje o projektowanym systemie między członkami grupy projektowej i komputerowymi narzędziami wspomagania projektowania CAD. Języki opisu sprzętu HDL (Hardware Description Languages) służą temu celowi. 2
Ograniczenia tradycyjnych języków programowania Tradycyjne języki programowania ogólnego przeznaczenia modelują proces sekwencyjny. W procesie sekwencyjnym operacje wykonywane są w kolejności jedna na jednostkę czasową. Operacje często zależą od wyników wcześniej wykonanych operacji, kolejność wykonania nie może zostać zmieniona kolejność operacji ma znaczenie. Zalety: możliwość tworzenia algorytmu krok po kroku, proces sekwencyjny odpowiada sposobowi działania komputerów. Sposób działania systemu cyfrowego jest całkowicie inny niż w modelu sekwencyjnym: wiele mniejszych elementów połączonych w sieć, zmiany sygnałów aktywują połączone z nimi elementy do wykonania operacji, operacje wykonywane współbieżnie. 3
Zastosowania języków HDL Program HDL wykorzystywany jest do: dokumentacji specyfikacja formalna sytemu i dokumentacja dla celów wymiany informacji między projektantami, użytkownikami i systemami CAD, symulacji dla celów weryfikacji działania projektowanego układu bez konieczności jego realizacji; symulator HDL pozwala modelować współbieżne operacje; program HDL wraz z generatorem testów i kodem kolekcjonującym odpowiedzi tworzy tzw. testbench który wykorzystywany jest przez symulator HDL do weryfikacji działania projektowanego układu, syntezy nowoczesny proces projektowy oparty jest na koncepcji transformacji wysokopoziomowego opisu funkcjonalnego na niskopoziomowy opis strukturalny; niektóre z etapów przekształcania opisu projektu mogą być wykonywane przez oprogramowanie do syntezy; oprogramowanie takie na podstawie kodu HDL realizuje projektowany układ z wykorzystanie elementów z biblioteki; wynikiem jest kod HDL opisujący strukturę syntetyzowanego układu. 4
Cechy języka HDL Charakterystyka układu cyfrowego opiera się na pojęciach jednostki projektowej, połączenia, współbieżności i zależności czasowych. Podstawowe cechy nowoczesnego języka HDL to: semantyka zawierająca koncepcję jednostki projektowej, połączenia, współbieżności i zależności czasowych, możliwość opisu opóźnienia w propagacji sygnału i zależności czasowych, konstrukcje umożliwiające opis realizacji strukturalnej, udostępnianie instrukcji umożliwiających opis funkcjonalny układu w sposób znany z tradycyjnych języków programowania możliwość efektywnego opisu operacji i struktur danych na poziomie bramek i przesłań między rejestrowych, posiadanie konstrukcji umożliwiających projektowania w sposób hierarchiczny. 5
VHDL Very high speed integrated Hardware Description Language Przyjęty jako przemysłowy standard języka HDL (IEEE Std 1076) Modyfikowany w 1987, 1993 i 2001 (VHDL-87, -93, -2001) Rozszerzenia (wybrane): IEEE Std 1076.2-1996, VHDL Mathematical Packages definiuje dodatkowe funkcje matematyczne dla liczb rzeczywistych i zespolonych, IEEE Std 1076.3-1997, Synthesis Packages definiuje arytmetyczne operacje na zestawach bitów, IEEE Std 1076.6-1999, VHDL Register Transfer Level (RTL) Synthesis definiuje podzbiór języka odpowiedni dla procesów syntezy, IEEE Std 1164-1993 Multivalue Logic System for VHDL Modeling Interoperability (st_logic_1164) definiuje nowe typy danych dla celów modelowania logiki wielowartościowej, IEEE Std 1029.1-1998 VHDL Waveform and Vector Exchange to Support Design and Test Verification (WAVES) definiuje sposób wykorzystania języka VHDL do wymiany danych w środowisku symulacyjnym. 6
Podstawowe koncepcje języka VHDL Przykład Układ detektora parzystości: wejścia x 2, x 1, x 0, wyjście even Wejścia zgrupowane w szynę Wyjście aktywne, gdy w wektorze wejściowym jest parzysta liczba jedynek (0 lub 2) x 2 x 1 x 0 even 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 0 1 1 1 1 0 Wyrażenie boolowskie opisujące układ even = x 2 x 1 x 0 + x 2 x 1 x 0 + x 2 x 1 x 0 + x 2 x 1 x 0 7
Opis ogólny SOP (Sum-of-Product) library ieee; use ieee.std_logic_1164.all; -- deklaracja jednostki entity even_detector_sop is port( x : in std_logic_vector(2 downto 0); even : out std_logic ); end even_detector_sop ; -- definicja architektury architecture sop_arch of even_detector_sop is signal p1, p2, p3, p4 : std_logic; p1 <= (not x(2)) and (not x(1)) and (not x(0)); p2 <= (not x(2)) and x(1) and x(0); p3 <= x(2) and (not x(1)) and x(0); p4 <= x(2) and x(1) and (not x(0)); even <= p1 or p2 or p3 or p4; end sop_arch; Wykorzystywane biblioteki Deklaracja jednostki projektowej Specyfikuje wejścia i wyjścia układu. Opisuje interfejs projektowanego urządzenia. X 3 Architektura układu Między słowami kluczowymi i end specyfikuje działania i wewnętrzną organizację układu. Architektura skojarzona jest z konkretną jednostką projektową : architecture sop_arch of even_detector_sop is even 8
Koncepcja realizacji architektury SOP library ieee; use ieee.std_logic_1164.all; Wprowadzenie sygnałów wejściowych do wnętrza układu -- deklaracja jednostki entity even_detector_sop is port( x : in std_logic_vector(2 downto 0); even : out std_logic ); end even_detector_sop ; -- definicja architektury architecture sop_arch of even_detector_sop is signal p1, p2, p3, p4 : std_logic; p1 <= (not x(2)) and (not x(1)) and (not x(0)); p2 <= (not x(2)) and x(1) and x(0); p3 <= x(2) and (not x(1)) and x(0); p4 <= x(2) and x(1) and (not x(0)); even <= p1 or p2 or p3 or p4; end sop_arch; Deklaracja sygnałów połączeń między wewnętrznymi elementami X 3 x(2) x(1) x(0) (not x(2)) and (not x(1)) and (not x(0)) (not x(2)) and x(1) and x(0); x(2) and (not x(1)) and x(0); x(2) and x(1) and (not x(0)) Współbieżne operacje wyobrażają części układu działające równolegle w układzie. Połączone przy wykorzystaniu sygnałów tworzą sieć. Kolejność tych operacji nie ma znaczenia p1 p2 p3 p4 p1 or p2 or p3 or p4 even 9
Działania architektury SOP Inaczej niż w przypadku wykonania instrukcji w tradycyjnym języku programowania, operacje współbieżne są niezależne i mogą być aktywowane równolegle. Gdy tylko wejścia takiej operacji się zmienią operacja się budzi i oblicza odpowiedź na nowe wartości wejściowe. Wynik obliczeń jest widoczny na wyjściu z pewnym opóźnieniem. Zmiana sygnału wyjściowego może z kolei aktywować dalsze elementy układu. Zmiana na wejściach układu uruchamia elementy układu, które generują nowe odpowiedzi pobudzając do działania kolejne części systemu 10
Wynik kompilacji kodu VHDL Dokładnie jak zapisaliśmy. 11
Koncepcja realizacji architektury XOR library ieee; use ieee.std_logic_1164.all; Wprowadzenie sygnałów wejściowych do wnętrza układu -- deklaracja jednostki entity even_detector_xor is port( x : in std_logic_vector(2 downto 0); even : out std_logic ); end even_detector_xor ; -- definicja architektury architecture xor_arch of even_detector_xor is signal odd : std_logic; odd <= x(2) xor x(1) xor x(0); even <= not odd; end xor_arch ; Deklaracja sygnału połączeń między wewnętrznymi elementami X 3 x(2) x(1) x(0) x(2) xor x(1) xor x(0) odd not odd even Współbieżne operacje wyobrażają części układu działające równolegle w układzie 12
Wynik kompilacji kodu VHDL Dokładnie jak zapisaliśmy. 13
Opis strukturalny library ieee; use ieee.std_logic_1164.all; -- deklaracja jednostki entity even_detector_str is port( x : in std_logic_vector(2 downto 0); even : out std_logic ); end even_detector_str ; -- definicja architektury architecture structure of even_detector_str is -- deklaracja komponentow component not1 port( i1 : in std_logic; o1 : out std_logic ); end component; -- konkretyzacja pierwszej bramki xor xorgate1 : xor2 port map(i1 => x(2), i2 => x(1), o1 => s1); -- konkretyzacja drugiej bramki xor xorgate2 : xor2 port map(i1 => x(0), i2 => s1, o1 => s2); -- konkretyzacja bramki not notgate1 : not1 port map(i1 => s2,o1 => even); end structure ; Konkretyzacja komponentów component xor2 port( i1, i2 : in std_logic; o1 : out std_logic ); end component; signal s1, s2 : std_logic; X 3 x(2) x(1) x(0) Deklaracja komponentów i1 i2 xor2 o1 i1 i2 xor2 o1 i1 not1 o1 even 14
Opis strukturalny library ieee; use ieee.std_logic_1164.all; -- deklaracja jednostki entity not1 is port( i1 : in std_logic; o1 : out std_logic ); end not1 ; library ieee; use ieee.std_logic_1164.all; -- deklaracja jednostki entity xor2 is port( i1, i2 : in std_logic; o1 : out std_logic ); end xor2 ; -- definicja architektury architecture structure of not1 is o1 <= not i1; end structure ; end structure ; -- definicja architektury architecture structure of xor2 is o1 <= i1 xor i2; Konkretyzacja komponentów jest jedną z instrukcji współbieżnych Architektura zawierająca jedynie instrukcje konkretyzacji jest swoistym sposobem tekstowego opisu schematu blokowego Komponent może być istniejącym modułem lub hipotetycznym systemem, którey jest jeszcze niezaprojektowany Opis strukturalny pozwala na projektowanie hierarchiczne złożony system może być podzielony na mniejsze podsystemy, które są projektowane niezależnie i które mogą być dalej dzielone. Strukturalna reprezentacja pozwala opisać rezultat syntezy sieć bramek lub komórek 15
Wynik kompilacji kodu VHDL Dokładnie jak zapisaliśmy. Jest nawet zachowana hierarchia. 16
Abstrakcyjny opis funkcjonalny W przypadku dużych systemów implementacja może być bardzo skomplikowana W początkowej fazie projektowania istnieje raczej potrzeba zbadania działania projektowanego systemu niż wymóg stworzenia rzeczywistego układu Z tego względu, iż rozumowanie człowieka przypomina proces sekwencyjny, lepiej to odzwierciedlają klasyczne języki programowania VHDL udostępnia konstrukcję reprezentującą sekwencyjny proces z możliwością zastosowania zmiennych process (lista_czułości) variable definicja; instrukcje sekwencyjne; end process; Lista czułości zawiera sygnały, których zmiana aktywuje proces Instrukcje wewnątrz procesu są podobne do tradycyjnych języków programowania Można wykorzystywać zmienne a wykonanie instrukcji jest sekwencyjne 17
Opis funkcjonalny library ieee; use ieee.std_logic_1164.all; -- deklaracja jednostki entity even_detector_beh1 is port( x : in std_logic_vector(2 downto 0); even : out std_logic ); end even_detector_beh1 ; X 3 x(2) x(1) x(0) process (x) variable tmp : std_logic; tmp := '0'; for i in 2 downto 0 loop tmp := tmp xor x(i); end loop; odd <= tmp; end process; not odd even -- definicja architektury architecture behavior of even_detector_beh1 is -- deklaracja sygnalu signal odd : std_logic; even <= not odd; process (x) variable tmp : std_logic; tmp := '0'; for i in 2 downto 0 loop tmp := tmp xor x(i); end loop; odd <= tmp; end process; end behavior ; Jak mam zdecydować o tym czy liczba jedynek w wektorze binarnym jest parzysta to sprawdzając kolejne bity, z każdym razem gdy znajdę jedynkę zmieniam decyzję. Proces opisujący sposób obliczenia nieparzystości liczby jedynek w wektorze wejściowym 18
Wynik kompilacji kodu VHDL x(0) x(2) x(0) Wygląda to dobrze. 19
Opis funkcjonalny library ieee; use ieee.std_logic_1164.all; -- deklaracja jednostki entity even_detector_beh2 is port( x : in std_logic_vector(2 downto 0); even : out std_logic ); end even_detector_beh2 ; -- definicja architektury architecture behavior of even_detector_beh2 is process (x) variable sum, r : integer; sum := 0; for i in 2 downto 0 loop if (x(i) = '1') then sum := sum + 1; end if; end loop; r := sum mod 2; if (r = 0) then even <= '1'; else even <= '0'; end if; end process; end behavior ; X 3 x(2) x(1) x(0) Proces opisujący sposób obliczenia nieparzystości liczb jedynek w wektorze wejściowym process (x) variable sum, r : integer; sum := 0; for i in 2 downto 0 loop if (x(i) = '1') then sum := sum + 1; end if; end loop; r := sum mod 2; if (r = 0) then even <= '1'; else even <= '0'; end if; end process; Wystarczy policzyć ile jest jedynek w wektorze i liczbę która wyjdzie wziąć modulo 2. Jak będzie 0 tzn. parzysta jak nie to nieparzysta even 20
Wynik kompilacji kodu VHDL Jak to właściwie działa? 21
Testbench Jednym z podstawowych zastosowań języka VHDL jest symulacja, gdzie bada się działanie układu dla zweryfikowania poprawności projektu. Symulację można porównać do badania fizycznego układu, którego wejścia podłączamy do stymulatora (generatora testów) i obserwujemy wyjścia. Symulacja kodu VHDL to wykonywanie wirtualnego eksperymentu, w którym fizyczny układ zastąpiono opisem VHDL. Dodatkowo można wykorzystać VHDL do opisu generatora testów i modułu kolekcjonującego odpowiedzi układu i porównującego je ze wzorcem. Mechanizm taki nosi nazwę testbench process test_vector <= "000"; test_vector <= "001"; test_vector <= "010"; test_vector <= "011"; test_vector <= "100"; test_vector <= "101"; test_vector <= "110"; test_vector <= "111"; end process; UUT (Unit Under Test) process variable error_response : boolean; wait on test_vector; if ((test_vector = "000" and response = '1') or (test_vector = "001" and response = '0') or (test_vector = "010" and response = '0') or (test_vector = "011" and response = '1') or (test_vector = "100" and response = '0') or (test_vector = "101" and response = '1') or (test_vector = "110" and response = '1') or (test_vector = "111" and response = '0')) then error_response := false; else error_response := true; end if; -- raportowanie bledu assert not error_response report "Test zakonczyl sie niepowidzeniem." severity note; end process; end testbench; 22
Testbench entity even_detector_testbench is end even_detector_testbench; architecture testbench of even_detector_testbench is -- deklaracja modulu poddanego testowi component even_detector port ( x : in std_logic_vector (2 downto 0); even : out std_logic ); end component; -- deklaracja sygnalow testow i odpowiedzi signal test_vector : std_logic_vector (2 downto 0); signal response : std_logic; -- konkretyzacja modułu poddanego testowi uut : even_detector port map (x => test_vector, even => response); -- generator testow process test_vector <= "000"; test_vector <= "001"; test_vector <= "010"; test_vector <= "011"; test_vector <= "100"; test_vector <= "101"; test_vector <= "110"; test_vector <= "111"; end process; -- weryfikator process variable error_response : boolean; wait on test_vector; if ((test_vector = "000" and response = '1') or (test_vector = "001" and response = '0') or (test_vector = "010" and response = '0') or (test_vector = "011" and response = '1') or (test_vector = "100" and response = '0') or (test_vector = "101" and response = '1') or (test_vector = "110" and response = '1') or (test_vector = "111" and response = '0')) then error_response := false; else error_response := true; end if; -- raportowanie bledu assert not error_response report "Test zakonczyl sie niepowidzeniem." severity note; end process; end testbench; Konkretyzacja modułu poddawanego testowi i deklaracja sygnałów testów i odpowiedzi. Generator testów generuje kolejne wektory testowe w zadanym rytmie Weryfikator porównuje odpowiedzi modułu poddawanego testowi ze wzorcami i w razie wykrycia niezgodności generuje raport 23
Konfiguracja W języku VHDL istnieje możliwość przypisania do jednostki projektowej entity wielu architektur Na etapie symulacji czy syntezy można wybrać która architektura ma być podłączona do jednostki projektowej. entity architecture architecture architecture configuration config of even_detector_testbench is for testbench for uut : even_detectod use entity work.even_detrector(xor_arch); end for; end for; end config; 24