FPGA od początku do końca - część druga

| Technika

Opisane w pierwszej części artykułu podstawowe kwestie dotyczące rodzajów i budowy układów FPGA nie obejmują całego zakresu spraw, jakie muszą być wzięte pod uwagę przy wyborze układu programowalnego. Nowoczesne FPGA to nie tylko matryce komórek logicznych, ale i specjalizowane podsystemy zintegrowane wewnątrz obudowy układu, co pozwala zmaksymalizować wydajność systemu w konkretnych zadaniach. Najbardziej uniwersalnymi elementami tego typu są bloki pamięci RAM. Mogą one służyć jako zwykła pamięć operacyjna, kolejki FIFO lub komórki przechowujące dane dotyczące stanów automatu. Bloki te umieszczone są na obrzeżach lub równomiernie rozmieszczone wewnątrz struktury układu i zorganizowane w grupy po kilka do kilkuset kilobitów. W najnowszych układach (Stratix III, Virtex 5) sumaryczny rozmiar tej pamięci sięga nawet kilkunastu megabitów, co pozwala na implementację złożonych algorytmów bez poświęcania części portów układu scalonego na komunikację z zewnętrzną pamięcią. Ponadto zintegrowane bloki pamięci mogą pracować z dużymi częstotliwościami zegara i nie zajmują dodatkowej powierzchni na płytce drukowanej.

FPGA od początku do końca - część druga

Opisane w pierwszej części artykułu podstawowe kwestie dotyczące rodzajów i budowy układów FPGA nie obejmują całego zakresu spraw, jakie muszą być wzięte pod uwagę przy wyborze układu programowalnego.

Nowoczesne FPGA to nie tylko matryce komórek logicznych, ale i specjalizowane podsystemy zintegrowane wewnątrz obudowy układu, co pozwala zmaksymalizować wydajność systemu w konkretnych zadaniach. Najbardziej uniwersalnymi elementami tego typu są bloki pamięci RAM. Mogą one służyć jako zwykła pamięć operacyjna, kolejki FIFO lub komórki przechowujące dane dotyczące stanów automatu. Bloki te umieszczone są na obrzeżach lub równomiernie rozmieszczone wewnątrz struktury układu i zorganizowane w grupy po kilka do kilkuset kilobitów. W najnowszych układach (Stratix III, Virtex 5) sumaryczny rozmiar tej pamięci sięga nawet kilkunastu megabitów, co pozwala na implementację złożonych algorytmów bez poświęcania części portów układu scalonego na komunikację z zewnętrzną pamięcią. Ponadto zintegrowane bloki pamięci mogą pracować z dużymi częstotliwościami zegara i nie zajmują dodatkowej powierzchni na płytce drukowanej.

Specjalizowane podukłady

Innymi blokami, jakie umieszczane są wewnątrz układów FPGA są podsystemy realizujące najczęściej wykonywane operacje. Mowa o działaniach takich jak dodawanie lub mnożenie, których realizacja w postaci odpowiedniej konfiguracji komórek logicznych byłaby mało efektywna i zajmowała dosyć dużo miejsca w stosunku do tego, ile zajmuje taki specjalizowany podsystem. Wbudowanie dodatkowych bloków dodających lub mnożących, a także bloków MAC, które integrują mnożenie, dodawanie i zapamiętywanie danych, pozwala na znaczące przyspieszenie tych operacji. Dobrym przykładem są zastosowania DSP, w których układy MAC są najbardziej przydatne. Jednakże w przetwarzanie sygnałów najwięcej wnoszą wbudowane rdzenie specjalizowanych procesorów.

Rdzenie te lub rdzenie dowolnych innych mikrokontrolerów mogą być realizowane albo w postaci syntezowalnych modułów IP (soft core) albo jako trwałe fragmenty w strukturze półprzewodnika (hard core). Naturalnie, te drugie będą zajmować mniej miejsca i pracować z większą wydajnością, ale powodują, że cały układ FPGA staje się specjalizowany, co kłóci się z ideą uniwersalności, jaka przyświeca producentom układów programowalnych. Powstaje także pytanie po co implementować mikrokontroler w układzie programowalnym, skoro wybór FPGA jako procesora systemowego jest często ucieczką od ograniczeń stawianych przez zwykłe mikroprocesory. Okazuje się bowiem, że są funkcje, które mogą ograniczać działanie całego układu w przypadku, gdy zostaną zrealizowane w ramach grupy komórek logicznych. Przykładem może być sterowanie diod, które wymaga odpowiednio długiego czasu zapalania i wygaszania, który to musiałby być kontrolowany przez bardzo długi licznik złożony z dużej liczby komórek pamięci. Co więcej niektóre z funkcji wymagają wykonania szeregu następujących po sobie operacji, które łącznie są zbyt skomplikowane, by w szybki sposób przełożyć ja na elementarne działania w algebrze boolowskiej. Jest to wystarczający powód, aby układy programowalne wspierane były przez współpracujące z nimi mikrokontrolery. Usprawnieniem tego pomysłu jest integracja mikrokontrolera do wnętrza układu FPGA, co pozwala skrócić czas potrzebny na komunikację pomiędzy układem logicznym, a mikrokontrolerem, a także zaoszczędzić wolne porty układu i ograniczyć powierzchnię całej płytki drukowanej.

Rdzenie trwale wbudowane

Wracając do podziału na rdzenie programowe i te, które są integralnym elementem układu FPGA, wypada omówić dostępne realizacje tychże elementów. Pierwszą z nich jest ułożenie mikrokontrolera poza obszarem, w którym znajdują się komórki logiczne – tak jak zostało to przedstawione na rysunku 1. Pomysł ten może być wykonany nie tylko jako pojedynczy układ krzemowy, ale także jako dwa lub więcej układów scalonych połączonych ze sobą i zamkniętych w jednej obudowie. Separacja części klasycznej układu programowalnego od dodatkowych funkcji zintegrowanych w tej samej obudowie ułatwia wykorzystywanie narzędzi wspomagających programowanie. Programy te posługują się wtedy identycznym opisem układu, jak w przypadku FPGA bez dodatkowych bloków. Zadaniem projektanta jest odpowiednie przypisanie portów wyjściowych w taki sposób, aby pożądane sygnały przekazywane były pomiędzy mikrokontrolerem a resztą układu.

Rys. 1. Układ FPGA z rdzeniem mikrokontrolera umieszczonym na obrzeżu struktury półprzewodnikowej lub na oddzielnej strukturze

Drugą opcją jest przedstawiony na rysunku 2 schemat, w którym poszczególne rdzenie umieszczone są wewnątrz głównego obszaru FPGA, a do swej pracy jako układy wejścia i wyjścia wykorzystują sąsiadujące z nimi bloki pamięci oraz komórki logiczne, które je otaczają.

Rdzenie wprogramowywane

Kolejnym typem wspomnianych rdzeni są syntezowalne moduły programowe, które sprzedawane są przez wiele różnych firm. Moduł mikroprocesora może być wykonany także przez projektanta całego systemu, ale częstszym zabiegiem jest kupowanie licencji na już istniejące projekty. O ile moduły te nie zwiększają szybkości wykonania poszczególnych operacji to mogą w znaczący sposób uprościć zapis realizowanych funkcji. Rozwiązują tym samym jeden z wymienionych problemów, który pojawia się przy próbie implementacji takich funkcji jak na przykład sterowanie diodami LED. Ponadto rdzenie programowalne mogą być dostosowane do potrzeb użytkownika, co w przypadku wersji trwale wbudowanych nie było możliwe. Projektant może praktycznie dowolnie zmieniać szerokość szyny danych mikroprocesora czy też rozmiar i liczbę jego rejestrów, a nawet implementować dowolną liczbę takich samych lub różniących się między sobą rdzeni w ramach jednego układu FPGA. Jedynym ograniczeniem jest liczba dostępnych w układzie zasobów takich, jak komórki logiczne i bloki pamięci RAM, ale te mogą być dobrane do potrzeb z szerokiej oferty układów dostępnych na rynku. Dzięki temu odpowiednio zaawansowany układ może przetwarzać określony typ danych dużo szybciej niż gigahercowy procesor, nawet jeżeli taktowany jest znacznie niższym zegarem.

Zarządzanie sygnałem zegara

Rys. 2. Układ FPGA z rdzeniami mikrokontrolera wkomponowanymi w główny obszar struktury półprzewodnikowej

Parametry wspomnianego już sygnału zegarowego są także bardzo istotne dla sprawności całego układu. Duże rozmiary struktury półprzewodnikowej, jakie występują w najbardziej zaawansowanych układach FPGA powodują, że opóźnienia w zegarze dla odległych od siebie komórek mogą być istotne. Nie mniejszą trudnością są niestabilności zboczy sygnału zegarowego (jitter), jakie również pojawiają się wewnątrz układu. Aby uniknąć tych problemów linie zegarowe w strukturach FPGA są projektowane w sposób drzewiasty. Oznacza to, że zamiast pojedynczej linii, po której przenoszony byłby sygnał zegarowy poprzez kolejne komórki układu, projektowane jest drzewo sygnałów w taki sposób, aby zminimalizować maksymalne występujące opóźnienia zegarowe. Ze względu na możliwość implementacji kilku oddzielnych funkcjonalnie jednostek logicznych wewnątrz jednego układu, a także w celu umożliwienia ograniczenia zużycia energii wprowadza się podział na domeny zegarowe – czyli obszary taktowane tym samym zegarem. Pozwala to na wyłączenie, a konkretnie zablokowanie sygnału zegarowego dla pewnej grupy komórek układu, dzięki czemu pobierany przez nie prąd jest minimalny. Poza tym w trakcie działania mogą one pracować z różnymi częstotliwościami, co jest dobrym sposobem na optymalizację pracy układu, bądź dopasowanie go do częstotliwości otaczających go podzespołów i ich interfejsów.

Sam sygnał zegarowy może być wprowadzany przez dowolną z nóżek układu, ale w celu zapewnienia jego optymalnego przebiegu, należy używać portów do tego wyznaczonych. Pozwala to także na skorzystanie z układów korekcji i zarządzania zegarem (DCM – Digital Clock Manager). Regulują one wewnętrzną częstotliwość, jaką sterowane są poszczególne podzespoły. Układy te, oparte o grupę pętli fazowych i opóźnieniowych (PLL i DLL) pozwalają na synchronizację, mnożenie, dzielenie oraz przesuwanie fazy sygnałów zegarowych. Podczas gdy synchronizacja jest dobrą metodą usuwania błędów jitteru, mnożenie i dzielenie częstotliwości pozwala na redukcję liczby zewnętrznych oscylatorów, jakie muszą być dołączone do układu. Synteza częstotliwości umożliwia dosyć precyzyjne taktowanie bloków logicznych częstotliwościami, które wytwarzane są na podstawie częstotliwości bazowej, wprowadzanej z zewnątrz. Tymczasem zmiana fazy pozwala na wprowadzanie opóźnień w działaniu poszczególnych części układu, co pozwala na lepszą kontrolę kolejności operacji odczytu lub zapisu. Dzięki temu możliwe jest projektowanie układów działających bardziej stabilnie, a niekiedy nawet szybciej, niż bez stosowania opóźnień. Dostępne wartości przesunięcia fazy wyrażane są w stopniach i są ułamkiem kąta pełnego. Mogą być one dobierane z dokładnością zależną od budowy układu kontroli zegara.

Różnica pomiędzy klasyczną pętlą fazową PLL (Phase Locked Loop) i cyfrową pętlą opóźnieniową DLL (Digital Delay-Locked Loop) polega nie tylko na ich konstrukcjach, ale także i na zastosowaniach, w jakich są one zazwyczaj wykonywane. Pętle DLL to nowszy pomysł, który stosowany jest przede wszystkim do wprowadzania opóźnień w sygnałach zegarowych. Istnieją także układy, w których jedynymi zaimplementowanymi pętlami są właśnie DLL, czego przykładem jest Virtex 4 firmy Xilinx. Trudno jest także określić wyższość jednej techniki nad drugą. O ile twierdzi się, że pętle DLL są stabilniejsze i bardziej odporne na szumy, to same są przyczyną powstawania szumów. Wszystko zależy od konkretnego wykonania pętli, które jak zwykle powiązane jest z koniecznością podjęcia kilku kompromisów. Istnieją także rozwiązania łączące ze sobą cechy pętli fazowych i opóźnieniowych (mixed PLL/DLL), ale jak dotąd nie były one stosowane w układach FPGA.

Liczba pętli fazowych i opóźnieniowych, a co za tym idzie liczba oddzielnych sygnałów zegarowych w układzie zależna jest od konkretnego FPGA. To właśnie za sprawą systemów kondycjonowania sygnału duże układy FPGA mogą pracować z częstotliwościami sięgającymi kilkuset megaherców.

Układy wejścia i wyjścia

Rys. 3. Przykład graficznego okna projektowego w programie Synplify Pro

Kolejny istotny parametr układów programowalnych to porty wejścia i wyjścia – a konkretnie zarówno ich liczba jak i standard, w którym mogą pracować. Ze względu na dużą liczbę różnego rodzaju wersji, z którymi zgodne są dostępne na rynku podzespoły, aby dowolny układ FPGA mógł się z nimi komunikować, konieczne było stworzenie konfigurowalnych bloków wejścia i wyjścia. Bloki te grupują ze sobą po kilka do kilkunastu wyprowadzeń układu, które to zostają skonfigurowane do pracy zgodnie z konkretnym standardem. Oznacza to, że danej grupie nóżek układu przypisywane są wartości napięć dla poziomów logicznych 0 i 1. Aby ograniczyć niedopasowanie na liniach z szybko zmieniającymi się sygnałami, dla poszczególnych bloków konfigurowane są także wartości wbudowanych rezystorów terminujących sygnał. Dzięki temu nie ma konieczności stosowania zewnętrznych rezystorów, których rozmieszczenie na płytce drukowanej – w przypadku układów o największej liczbie wyprowadzeń, byłoby bardzo kłopotliwe.

Kolejną częścią układów wejścia i wyjścia są specjalne szeregowe interfejsy zbudowane tak, aby przesyłały sygnał różnicowy. Podzespoły te wbudowywane są na stałe do FPGA, aby zapewnić ich jak najwyższą sprawność działania. Jest to rozwiązanie problemu, który wynikł z potrzeby uzyskania jak najwyższej przepustowości komunikacji. Zwiększanie prędkości transferu odbywało się dotąd głównie poprzez poszerzanie magistrali danych, co przy 64-bitach staje się problematyczne nie tylko ze względu na trudność w poprawnym poprowadzeniu ścieżek na płytce drukowanej, ale i z powodu wzajemnych interferencji, jakie pojawiają się przy tak szerokich magistralach. Wbudowywane obecnie interfejsy szeregowe odbierają wielobitowe dane z wewnątrz układu, po czym transmitują je na zewnątrz układu zgodnie z zadanymi parametrami transmisji, bez konieczności tworzenia osobnego projektu takich nadajników i odbiorników. Odbiór danych odbywa się dokładnie w ten sam sposób. Liczba takich układów transmisji zależna jest od konkretnego FPGA.

Oferta producentów

Rys. 4. Schemat blokowy modułu DCM opartego o pętle opóźnieniową w układzie Spartan 3 firmy Xilinx

Ostatnią kwestią, jaką należy rozważyć podczas wyboru układu programowalnego, jest zbiór narzędzi i modułów, jakie oferowane są przez poszczególnych producentów FPGA. Poza opisanymi wcześniej blokami programowymi, będącymi całymi mikrokontrolerami lub mikroprocesorami, możliwe jest stosowanie także różnego rodzaju pomniejszych bloków funkcjonalnych przeznaczonych do różnych zastosowań. Bloki te dostępne są w dwóch postaciach. W wersji soft IP, która zapisana jest w językach opisu sprzętu, takich jak VHDL czy Verilog - moduły te mogą być implementowane w układach dowolnej firmy – z wyjątkiem kodu w języku AHDL, który jest dostępny wyłącznie dla układów Altery. Drugą postacią są bloki typu firm IP, czyli takie, które zostały już przystosowane do konkretnej rodziny układów FPGA. Bloki te zawierają bezpośredni opis połączeń i konfiguracji komórek danego układu programowalnego i w związku z tym ich pole zastosowania jest ograniczone.

Producenci dostarczają także odpowiednich środowisk programowych. Przykładem może być oprogramowanie Quartus firmy Altera lub Xilinx ISE. Dostępne są także programy niezależne, takie jak Synplify Pro firmy Synplicity.

Wielkość układu

Rys. 5. Wejścia i wyjścia modułu Enchanced PLL układu Stratix firmy Altera

W trakcie oceny dostępnych na rynku produktów i poszukiwania układu, którego funkcjonalność i możliwości będą wystarczające, aby spełnić wymagania projektanta, dużą trudnością może okazać się porównywanie wielkości różnych FPGA. O ile działanie to w ramach jednej rodziny układów nie powinno sprawiać trudności, to umieszczenie w zestawieniu układów innej serii powoduje duże komplikacje. Wszystko to za sprawą wewnętrznej struktury, w której – jak to zostało opisane w pierwszej części tego artykułu – stosowane są komórki logiczne o różnej liczbie wejść. Co więcej, integrowane moduły pamięci także zwiększają objętość układu, ale tylko dla pewnego zakresu realizowanych funkcji. Producenci starają się podawać sposoby przeliczania liczby komórek jednego typu na komórki o innej liczbie wejść, ale mimo to często dosyć trudno jest wskazać, który z układów jest bardziej pojemny. Jeszcze bardziej skomplikowana może być próba porównania układu FPGA na strukturę ASIC. Przeliczanie FPGA na bramki lub tym bardziej na tranzystory mija się z celem, gdyż o ile w ASIC każdy tranzystor ma swoje zastosowanie i jest konieczny do działania układu, to w przypadku FPGA wiele z tranzystorów pozostanie niewykorzystanych – tj. nie będą pełnić jakiejkolwiek funkcji układowej.

Kwestia postępu

Czasami do finalnego etapu wyboru FPGA przechodzą układy, które różnią się głównie datą powstania. Na rynku dostępne są najnowsze i niewielkie FPGA, które zostały wykonane z wykorzystaniem nowoczesnych technologii, a liczba ich wewnętrznych komórek jest porównywalna z liczbą komórek układów o jedną lub kilka generacji starszych. W przypadku, gdy ceny obu układów jak i ich wydajności spełniają założenia projektowe, lub w obu przypadkach mogą być sensownym kompromisem, warto poszukać informacji na temat realnej użyteczności obu struktur. Rynek FPGA szybko się zmienia, i potrzeba czasu by niezawodność pojawiających się na nim produktów została zweryfikowana przez użytkowników.

Kolejne coraz mniejsze wymiary technologiczne pozwalają na produkcję układów o coraz mniejszym napięci zasilania, które w tej chwili może osiągać już wartość 0,9V. Dzięki tym postępom układy programowalne stosowane są w coraz szerszych zastosowaniach, choć nadal pracują głównie w urządzeniach przetwarzających sygnały w telekomunikacji, a coraz częściej także i w multimediach.

Marcin Karbowniczek

Zobacz również