HDL

Działalnością w sferze HDL zajmują się:

Jeśli jesteś zainteresowana/y naszymi projektami lub współpracą kliknij tu. Jeśli interesują Ciebie informacje szczegółowe (linki zewnętrzne) kliknij na kącik linków. Czytaj dalej jeśli chcesz się zapoznać z tematyką HDL.
 

Wstęp

HDL (Hardware Description Language) - Język Opsiu Sprzętu. Potocznie (w żargonie inżynierskim) pojęcie używane głównie do określenia projektowania firmware dla układów programowalnej logiki (PLD, a w tym FPGA) lub struktur układów scalonych. Do projektowania firmware i struktur układów scalonych używa się hierarchicznych i strukturalnych języków opisu sprzętu takich jak VHDL lub Verilog (ale jest też wiele innych języków). Ponadto tworzy się języki i metody opisu elektroniki wszelakiej (cyfrowej, analogowej) - zatem samo pojęcie HDL jest znacznie szersze, jednak na dzień obecny szeroko rozpowszechnione głównie w celach wytwarzania plików konfiguracyjnych dla PLD oraz wytwarzania struktur układów scalonych.

Procesy projektowania firmware oraz struktur dla układów scalonych są lekko różne. W naszym kole zajmujemy się projektowaniem firmware dla PLD i na tym przykładzie podawane są dalsze informacje.

Zanim przejdziemy dalej w głąb HDL i wytłumaczymy sobie na czym to polega, to pierw wytłumaczmy sobie (krótko) czym w ogóle jest "programowalna logika"?
 

Logika Programowalna

Dawniej kiedy "wszystko było prostsze" były to układy scalone zawierające kilka do kilkuset tranzystorów połączonych w odpowiednią sieć (np. matryca połączeń każdy tranzystor z każdym). Użytkownik "wypalał" raz na stałe zadane połączenia! Dopiero później zaczęto tworzyć układy oparte o pamięci, które pozwalały na rekonfigurację tych układów.

I co mogły takie układy? Dokładnie to co mogłoby odpowiednie połączenie tranzystorów (np. można było tworzyć bramki logiczne, przerzutniki, etc).

PLD używano (i do dziś się używa) m.in. do: zmniejszenia zajętości powierzchni płytki (miniaturyzacja), tworzenia różnych wariantów funkcjonalności bez żadnej zmiany na płycie PCB, oraz do wytworzenia równoległego przetwarzania/przepływu danych.

Dziś układy programowalnej logiki tworzone są z odpowiedniej sieci setek milionów tranzystorów i komórek pamięci, które ponadto tworzą bardzo złożoną architekturę (różne w przypadku różnych układów i producentów). Typowo użytkownik nie ma już dostępu do najmniejszych komórek i pojedynczych tranzystorów, ale od razu do całych struktur tworzonych przez tranzystory np. do przerzutnika lub matrycy pamięci 18x18 bit. Obecnie wytwarza się w tych układach nawet pewne elementy analogowe (realizujące zadania na dzień dzisiejszy niezastępowalne sposobami cyfrowymi) takie jak: pętle synchronizacji fazy (PLL), szybkie (wielo-giga-bitowe) nadajniki oraz odbiorniki.
 

Projekt HDL

Tworzenie projektu w języku HDL polega na opisie tekstowym (lub graficznym) z wykorzystaniem odpowiedniego poziomu abstrakcji. Warto wyróżnić i krótko opisać kilka z tych poziomów:

  • Najwyższym możliwym poziomem byłby opis funkcjonalny, gdzie projektant napisałby "Chcę by mój układ PLD rozpoznawał twarze i katalogował je do bazy danych", po czym wcisnął Enter i już by działało - bez przejmowania się jak układ PLD jest użyty, czyli bez potrzeby wiedzy o jego tzw. architekturze (tu jej przykład). Do dnia dzisiejszego nie opracowano jeszcze tworzenia projektów z wykorzystaniem takiego poziomu abstrakcji... i daleko jest ludzkości jeszcze do jego opracowania :(
  • Najniższym poziomem z kolei jest opis połączenia danych węzłów - czyli opis jakie tranzystory mają przewodzić, a jakie nie. Dziś tworzenie całego projektu tym sposobem wymagałoby ręcznego skonfigurowania tranzystorów, których liczba sięga rzędu miliarda i ponad! Ponadto dogłębna informacja o architekturze PLD jest ukrywana przed użytkownikiem przez projektantów samego PLD - chroni to ich produkt przed skopiowaniem. PLD jest jednak wciąż konfigurowane za pomocą plików zawierających informację o tysiącach połączeń! - rzecz w tym, że taki plik tworzy za nas odpowiednie narzędzie :)
  • Behawioralny, gdzie projektant określa dla zadanego bloku zależności (czasowe, logiczne, arytmetyczne) pomiędzy sygnałami wejściowymi, wewnętrznymi oraz wyjściowymi. Konstrukcje językowe o poziomie behawioralnym typowo wykorzystywane są przy symulacjach do tworzenia plków testowych (testbench) oraz do modelowania działania (ale tylko w symulatorze!) dowolnego bloku (np. urządzenia zewnętrznego). Na obecny dzień popularne (komercyjne) narzędzia nie są w stanie dokonać syntezy z behawioralnego opisu.
  • Przesłań międzyrejestrowych (Register-transfer Level - RTL, lub czasami Dataflow Level). Na tym poziomie planowana funkcjonalność jest opisywana konstrukcjami językowymi logiki kombinacyjnej (bramek, pamięci, multiplekserów, etc) oraz logiki sekwencyjnej (zazwyczaj synchronicznej - przerzutniki). Na dzień obecny konstrukcje te są syntezowalne w prawie każdym narzędziu - w zasadzie obecnie projekty HDL są to same konstrukcje RTL!!!
  • Logiczny, gdzie planowane funkcje opisuje się jako wyrażenia logiczne, które realizowane są poprzez swoje odpowiedniki kombinacyjne (bramki, pamięć stała) i sekwencyjne (przerzutniki).
  • Bloków podstawowych, do których projektant jedynie podłącza sygnały wejściowe i wyjściowe i nie ma wpływu na ich implementację. Jest tak w przypadku użycia tzw. rdzeni, zamkniętych bloków IP oraz elementów architektury danego PLD (np. przy korzystaniu z PLL).
  • Transaction-Level Modeling (TLM). Używany w języku SystemC i wykorzystywany do opisu (głównie w celach symulacji) rozległych systemów. Na tym poziomie wszystkie połączenia pomiędzy blokami (czyli fizycznie najczęściej magistrale, lub interfejsy bazujące na FIFO) widziane są jako wirtualne "kanały" umożliwiające transfer danych. Pozwala to projektantom na używanie (przy symulacjach) funkcjonalnych bloków bez potrzeby martwienia się o wspólny interfejs jakim bloki powinny być połączone. Typowo każdy blok ma inny interfejs i dopasowywanie jednego bloku do interfejsu drugiego może trwać bardzo długo. Przy użyciu TLM projektant systemu (względnie) szybko zweryfikuje jakie bloki nadają się do projektu całego sytemu, gdzie w danych blokach należy wprowadzić poprawki w realizowanych algorytmach, a nawet stwierdzić o nieprzydatności danego bloku. Ponadto "kanały" można modelować (w tym jako istniejące interfejsy), co pozwala w łatwy sposób na weryfikację systemu, jak i na wyliczanie maksymalnych transferów i osiągów całego systemu. Ostatecznie dzięki TLM dalsi (pod)projektanci systemu dostają informację jaki interfejs (na poziomie RTL) powinni zaimplementować dla swojego bloku.
  • Electronic System-Level (ESL). W praktyce jest to poziom abstrakcji pozwalający na syntezę z konstrukcji języków takich jak: C (OpenCL), C++, SystemC (czyli ESL pozwala na High-Level Sythesis). Projektant nie musi wiedzieć prawie nic o PLD i projektowaniu RTL! Poziom abstrakcji w szczególności przydatny dla rozwiązań gdzie procesor połączony jest z PLD, gdzie wówczas w PLD implementowany jest koprocesor (np. graficzny). W 2012 firmy Xilinx oraz Altera wprowadziły na rynek rozwiązania ESL (w tym oczywiście syntezatory).

Przy tworzeniu projektu często miesza się różne poziomy abstrakcji, gdyż różne rzeczy łatwiej (mniej kodu) opisuje się z wykorzystaniem różnych poziomów abstrakcji.
 

Etapy projektu HDL

Podczas wykonywania projektu HDL można wyróżnić kilka etapów:

1. Koncepcja oraz dobór układu PLD (przeważnie FPGA).

W PLD można zaimplementować niemalże dowolną (cyfrową) elektronikę (dowolną funkcję). Już na etapie opracowywania koncepcji ustala się co będzie realizowane za pomocą PLD, a co będzie realizowane przy pomocy innych układów scalonych - zatem projektowanie firmware istnieje na styku projektowania PCB.
W zależności od projektowanej funkcjonalności w HDL zachodzi dobór odpowiedniego PLD (obecnie głównie FPGA). Jest tak dlatego, że implementowana funkcjonalność wymaga pewnej ilości zasobów PLD. Typowo projektant PCB zapyta projektanta HDL "jakiego PLD mamy użyć w projekcie?". Na takie pytanie łatwo odpowiedzieć, kiedy kod HDL został już napisany (i zweryfikowany). Taka sytuacja byłaby dla drużyny projektowej idealna.
Niestety często jest tak, że kod nie jest dostępny podczas początków (albo nawet i do samego końca) projektowania PCB - a jakiś układ PLD przecież trzeba wybrać. W takim przypadku trzeba pewne rzeczy umieć przewidywać, wyliczać i oszacowywać - najlepiej z (lekkim) nadmiarem na margines błędu. Takie rachunki może wykonać zarówno projektant PCB, który zna się dostatecznie na układach (architekturach) PLD oraz HDL, lub może zrobić to projektant HDL, który rozumie potrzeby całej płyty PCB wraz z wymaganiami koncepcyjnymi.

2. Wytwarzanie firmware.

Napisane w zwykłych plikach tekstowym konstrukcje językowe (z różnego poziomu abstrakcji), lub schematy bloków graficznych wraz z ich połączeniami, poddawane są pod kolejne procesy wytwarzania firmware (tutaj przykład przepływy dla narzędzie ISE):

  • Konwersja schematów graficznych (jeśli zostały użyte) na HDL
  • Preprocessing tesktu
  • Sprawdzenie składni (parsowanie)
  • Linkowanie
  • Synteza
    Proces polegający na rozpoznawaniu i konwersji struktur językowych z wszystkich plików HDL w projekcie do: jednego zwartego opisu RTL, opisu technologicznego i netlisty (tu przykładowy przepływ syntezy). Tworzony opis RTL nadaje się do podglądu oraz symulacji. Tworzony opis technologiczny wraz netlistą zawiera znacznie więcej detali związanych z wykorzystaniem faktycznej architektury używanego w projekcie PLD - nadaje się on również do podglądu (ale znacznie trudniej go zrozumieć). Netlista jest z kolei opisem, który jest przetwarzany przez dalsze procesy. Ponadto opis technologiczny wraz z netlistą są już poddawane optymalizacjom takim jak: usuwanie zadeklarowanych ale nigdy nie używanych przerzutników, dzielenia tabilc LUT, i wielu innym.
  • Symulacja (Opcjonalna)
    Otrzymany w wyniku syntezy opis można poddać symulacjom w odpowiednim narzędziu (np. w ModelSim). Symulacja jednak jest jedynie tak dobra jak skonstruowane modele - tzn. aby np. uzyskać informację o opóźnieniu całego systemu należy zamodelować opóźnienia dla każdego (lub wszystkich kluczowych) elementów. Dostępne są typowo dwa rodzaje symulacji: logiczna i czasowa. "Symulacja Logiczna" nie zawiera żadnej informacji o opóźnieniach, a weryfikujemy jedynie poprawność wyrażeń logicznych kombinacyjnych i sekwencyjnych.
    "Symulacja czasowa" jest symulacją, gdzie wszytkim elementom zostały przypisane (przez używane narzędzie do tworzenia firmware) pewne opóźnienia. W tego rodzaju symulacji możliwe staje się zaobserwowanie efektów takich jak: naruszenia setup i hold time (w tym metastabilność), propagacji sygnałów w elementach logiki kombinacyjnej (powstawanie glitch'y i hazardów).
    Ponadto w dla celów symulacji, jeśli jakiś blok HDL jest bardzo złożony, to typowym podejściem jest zamodelowanie go całkowicie w języku programowania (takim jak C). Tak zamodelowany blok kompiluję się i uruchamia. Wówczas symulator nie musi wykonywać wielu (set) linii kodu, a zamiast tego komunikuję się z danym modelem jak z innym programem w systemie operacyjnym.
  • Implementacja
    Wynik syntezy przetwarzany jest kolejno przez następujące procesy:
    1. Translacja
    Zachodzi konwersja wyników syntezera (RTL, netlisty) na wew. plik opisu dla danego narzędzia oraz wybranego PLD - format tego pliku najczęściej nie jest ujawniany przez producentów. Na tym etapie RTL i netlist zamienia się już na elementy bloków standardowych z danego PLD. Jest to pierwszy z etapów, który wykrywa błędy w niepoprawnym użyciu zadanej architektury PLD - syntezer tego nie wykonuje!
    2. Mapowanie
    Zachodzi przypisanie blokom standardowym ich wstępnej pozycji, tak aby zoptymalizować projekt pod względem użytych elementów oraz zajętości powierzchni (czyli tak aby "zmieścić" zaprojektowany firmware do użytego w projekcie PLD).
    3. Routing
    Zachodzi dalsze rozmieszczanie (przesuwanie) bloków standardowych oraz przemieszczanie połączeń pomiędzy nimi tak aby zoptymalizować opóźnienia, zużyte bloki standardowe, powierzchnię, a nawet moc (wszystko wg. ustawień w projekcie).
    4. Kompilacja
    Wytworzony podczas implementacji obraz firmware jest kompilowany do postaci pliku binarnego (lub innych formatów) - generowany jest wsad.
  • Konfiguracja
    Jest to ostatni etap polegający na załadowaniu (wgraniu) pliku konfiguracyjnego (wsadu) do PLD (stricte do pamięci PLD). Po tym etapie nasz PLD jest gotowy do testów na "żywo"! Są różne sposoby konfiguracji oraz metody wgrywania wsadu (tutaj przykład dla układów z rodziny Spartan-6). Typowym jednak podczas "deweloperki" jest używanie interfejsu JTAG przez który można łączyć układy PLD oraz pamięci FLASH w łańcuch (daisy chain) - wówczas wszystkie widziane są w naszym narzędziu i gotowe by wgrać do nich wsad.
3. Uruchamianie i debugging firmware

Uruchamiania i testowanie PLD nie należy do rzeczy trywialnych. Dzieje się tak dlatego, że podczas symulacji nie "wychwyci" się wszystkiego, gdyż symulacja jest zależna od modeli i typowo nie wszystkie efekty będą w niej widoczne. Ponadto jeśli jeden z bloków nie działa poprawnie, to nie znaczy, że reszta bloków nie działa poprawnie, gdyż PLD daje możliwość aby bloki były od siebie niezależne. Dlatego też typowym podejściem jest testowanie małych bloków (jeden po drugim) zanim złoży się je w jedną całość. Niestety i takie podejście nie gwarantuje nam poprawnie działającego systemu jako całość :( Ponadto nie ma dostępu przez oscyloskop co rzeczywiście dzieje się w naszym układzie. Rozwiązaniem problemu zazwyczaj jest implementacja analizatorów stanów lub sygnałowych. Wówczas należy w projekcie przewidzieć na ich realizację dostateczną ilość zasobów: pamięci, komórek logicznych oraz pinów wejścia/wyjścia. Na uwagę zasługują też rozwiązania analizy przy użyciu samego intefejsu JTAG pozwalającego "podpatrzeć" wartości sygnałów i zawartości pamięci w PLD. Ponadto w dobrych narzędziach projektowych istnieją rozwiązania takich analizatorów (w postaci bloków IP) zintegrowanych wraz ze środowiskiem (SignalTap, Chipscope)
 

Nasza działalność

Obecnie w kole naukowym w ramach specjalności związanej z HDL tworzone są projekty dla systemów elektronicznych opartych o standardy: FMC, VME, (u)TCA oraz dla komputerów przemysłowych (na których uruchamiamy również systemy wbudowane).

Nasze projekty skupiają się głównie na wykorzystaniu zaawansowanych układów cyfrowych takich jak mikro-procesory (uP), procesory sygnałowe, układy programowalnej logiki (FPGA, CPLD). Projektujemy złożone systemy elektroniczne, szybkie analogowe front-endy, komputery przemysłowe, karty typu add-on: PCIe, FMC, PCI, VME, uTCA, urządzenia wyposażone w interfejsy RF (BT, WIFI, Zigbee), kamery przemysłowe i astronomiczne, a nawet studenckie projekty typu low-cost ;).

Jeśli jesteś osobą ciekawską i chcesz zobaczyć jak to wszystko działa lub też chcesz się wdrożyć w tematy HDL, ale nie bardzo wiesz jak i gdzie zacząć, to zachęcamy do odwiedzenia nas na 6 piętrze - pokój 603B. Możesz też napisać e-mail do wymienionych osób. Możesz też zapisać się na nasz "tutorial" dot. projektowania HDL na przykładzie projektowania w Xilinx ISE lub Quartus.

Osoby posiadające już umiejętności zapraszamy do dołączenia do koła w celu realizacji bardziej zaawansowanych projektów, które przy odrobinie wysiłku mogą stać się nie tylko dobrą zabawą, ale również waszą pracą dyplomową!
 

Znani producenci PLD

Kącik Linków

Narzędzia

Tutoriale

  • VHDL: 1, 2,

ESL

ARM Cortex-A9 SoC FPGA

ARM Cortex-M3 Soc FPGA