Politechnika Białostocka Wydział Elektryczny Katedra Automatyki i Elektroniki ĆWICZENIE Nr 9 (3h) Projekt struktury hierarchicznej układu cyfrowego w FPGA. Instrukcja pomocnicza do laboratorium z przedmiotu Synteza układów cyfrowych ES2C100005 studiów stacjonarnych II stopnia kierunku: Elektrotechnika Opracował: dr inż. Walenty Owieczko dr inż. Marian Gilewski Białystok 2013
1. Cel ćwiczenia. W tym ćwiczeniu zastosujemy bardziej złożone aplikacje układów sekwencyjnych w kodzie VHDL. Ze względu na złożoność projektów należy zastosować struktury hierarchiczne, w których plik top-level będzie zrealizowany w postaci schematu lub kodu VHDL. Projekty złożonych systemów cyfrowych w strukturach programowalnych trudno jest definiować w postaci pojedyńczego pliku graficznego schematu lub kodu źródłowego VHDL. W tym celu dokonuje się dekompozycji złożonej struktury na mniejsze bloki funkcjonalne, opisując ich wewnętrzne struktury w oddzielnych komponentach. Połączenia pomiędzy komponentami definiuje się w pliku top-level. Zatem złożoną strukturę hierarchiczną stanowią: pliki komponentów, połączenia między nimi oraz plik top-level. W praktyce zagadnie może być jeszcze bardziej złożone, gdyż poszczególne komponenty, których połączenia są widoczne w top-level, mogą składać się z własnych struktur hierarchicznych. Nie komplikując bardziej zagadnienia, prześledźmy proces tworzenia struktury na poniższym przykładzie. Załóżmy, że należy zaprojektować układ sumujący dwie czterobitowe liczby binarne i wyświetlający wynik na dwucyfrowym wyświetlaczu siedmiosegmentowym. Dokonajmy dekompozycji układu na komponenty w sposób następujący: - komponent Suma dodający dwie liczby 4 bitowe liczby binarne i podający wynik w postaci 5 bitowej liczby binarnej; - komponent Dekoder dokonujący konwersji 5 bitowego wyniku sumowania na 2 cyfrową liczbę w kodzie BCD, - komponent Segment dokonujący konwersji pojedyńczej cyfry w kodzie BCD na kod wskaźnika siedmiosegmentowego. Niech komponent Suma będzie zdefiniowany następującym kodem źródłowym w VHDL: library ieee; use ieee.numeric_std.all; entity Suma is port ( A, B : in unsigned(3 downto 0); -- czynnik pierwszy Wynik : out unsigned(4 downto 0)); -- suma end entity; architecture rtl of Suma is signal AA, BB : unsigned(4 downto 0) := "00000"; begin AA(3 downto 0) <= A; AA(4) <= '0'; BB(3 downto 0) <= B; BB(4) <= '0'; Wynik <= AA + BB; end rtl; Następnie funkcją: File -> Create/Update -> Create Symbol Files for Current File, wygenerujmy graficzny symbol biblioteczny komponentu. Plik symbolu graficznego jak i odpowiadający mu kod źródłowy znajdują się w katalogu roboczym Project.
W analogiczny sposób zdefiniujmy komponent Dekoder, którego przykładowy kod źródłowy przedstawiono na poniższym listingu: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Dekoder is port ( Z_Iloczynu : in unsigned(4 downto 0); -- wejści wyniku mnozenia BCD_1 : out unsigned(3 downto 0); -- starsza cyfra BCD BCD_0 : out unsigned(3 downto 0)); -- mlodsza cyfra BCD end entity; architecture rtl of Dekoder is signal Tmp : unsigned(7 downto 0) := "00000000"; begin with Z_iloczynu select Tmp <= "00000000" when "00000", -- 00 "00000001" when "00001", -- 01 "00100000" when "11110", -- 30 "00000000" when others; BCD_1 <= Tmp(7 downto 4); BCD_0 <= Tmp(3 downto 0); end rtl; oraz kod komponentu Segment: library ieee; use ieee.std_logic_1164.all; entity Segment is port ( Z_wyj_BCD : in std_logic_vector(3 downto 0); -- wejsciowa cyfra BCD Na_7segm : out std_logic_vector(6 downto 0)); -- cyfra 7-seg "gfedcba" end entity; architecture rtl of Segment is begin with Z_wyj_BCD select Na_7segm <= "1000000" when "0000", -- 0 "0000110" when "0001", -- 1 "1111000" when "0111", -- 7 "0000000" when "1000", -- 8 "0010000" when "1001", -- 9 "1111111" when others; end rtl;
Po przygotowaniu komponentów należy utworzyć plik top-level opisujący połączenia między nimi. Można to zrobić w postaci pliku źródłowego VHDL używając instrukcji PORT MAP lub w postaci pliku graficznego korzystając z symboli graficznych komponentów. W omawianym przypadku zastosujemy drugą wersję tworząc poniższy schemat: Na platformie projektowej Quartus można automatycznie wygenerować ze schematu plik toplevel w postaci kodu źródłowego VHDL lub Verilog. W tym celu należy wykonać funkcję: File -> Create/Update -> Create HDL Design File for Current File W przedstawionym przykładzie kod źródłowy VHDL pliku top-level wygenerowanego automatycznie jest następujący: -- PROGRAM "Quartus II" -- VERSION "Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Web Edition" -- CREATED "Sun Jan 27 17:10:16 2013" LIBRARY ieee; USE ieee.std_logic_1164.all; LIBRARY work; ENTITY hierarchia IS PORT ( Liczba_A : IN STD_LOGIC_VECTOR(3 DOWNTO 0); Liczba_B : IN STD_LOGIC_VECTOR(3 DOWNTO 0); Mlodsza_cyfra : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); Starsza_cyfra : OUT STD_LOGIC_VECTOR(6 DOWNTO 0) ); END hierarchia; ARCHITECTURE bdf_type OF hierarchia IS COMPONENT suma -- deklaracja komponentu PORT ( A : IN STD_LOGIC_VECTOR(3 DOWNTO 0); B : IN STD_LOGIC_VECTOR(3 DOWNTO 0); Wynik : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)); END COMPONENT; COMPONENT dekoder -- deklaracja komponentu PORT (Z_Iloczynu : IN STD_LOGIC_VECTOR(4 DOWNTO 0); BCD_0 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); BCD_1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT;
COMPONENT segment -- deklaracja komponentu PORT (Z_wyj_BCD : IN STD_LOGIC_VECTOR(3 DOWNTO 0); Na_7segm : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END COMPONENT; -- deklaracja sygnałów wewnętrznych - łączących komponenty SIGNAL SYNTHESIZED_WIRE_0 : STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL SYNTHESIZED_WIRE_1 : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL SYNTHESIZED_WIRE_2 : STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN -- łączenie komponentów b2v_inst : suma PORT MAP (A => Liczba_A, B => Liczba_B, Wynik => SYNTHESIZED_WIRE_0); b2v_inst1 : dekoder PORT MAP(Z_Iloczynu => SYNTHESIZED_WIRE_0, BCD_0 => SYNTHESIZED_WIRE_2, BCD_1 => SYNTHESIZED_WIRE_1); b2v_inst2 : segment PORT MAP(Z_wyj_BCD => SYNTHESIZED_WIRE_1, Na_7segm => Starsza_cyfra); b2v_inst3 : segment PORT MAP(Z_wyj_BCD => SYNTHESIZED_WIRE_2, Na_7segm => Mlodsza_cyfra); END bdf_type; Powyższy kod źródłowy można napisać ręcznie korzystając z instrukcji VHDL. Metoda automatyczna jest wygodna przy generowaniu opisu projektów tylko w kodzie VHDL, przenoszonych pomiędzy różnymi platformami projektowymi, np. Quartus i ISE. Projektów opisanych plikami graficznymi schematycznie, nie można przenosić pomiędzy środowiskami projektowymi różnych firm, projekty w postaci kodów źródłowych pomiędzy wszystkimi. Ważne jest, żeby definicje (pliki) komponentów były widoczne dla kompilatora, tzn. znajdowały się w katalogu roboczym projektu, w bibliotece wywoływanej z top-level lub na końcu kodu źródłowego pliku top-level. 2. Część pierwsza. Zaprojektuj generator PWM w module DE2 o następujących właściwościach: 1. Układ powinien wykorzystywać wbudowany generator kwarcowy 50MHz, 2. Częstotliwość generatora PWM powinna wynosić 1 khz, 3. Przełącznikami SW 0 SW 7 należy zadawać proporcjonalnie wartość współczynnika wypełnienia w przedziale od 5% do 95%, 4. Zatem układ powinien posiadać oprócz pliku top-level komponenty niższego poziomu: dzielnik częstotliwości, dekoder na wyświetlacze 7 segmentowe, moduł PWM. 5. Układ należy zasymulować i zaimplementować, 6. Efekt działania należy zaobserwować na diodach LED oraz zmierzyć oscyloskopem. 3. Część druga. Wykorzystując doświadczenia z części pierwszej niniejszego ćwiczenia należy rozbudować układ generatora PWM do postaci uniwersalnej i zaimplementować DE2, tak, aby: 1. Przełącznikami SW9 9 SW 8 można było dodatkowo wybierać częstotliwość sygnału PWM: 100kHz, 10kHz, 1kHz, 100Hz, 10Hz, 2. Przełącznikami SW 0 SW 7 można było zadawać współczynnik wypełnienia impulsu zaczynając od wartości 5%, 3. Układ należy zasymulować i zaimplementować, 4. Efekt działania należy zaobserwować na diodach LED oraz zmierzyć oscyloskopem.
4. Część trzecia. Proszę rozbudować strukturę hierarchiczną z części drugiej w taki sposób, żeby był możliwy bieżący odczyt częstotliwości sygnału PWM w przedziale 100 Hz do 100 khz. Tzn. należy zbudować komponent częstościomierza. Układ należy zaimplementować w module DE2 i zbadać, stosując jako źródło sygnału dodatkowy moduł DE2 studentów sąsiedniego zespołu. 5. Część czwarta. Proszę rozbudować strukturę hierarchiczną z części trzeciej w taki sposób, żeby był możliwy bieżący odczyt współczynnika wypełnienia sygnału PWM. Układ należy zaimplementować w module DE2 i zbadać, stosując jako źródło sygnału dodatkowy moduł DE2 studentów sąsiedniego zespołu. Literatura: 1. Barski M., Jędruch W.: Układy cyfrowe, podstawy projektowania i opisu w języku VHDL, Wydawnictwo Politechniki Gdańskiej, 2007. 2. IEEE-SA Standars Board: IEEE Standard VHDL Language reference manual, ieeexplore.ieee.org/iel5/7180/19335/00893288.pdf, USA, 2000. 3. Łuba T.: Synteza układów cyfrowych, WKiŁ, Warszawa, 2004. 4. Mano M.M., Kime Ch.R.: Podstawy projektowania układów logicznych i komputerów, NT, Warszawa 2007. 5. Skahill K.: Język VHDL Projektowanie programowalnych układów logicznych, WNT, Warszawa, 2001.