FPGA Budowa sterownika do wyświetlacza 7-segmentowego przy użyciu bramek 1. Opis projektu tworzonego w dalszej części instrukcji Celem ćwiczenia jest zapoznanie się ze sposobem projektowania układów logicznych na podstawie opisu funkcji zapisanej w tablicy prawdy. Po raz kolejny zaprojektujemy dekoder kodu BCD na kod wyświetlacza siedmiosegmentowego. Tym razem, utworzony projekt będzie optymalny pod względem wykorzystywanych zasobów układu FPGA. Tutorial składa się z następujących etapów: - zdefiniowania tablicy prawdy; - zdefiniowania tablicy Karnaugh i wyznaczenia funkcji logicznej (dla każdego segmentu osobno); - utworzenia projektu w programie Active-HDL; - dołączenia do projektu istniejących schematów i ich uzupełnienia; - przeprowadzenia symulacji projektu; - implementacji projektu; - zaprogramowania układu FPGA; - zweryfikowania poprawnego działania projektu na płycie ewaluacyjnej. 2. Zdefiniowanie tablicy prawdy 3. Definicja tablicy Karnaugh i minimalizacja funkcji logicznej
4. Tworzymy nowy projekt w Active HDL a) Uruchomić program Active-HDL. Można użyć ikony na pulpicie lub wybrać z menu start Wszystkie programy a następnie Aldec -> Active-HDL 9.3. UWAGA! Program uruchamia się dobre 30-40 sekund nie dając oznak życia cierpliwości Rys. 11. Uruchomienie programu Active-HDL. b) Pojawi się okno wyboru licencji. Wybrać Next. Rys. 12. Okno wyboru licencji. c) W oknie Getting Started wybrać utworzenie nowej przestrzeni roboczej i kliknąć OK. Rys. 13. Okno pozwala otworzyć istniejącą przestrzeń roboczą lub utworzyć nową. 8
d) W kolejnym oknie nadaje się nazwę przestrzeni roboczej oraz ustawia jej położenie na dysku. Proszę nadać unikalną nazwę, tak by nie nadpisywać czyjegoś projektu, np. Pon_1615_Cw1. Nazwa musi zaczynać się od litery po czym mogą występować litery, cyfry i znaki podkreślenia _. Znak podkreślenia nie może być na końcu ani w sąsiedztwie drugiego znaku podkreślenia. Nie używać polskich liter ani znaku spacji (dotyczy to też ścieżki na dysku twardym)! Proszę nie zmieniać ścieżki okresowo czyścimy komputery. Rys. 14. Wybór nazwy i położenia dla tworzonej przestrzeni roboczej. e) W kolejnym oknie wybrać opcję Create an Empty Design with Design Flow. W efekcie, dołożymy do przestrzeni roboczej pusty projekt i będziemy mieć aktywny tzw. Design Flow (niezbędny aby wgrać później projekt na płytkę ewaluacyjną; w razie pomyłki się nie przejmować gdyż Design Flow można łatwo aktywować w ustawieniach istniejącego projektu). Rys. 15. Wybieramy utworzenie nowego projektu z aktywnym Design Flow. f) W kolejnym oknie mamy możliwość wybrać narzędzia uruchamiane w trakcie syntezy i implementacji. Ważne jest aby wszystkie opcje ustawić tak jak na rysunku poniżej. Zwrócić szczególną uwagę aby Block Diagram Configuration był ustawiony na EDIF Schematic natomiast pole Default HDL Language było ustawione na VHDL. Jeżeli opcje nie były poprawnie wybrane to dokonać zmian a po utworzeniu projektu zawołać prowadzącego zmieni wtedy wartości domyślne w ustawieniach programu tak by na kolejnych zajęciach nie trzeba było nic zmieniać. 9
Rys. 16. Konfiguracja projektu. g) W kolejnym oknie wpisać nazwę projektu, np.: Tutor. Nazwa musi zaczynać się od litery po czym mogą występować litery, cyfry i znaki podkreślenia _. Znak podkreślenia nie może być na końcu ani w sąsiedztwie drugiego znaku podkreślenia. Nie używać polskich liter ani znaku spacji! Rys. 17. Wybór nazwy i położenia projektu. 10
h) Zatwierdzić utworzenie nowej przestrzeni roboczej i nowego projektu. Rys. 18. Ostatnie okno kreatora. 5. Dołączenie schematów do projektu i ich uzupełnienie Na obecnym etapie prac mamy gotową przestrzeń roboczą Wtorek_1430_Cw1 w której znajduje się jeden projekt o nazwie Tutor. Projekt jest na razie pusty musimy zacząć tworzyć poszczególne pliki projektowe. Zamiast wprowadzać projekt dekodera "od zera", dodamy gotowe pliki do projektu. a) Pobrać materiały pomocnicze i wypakować je do folderu scr tworzonego projektu. D:\My_Designs\[nazwa workspace]\tutor\src\ Rys. 19. Zawartość folderu src tworzonego projektu. 11
b) Dołączamy skopiowane pliki do projektu. Po lewej stronie znajduje się okno Design Browser, w którym na poszczególnych zakładkach (Files, Structure, Resources) zobrazowane są zasoby i struktura projektu. Na zakładce Files należy kliknąć dwukrotnie opcję Add New File. W oknie Add New File wybrać typ nowo powstającego pliku Block Diagram i kliknąć pole Add Existing File. Rys. 20. Dołączanie istniejących plików do projektu. c) W kolejnym oknie zaznaczyć wszystkie 3 pliki i kliknąć przycisk Otwórz. Rys. 21. Wybór plików które zostaną dołączone. 12
d) W Design Browser dwukrotnie kliknij na Decoder.bde aby wyświetlić jego zawartość. e) Wyświetl bibliotekę symboli elementów cyfrowych Symbols Tolbox. W tym celu poszukaj na górnym pasku programu ikony skrótu Show Symbols Toolbox (S). Rys. 22. Ikona skrótu do wyświetlenia biblioteki elementów. Z prawej strony ekranu pojawi się Symbols Tolbox. W lewej kolumnie (Name) umieszczone są alfabetycznie nazwy elementów, w prawej zaś (Description) odpowiadające im opisy funkcjonalne. W górnym polu tekstowym można wpisać nazwę elementu aby łatwiej go odszukać ( and4 na Rys. 23). Symbol umieszczamy na schemacie z wykorzystaniem techniki przeciągnij i upuść. Można złapać zarówno za nazwę elementu (np. tekst AND4) jak i za symbol graficzny. Zawsze używaj symboli z biblioteki ARTIX7. Jeżeli po umieszczeniu na schemacie bramka ma żółte wypełnienie, to wybrał się element biblioteki Built-in symbols której nie będziemy nigdy używać. Jeżeli symbol znajduje się już na schemacie, to można też użyć kopiowania i wklejania (Ctrl+C, Ctrl+V). Rys. 23. Zawsze wyszukiwać symboli z biblioteki ARTIX7. 13
Elementy, połączenia czy inne obiekty na schemacie można kasować poprzez: - wskazanie ich narzędziem Select (przełączenie do tego narzędzia można uzyskać wciskając klawisz Esc na klawiaturze); - skasowanie przyciskiem Delete na klawiaturze. Łączenie elementów na schemacie dokonuje się po wybraniu na pasku narzędzi Wire (W). Unikaj sytuacji w której linie różnych sygnałów nakładają się na siebie. Położenie elementu na przewodzie nic nie daje element wisi w powietrzu do niczego nie podpięty natomiast połączenie nie ulega zmianie. Różowy kwadracik oznacza brak połączenia układ nie będzie działał poprawnie. Rysowanie połączenia musisz zakończyć dokładnie w miejscu gdzie kończy się pin symbolu. Rysuj dokładnie Zwróć uwagę na właściwą nazwę i orientację symbolu. 14
Na schemacie można położyć Terminal. Jest to port umożliwiający wprowadzenie sygnału z zewnątrz. Jego użycie pozwala tworzyć schematy hierarchiczne (zamykamy jeden schemat do postaci symbolu który następnie możemy wstawiać na innych schematach) lub wyprowadzać sygnał poza układ FPGA (aby np. dołączyć się do przycisku czy diody LED). Rys. 30. Terminale które będą wykorzystywane na zajęciach. f) W oparciu o funkcje wyprowadzone w rozdziale 3, uzupełnij schemat Decoder.bde o brakujące układy sterujące pozostałymi segmentami. Kółko na wejściu bramki oznacza że jest tam dołączony inwerter. Rys. 31. Bramki i odpowiadające im operatory logiczne. Rys. 32. Dorysowujemy brakujący układ poniżej segmentu A. 15
g) Zapisujemy zmiany i kompilujemy schemat. Można to zrobić na kilka równoważnych sposobów. I Sposób W oknie Design Browser klikamy prawym przyciskiem myszy na schemacie który chcemy skompilować. Pojawi się menu kontekstowe w którym wybieramy opcję Compile. Rys. 33. Kompilacja schematu. II Sposób Można kliknąć na ikonie skrótu znajdującej się na jednym z pasków narzędzi w górnej części okna. Aktualnie wyświetlony schemat zostanie skompilowany. Rys. 34. Kompilacja schematu. III Sposób Z głównego menu programu wybieramy Design -> Compile. IV Sposób Na Rys. 33. można zauważyć że schemat kompiluje się po wciśnięciu klawisza F11 na klawiaturze ;D h) W Design Browser dwukrotnie kliknij na Top_7Segment.bde aby wyświetlić jego zawartość. 16
i) Uzupełnij schemat Top_7Segment.bde zgodnie z poniższym rysunkiem. Przed uruchomieniem procesu implementacji należy uzupełnić schemat o specjalne bufory we/wy. Każdy Terminal, który jest przypisany do wyprowadzenia układu FPGA musi mieć dodany specjalny bufor. Zastosujemy symbole IBUF dla sygnałów wejściowych i OBUF dla sygnałów wyjściowych. Nie wolno dołączać symboli IBUF oraz OBUF do terminali połączonych z sygnałami wewnętrznymi, służącymi do tworzenia hierarchii. Symbol IBUF lub OBUF jest potrzebny wyłącznie dla sygnałów które chcemy wyprowadzić poza obudowę układu FPGA. Rys. 35. Zawartość schematu Top_7Segment.bde. j) Zapisz zmiany i skompiluj schemat. Jeżeli wszystko pójdzie dobrze powinniśmy mieć sytuację jak na rysunku poniżej. Rys. 36. Zielona parawka przy nazwie pliku oznacza poprawne skompilowanie schematu. 17
6. Symulacja modułu Decoder a) Wybieramy schemat który chcemy symulować. W tym celu należy rozwinąć listę Top-level selection znajdującą się w Design Browser i wybrać Decoder. Jeżeli nie ma go na liście, to schemat nie został wcześniej skompilowany (lub kompilacja zakończyła się błędem). Rys. 37. Wybór schematu który będzie symulowany. b) Inicjalizujemy symulację poprzez wybranie z menu głównego programu opcji Simulation -> Initialize Simulation. Rys. 38. Inicjalizacja symulacji. W oknie Design Browser automatycznie przełączy się zakładka z Files na Structure, obrazującą strukturę projektu (jego elementy i połączenia w ujęciu hierarchicznym). Patrz Rys. 39. 18
c) Otwieramy okno przebiegów czasowych, przyciskając na pasku narzędzi przycisk New Waveform. Rys. 39. Zmienione zakładki Design Browser i ikona skrótu otwierająca okno do analizy działania układu. d) Dodaj sygnały które będą obserwowane w symulacji. Aby w oknie przebiegów czasowych móc edytować wymuszenia i obserwować zmiany stanów sygnałów w funkcji czasu, należy wprowadzić do niego wybrane ze struktury projektu sygnały. Ponieważ przykładowy projekt podczas symulacji będzie traktowany jako czarna skrzynka, to wystarczy że do okna przebiegów czasowych dodamy tylko porty wejściowe (X0, X1, X2 i X3) i porty wyjściowe (A, B, C, D, E, F, G). W tym celu, w oknie Design Browser należy zaznaczyć powyższe sygnały i przenieść je (metodą drag-and-drop) do okna przebiegów czasowych. Rys. 40. Dodawanie obserwowanych przebiegów do okna symulacji. 19
e) Do wszystkich sygnałów wejściowych przypisujemy wymuszenia, czyli mechanizm pozwalający dokonywać zmian na wejściu symulowanego układu. W tym celu zaznaczamy sygnały X0... X3, klikamy prawym przyciskiem myszy na zaznaczonych sygnałach i wybieramy z menu kontekstowego opcję Stimulators Jeżeli w menu nie ma Stimulators... to proszę wybrać z głównego menu programu Tools -> Preferences Pojawi się okno, w którego lewej części zaznaczamy Waveform Viewer/Editor. W prawej części okno zmieniamy Default waveform viewer/editor na Standard Waveform Viewer/Editor. Jeżeli nie da się rozwinąć listy, to proszę zatrzymać symulację i spróbować ponownie. Rys. 41. Wyświetlanie okna do przypisywania wymuszeń na wejściach testowanego układu. Pojawi się okno w którym zaznaczamy sygnał któremu chcemy przypisać stymulator/wymuszenie. Wybieramy rodzaj wymuszenia z listy Type w naszym przypadku będzie to zegar czyli Clock. Ustawiamy okres zegara i klikamy Apply (pojawi się parawka obok nazwy sygnału). X0 okres 200 ns; X1 okres 400 ns; X2 okres 800 ns; X3 okres 1600 ns; Rys. 42. Przypisanie wymuszenia do sygnału/portu wejściowego. 20
f) Wykonujemy symulację krokowo. Każde kliknięcie przycisku Run For powoduje wykonanie kroku symulacji o długości podanej w polu tekstowym znajdującym się tuż obok. Rys. 43. Każde kliknięcie przycisku Run For spowoduje wykonanie kolejnych 100 ns symulacji. Nigdy nie klikamy przycisku Run. Nie mamy zdefiniowanego końca symulacji, przez co będzie się ona wykonywać w nieskończoność. W efekcie zapchamy pamięć RAM i komputer zacznie przymulać lub w skrajnym przypadku się zawiesi. Jeżeli kliknąłeś Run, to jak najszybciej kliknij End Simulation (symbol Stop). g) Wyświetl zawartość schematu 'Decoder.bde'. h) Włącz opcję Probe środowiska AHDL. Z menu głównego programu wybierz Diagram -> Probes -> Add Probes. Rys. 44. Włączenie Probes graficznego wyświetlania bieżącego stanu sygnałów. W oknie które się pojawi zaznacz wszystkie opcje i kliknij Add. Rys. 45. Włączenie Probes graficznego wyświetlania bieżącego stanu sygnałów. 21
i) Zweryfikuj poprawne działanie wyświetlacza. W prawym górnym rogu schematu Decoder.bde jest namiastka wyświetlacza ułatwiająca organoleptyczną weryfikację działania projektu. Po każdym kliknięciu przycisku Run For (Rys. 38.) wyświetlana cyfra powinna się zwiększyć. Wyświetlamy po kolei znaki 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, [a dalej są śmieci] Rys. 46. Atrapa wyświetlacza. Przedstawione cyfry 4, 5, 6 i 7. Jeżeli np. segment D świeci się choć nie powinien lub jest wygaszony chociaż powinien być zaświecony, to źle połączono bramki realizujące funkcję logiczną D. Popraw wszelkie błędy. j) Zatrzymaj tryb symulacji, wybierając z menu Simulation opcję End Simulation. 7. Opcje implementacji a) Wyświetl zawartość zakładki Design Flow. Rys. 47. Zakładka Design Flow. 22
Jeżeli zakładka Design Flow jest niewidoczna (lub została zamknięta) to kliknij ikonę skrótu View Flow (Alt+3) na górnym pasku programu. Rys. 48. Design Flow można włączyć klikając na ikonę skrótu View Flow. Jeżeli ikona jest wyszarzona to popełniono błąd na etapie zakładania projektu (wybrano złą opcję na Rys. 15). Aby aktywować Design Flow, wybierz z głównego menu programu Tools -> Preferences W nowym oknie wybierz z lewej strony Flows i zaznacz opcję Enable Design Flow Manager. b) Wyświetl okno opcji dla implementacji Rys. 49. Wyświetlenie opcji implementacji. Opcje implementacji są bardzo rozbudowane i służą do profilowania sposobu w jaki ma działać oprogramowanie przeprowadzające implementację. Na zajęciach będziemy konfigurować najbardziej podstawowe opcje, pozostawiając pozostałe w ustawieniach domyślnych. c) Wskaż który schemat będzie implementowany. W zakładce Main (patrz poniżej) kliknij przycisk Browse. W nowym oknie przejdź do folderu compile i wybierz plik Top_7Segment.edn. d) Wskaż na jakim układzie FPGA projekt zostanie zrealizowany. Family: Xilinx 14x ARTIX7 Device: 7a100tcsg324 Speed Grade: -2 e) Wskaż plik UCF wiążący nazwy Terminali znajdujących się na schematach z pinami ułożonymi na obudowie układu FPGA. Z rozwijanej listy Constrain File (UCF) Support wybierz opcję Custom constrain file. Następnie kliknij przycisk Browse i wybierz plik Cw1.ucf znajdujący się w katalogu src. f) W tym momencie można już kliknąć OK aby zatwierdzić zmiany. 23
Rys. 50. Ustawienia implementacji. 8. Implementacja projektu a) Wyświetl zawartość zakładki Design Flow. W prazie problemów patrz punkt 7.a. b) Kliknij na ikonie Configure tak by zrobiła się kolorowa. c) Uruchom implementację klikając na ikonie implementation. Rys. 51. Aby wygenerować plik do zaprogramowania układu FPGA, ikona Configure musi być kolorowa. 24
Implementacja projektu składa się z kilku etapów i może zająć do kilku minut! Na górnym pasku widać postęp Rys. 52. Translacja i mapowanie zostało ukończone. Ostrzeżeniami, (z grubsza) nie należy się przejmować o ile ich liczba jest taka jak w instrukcji na dzisiejszych zajęciach, optymalna liczba ostrzeżeń to 1. Rys. 53. Powinniśmy dziś otrzymać 1 ostrzeżenie. W przypadku błędu, przewijamy na sam początek logu i szukamy pierwszego błędu od góry (każdy kolejny jest jego następstwem). W szczególności, nie należy pytać prowadzącego gdzie jest plik *.ngd?. Plik *.ngd jest tworzony na koniec etapu translacji. Jeżeli z powodu innego błędu translacja się nie powiedzie, to kolejny etap mapowania wygeneruje błąd o brakującym pliku *.ngd i przerwie proces implementacji. d) Zweryfikować czy wszystkie Terminale zostały poprawnie zaalokowane. Jeżeli 100% bloków IOB jest przyporządkowanych, to znaczy, że dyrektywy z pliku *.ucf zostały uwzględnione. Rys. 54. Sprawdzamy liczbę zaalokowanych Input-Output Blocks (IOB). 25
9. Zaprogramowanie układu FPGA a) Podłączyć płytkę FPGA do komputera przy pomocy kabla USB. Kabel wepnij w gniazdo PROG znajdujące się na lewej krawędzi płytki. b) Przestaw włącznik POWER (lewy górny róg) do pozycji ON. c) W programie Active-HDL wyświetl zawartość zakładki Design Flow (punkt 5.a). d) Kliknij na ikonie Analysis a następnie kliknij na ikonie impact. Tak, ten program też się długo uruchamia ;D Rys. 55. Uruchomienie narzędzia impact służącego do programowania układu FPGA. e) Jeżeli zobaczysz poniższy błąd to kliknij OK i się nie przejmuj. Rys. 56. Ten błąd można zignorować. f) Jeżeli program zapyta się czy automatycznie utworzyć i zapisać projekt, to zaznacz opcję Don t show this message again i kliknij Yes. Rys. 57. Chcemy aby program przy starcie tworzył nam nowy projekt. 26
g) Jeżeli impact uruchomi się pusty. To wybieramy z menu głównego programu File -> New Project. Rys. 58. Puste okno programu impact. h) Dążymy do tego by zobaczyć poniższe okno. Zostawiamy domyślnie zaznaczoną opcję Configure device using Boundary-Scan (JTAG) i klikamy OK. Rys. 59. Jeśli impact przywita nas tym oknem, to jesteśmy w domu. 27
i) W kolejnym oknie klikamy cokolwiek, byle nie Help. Rys. 60. To okno zamykamy. j) Kliknąć prawym przyciskiem na xc7a100t i wybieramy Assign New Configuration File. Rys. 61. Wskazujemy położenie pliku do programowania układu FPGA. k) Wskazać plik top_7segment.bit znajdujący się w folderze D:\My_Designs\[nazwa workspace]\tutor\implement\ver1\rev1\ Pojawi się pytanie czy użyć pamięci nieulotnej PROM zawsze wybierać No. Rys. 62. Nie będziemy używać pamięci nieulotnej PROM. l) Ponownie kliknij prawym przyciskiem na xc7a100t i wybierz Program. Następnie OK. m) Zweryfikuj poprawne działanie projektu. 28
Zadanie 1 W obecnej wersji projektu, wszystkie wyświetlacze pokazują tę samą cyfrę. Jest to związane ze sposobem w jaki połączono wyprowadzenia wyświetlaczy, co przedstawiono schematycznie na Rys. 47. Rys. 47. Sygnały potrzebne do wyświetlenia cyfry 2 tylko na lewym wyświetlaczu. Segmenty wyświetlaczy są połączone ze sobą, tzn. segment A wyświetlacza pierwszego od lewej jest połączony z segmentem A wyświetlacza drugiego i segmentem A wyświetlacza trzeciego i segmentem Podobnie, segmenty B wszystkich wyświetlaczy są spięte razem. Segmenty C wszystkich wyświetlaczy są połączone ze sobą. I tak dalej Zatem, mamy osiem sygnałów A, B, C, D, E, F, G oraz DP do sterowania kropką. Wysterowanie tych sygnałów spowoduje że każdy z wyświetlaczy pokaże dokładnie to samo. Aby móc wyświetlać różne cyfry na poszczególnych pozycjach, musimy użyć sygnałów sterujących anodami wyświetlaczy AN<x> (górna krawędź Rys. 45.). Każdy wyświetlacz ma dokładnie jeden sygnał AN<x> służący do jego włączenia lub zablokowania. Jeżeli na AN<x> jest poziom wysoki, to dany wyświetlacz jest wyłączony i nie reaguje na sterowanie segmentami A, B, C, Jeżeli na AN<x> jest poziom niski, to wyświetlacz jest aktywny i zapala segmenty zgodnie z wartością sygnałów A, B, C, Pierwsze zadanie polega na wprowadzeniu sterowania z ośmiu (wystarczy czterech bo idea jest ta sama) przełączników SW tak, aby można było selektywnie zapalać i gasić poszczególne cyfry wyświetlacza. W tym celu należy: - umieścić na schemacie dodatkowe Terminale wejściowe na których pojawi się sygnał logiczny w zależności od położenia przełącznika SW<n>. Nie zapomnij o dołączeniu symbolu IBUF tak jak w 6.d. - umieścić na schemacie dodatkowe Terminale wyjściowe które będą sterować anodą poszczególnego wyświetlacza (można ograniczyć się do 4 wyświetlaczy). Nie zapomnij o dołączeniu symbolu OBUF tak jak w 6.f. - zaprojektować funkcję logiczną, która podaje poziom logiczny Hi na wyjście AN<x> gdy na SW<x> jest poziom logiczny Hi. W gruncie rzeczy, funkcja jest dziecinnie prosta ;D - zapisać i skompilować edytowany schemat. - odkomentować odpowiednie linie w pliku UCF. Pamiętać, że pole NET musi być zgodne z nazwą Terminala umieszczonego na schemacie. Nie zapomnij zapisać zmian i zamknąć karty z zawartością UCF. - Przeczytać treść zadania 2 gdyż jest bardzo podobne. W ten sposób można zaoszczędzić czas potrzebny na drugą implementację projektu - Na zakładce Design Flow uruchomić implementację. - Zaprogramować układ FPGA (jeżeli impact nie został zamknięty to wystarczy wykonać krok z punktu 6.l; w przeciwnym wypadku, od 6.c do 6.l). Zadanie 2 Wprowadzić sterowanie punktem dziesiętnym zespołu wyświetlaczy z przycisku, np. btnc. Zadanie 3 gdy na wyświetlaczu jest zero punkt dziesiętny ma zostać zaświecony, w pozostałych przypadkach ma być zgaszony. Zadanie 4 zmodyfikować sterowanie z zadania pierwszego. Przełączniki SW wskazują, który wyświetlacz ma być aktywny, np ustawienie wartości zero powoduje zaswiecenie wyświetlacza pierwszego, ustawienie wartości trzy powoduje zaswiecenie wyświetlacza ostatniego. 21