CPU w FPGA
| TechnikaOd chwili pojawienia się na rynku układów programowalnych projektantom zaczęła towarzyszyć pokusa zsyntezowania własnego procesora. Początkowo bardzo ograniczona liczba zasobów pozwalała budować jedynie proste automaty i uproszczone rdzenie CPU, jednakże z czasem sytuacja uległa zmianie. Wzrost złożoności układów FPGA i niebotyczne niekiedy zasoby logiczne pozwalają w dzisiejszych czasach umieścić w układzie programowalnym procesor o bardzo złożonej architekturze.
Konkurencja na rynku między wiodącymi producentami FPGA i ich dążenie do jak największej oszczędności czasu projektantów sprawiły, że dostępna jest szeroka oferta gotowych rozwiązań. Duża różnorodność pozwala wybierać, poczynając od najprostszych 8-bitowych rdzeni, aż po konstrukcje 32-bitowe zawierające sprzętowe bloki DSP.
Mogą to być implementacje oparte na popularnej architekturze takiej jak ARM, bądź autorskie rozwiązanie producenta układu programowalnego, czego przykład stanowią procesory Nios i MicroBlaze. Wybór architektury, oprócz wpływu na wydajność i zużycie zasobów, wpływa także na sposób implementacji oraz determinuje, jakie narzędzia diagnostyczne będą dostępne.
Projekty wykorzystujące układ programowalny z obecnym w jego strukturze procesorem stały się popularne do tego stopnia, że producenci mają w swojej ofercie nawet rozwiązania zawierające sprzętowe ("twarde") rdzenie. Jest to znaczące ułatwienie pozwalające uniknąć wielu problemów z syntezą i testowaniem "miękkiego" procesora.
Specyfika procesora w strukturze FPGA
Układy programowalne na przestrzeni lat przeszły znaczącą ewolucję. Wczesne ich wersje były na tyle ograniczone, że niewielkie zasoby logiczne były wystarczające do realizacji niezbyt złożonych zadań, takich jak kontroler magistrali, czy realizacja funkcji boolowskich.
Wraz z rozwojem technologii produkcji półprzewodników możliwe stało się zwiększenie zasobów logicznych. Z czasem ich liczba wzrosła do poziomu pozwalającego myśleć o opisie i osadzeniu prostego procesora. Początkowo nawet 4-bitowe jednostki stanowiły satysfakcjonującą realizację tego zagadnienia. Przy okazji zaczęły się ujawniać pierwsze trudności i ograniczenia związane z rdzeniami syntezowanymi z zasobów logicznych FPGA.
Pierwszym tego przejawem była znacząco mniejsza wydajność niż standardowych mikroprocesorów. Wynikało to bezpośrednio z niemożności stosowania technik dostępnych jedynie podczas opracowywania układu scalonego od podstaw - zapewniających większą wydajność przy mniejszym zajęciu powierzchni półprzewodnika.
Przykład tego typu technik stanowią bufory trójstanowe niedostępne w układach programowalnych. Również wykorzystanie szybkich rejestrów wieloportowych wymaganych przez jednostkę centralną znacznie podnosi wydajność przetwarzania. Elementy te potrafią zapewnić równoległy dostęp kilku blokom przetwarzania jednocześnie. Wspiera to w znacznym stopniu przetwarzanie potokowe, gdyż możliwe staje się obliczanie adresu, wykonywanie obliczenia i zapis wyników w jednym cyklu zegara.
W FPGA tablice LUT (look-up table) oraz pamięć RAM, wykorzystywane do tego celu, nie zapewniają same z siebie jednoczesnego dostępu do kilku bloków funkcjonalnych. Konieczne jest opracowanie układu arbitrażu w ramach dostępnych zasobów logicznych odpowiedzialnego za emulację wielodostępu do rejestrów.
Moduł ten, syntezowany i umieszczany wewnątrz FPGA, będzie spełniał swoją funkcję, ale związana z nim nadmiarowość przyczyni się do obniżenia maksymalnej częstotliwości taktowania rdzenia. Optymalizacja CPU sprowadza się do znaczącej reorganizacji pracy potoku tak, aby maksymalnie ograniczyć wykorzystanie rejestrów wieloportowych w rdzeniu.
Powszechnym problemem napotykanym podczas opisu procesora jest tzw. ścieżka krytyczna. Stanowi ona najdłuższe połączenie pod względem czasu propagacji sygnału. Tym samym wyznacza maksymalną częstotliwość taktowania układu, dla jakiej sygnał zdąży się na takiej ścieżce ustabilizować przed wystąpieniem zbocza sygnału zegarowego.
Wzrost złożoności układu sprawia, że zwiększa się liczba elementów logicznych, przez jakie propagowany jest sygnał, co wydłuża czas stabilizacji sygnału. Rozwiązanie stanowi optymalizacja opisu sprzętu i jego upraszczanie poprzez zmianę stosowanych konstrukcji i/lub wykorzystanie przetwarzania potokowego.
Problem ścieżki krytycznej stał się szczególnie dotkliwy, gdy projektanci rozpoczęli implementację bardziej złożonych rdzeni, takich jak np. ARM. Pojawiło się przekonanie, że procesory osadzone w strukturze FPGA są wolne, zużywają znaczne ilości energii i wykorzystują dużą ilość zasobów logicznych. W zaistniałej sytuacji implementacja CPU straciła na atrakcyjności.
W odpowiedzi na taki stan rzeczy Altera podjęła się opracowania procesora od podstaw z uwzględnieniem całej specyfiki układów programowalnych. W wyniku stosowania konstrukcji i technik naturalnych dla układów programowalnych oraz silnej optymalizacji opisów sprzętu powstał procesor Nios. Pomimo ograniczeń spełnia on swoją funkcję w większości typowych zastosowań.
Podobną strategię, opartą ma własnym, starannie zaprojektowanym rdzeniu, przyjął Xilinx, udostępniając projektantom procesor MicroBlaze z autorską architekturą. Do grona tego dołączyły także niezależne firmy oferujące gotowe rozwiązania oparte na ARM czy MIPS zaadaptowane dla potrzeb układów programowalnych.
Zastosowania
W kontekście implementacji procesora w FPGA często pada pytanie o celowość takiego podejścia. Jest ono tym bardziej zasadne, że cena samodzielnego procesora może być niższa niż cena nawet najtańszych układów programowalnych. Pomimo tej oczywistości szacunki Altery wskazują, że w 30% sprzedawanych przez nią układów programowalnych umieszczany jest rdzeń Nios.
Niekiedy na taką decyzję wpływ mają przeprowadzone analizy wskazujące, że rezygnacja z zewnętrznego mikrokontrolera bądź procesora przyczyni się do oszczędności pieniędzy. Może to być spowodowane niemożliwością zdefiniowania wymaganego rozkładu wyprowadzeń procesora, co w przypadku FPGA pozwala zachować dużą elastyczność.
Ostateczna decyzja o wyprowadzeniach może być podjęta znacznie później i w razie potrzeby można ją zmienić, np. gdy urządzenia ma realizować nowe zadania. Osadzenie procesora bywa rozważane także w sytuacji, gdy dostępne w układzie programowalnym zasoby miałyby pozostać niewykorzystane, a dzięki obecności CPU możliwe jest uproszczenie i przyspieszenie pracy.
Okazuje się, że procesor stanowi najczęściej uzupełnienie dla zaimplementowanych bloków logicznych. Jako przykład można tu podać obsługę układów peryferyjnych (I²C, USART, przetworniki), nadzór nad poprawną pracą układów logicznych, realizację funkcji koprocesora w środowisku wieloprocesorowym lub w roli układu DSP. Ponadto obsługa interfejsów komunikacyjnych takich jak Ethernet, USB, SPI, USART jest łatwiejsza z wykorzystaniem CPU.
Niekiedy procesor może być użyty jako automat wielostanowy. Szeroki obszar zastosowań rdzenia Nios sprawił, że producent wzbogacił go o szereg dodatkowych funkcjonalności wspomagających jego pracę oraz moduł debugowania - rysunek 1. CPU dostępne jest w wariantach zoptymalizowanym pod kątem ekonomicznego zużycia zasobów bądź zwiększonej wydajności.
Warto wspomnieć o generatorze instrukcji umożliwiającym dodawanie nowych, samodzielnie zdefiniowanych rozkazów do listy tych już obsługiwanych. Najbardziej złożone aplikacje mogą zostać uruchomione w środowisku systemu operacyjnego Linux, w oparciu na dystrybucji przeznaczonej dla procesora Nios.
Xilinx opracował i udostępnił własny procesor MicroBlaze, który wpisuje się w trend zapewniania projektantom zoptymalizowanej jednostki CPU. Pakiet narzędzi EDK (Embedded Development Kit) jest zintegrowanym środowiskiem pozwalającym skonfigurować procesor i jego otoczenie oraz dodać potrzebne układy peryferyjne. Większość rzeczy można zrobić za pomocą kreatorów z graficznym interfejsem użytkownika, m.in.: wskazać, jakie moduły mają zostać dołączone, ustalić ich adres w przestrzeni adresowej.
Udostępniony kompilator języka C i debugger pozwalają tworzyć oprogramowanie szybciej i łatwiej, bez konieczności sięgania po dodatkowe narzędzia. Projektanci mają możliwość wykorzystania bloków sprzętowych opracowanych przez producenta, wśród których można wymienić liczniki, porty GPIO, port szeregowy, kontroler Ethernet, kontroler pamięci DDR, jednostki zmiennoprzecinkowe czy układy zarządzające pamięcią MMU. Podobnie jak dla Nios, również dla MicroBlaze dostępna jest dystrybucja Linuxa.
Warto wspomnieć, że Xilinx wprowadził na rynek układy z rodziny Zynq integrujące w sobie logikę programowalną oraz niezależny, sprzętowy procesor ARM Cortex-A9. Projektanci mają do dyspozycji wydajny, sprzętowy rdzeń procesora, dzięki czemu częstotliwość taktowania jest znacząco wyższa, a zasoby logiczne mogą zostać wykorzystane w innym celu.
Oferta Microsemi (dawniej Actel) obejmuje układy SoC (System on Chip) z rodziny SmartFusion wyposażone w blok logiki programowalnej, sprzętowy rdzeń Cortex-M3 oraz programowalne układy analogowe: ADC, DAC, komparator itp. Udostępniono także syntezowalne rdzenie oparte na architekturze 8051, Cortex-M1 oraz Leon. Ostatni z wymienionych jest przeznaczony do zastosowań militarnych.
Inny, liczący się na rynku producent układów programowalnych, jakim jest Lattice Semiconductor, opracował procesor oparty na rdzeniu LatticeMico32. Jest to autorska 32-bitowa architektura harwardzka z rozdzielonymi magistralami danych i programu. Jest ona funkcjonalnie zbliżona do wielu współczesnych rozwiązań i oferuje 5-stopniowy potok przetwarzania rozkazów, obsługę szybkiej pamięci RAM oraz pamięci cache, a układy peryferyjne mają postać bloków IP.
Na tle konkurencji wyróżniającą cechą LatticeMico32 jest otwarty dostęp do kodu źródłowego jednostki centralnej i niektórych bloków peryferyjnych. Również narzędzia przeznaczone dla tej jednostki są oparte na wolnych rozwiązaniach bazujących na GNU GPL (GCC, Eclipse). Procesor z tego względu można osadzić w układach programowalnych dowolnego producenta. Konsekwencją takiego podejścia jest mniejsza optymalizacja rdzenia, niemniej projektanci mając dostęp do źródeł, mogą się z nimi zapoznać, zmienić i dostosować do własnych potrzeb.
LatticeMico znajduje zastosowanie głównie podczas realizacji złożonych zadań niewymagających dużej szybkości, czego przykład stanowi komunikacja z otoczeniem (zewnętrzne układy scalone, interfejs użytkownika itp.). Również zarządzanie układem programowalnym i jego otoczeniem może być z powodzeniem zrealizowane przez ten procesor, warto tu wskazać zwłaszcza na bieżące monitorowanie zasilania, ocenę wydajności przetwarzania czy monitorowanie bezpieczeństwa.
Pamięci TCMPamięć TMC (Tightly-Coupled Memory) obecna w układach z rdzeniem ARM11 powstała, aby zapewnić procesorowi szybki dostęp do pamięci z gwarantowanym czasem dostępu. Nadaje się ona m.in. do przechowywania kodu obsługującego przerwania, zawartości stosu przerwań czy zadania czasu rzeczywistego, w których nieokreślony czas dostępu typowy dla pamięci podręcznej jest niedopuszczalny. Pamięci TCM sprawdza się także przy przechowywaniu danych schowka systemowego, który jest problematyczny dla pamięci typu cache. Pamięć TCM może mieć rozmiar zawierający się w przedziale od 4 KB do 256 KB i może zostać przeznaczona do obsługi instrukcji i danych, instrukcji bądź danych lub zostać wyłączona. |