ZPU (procesor)

ZPU to mikroprocesorowa maszyna stosowa zaprojektowana przez norweską firmę Zylin AS do uruchamiania kodu nadzorczego w systemach elektronicznych zawierających programowalną przez użytkownika macierz bramek (FPGA).

ZPU jest stosunkowo nową maszyną stosową z niewielką niszą ekonomiczną i ma rosnącą liczbę użytkowników i wdrożeń. [ Potrzebne źródło ] Został zaprojektowany tak, aby wymagał bardzo małych ilości logiki elektronicznej, udostępniając więcej logiki elektronicznej do innych celów w FPGA. Aby był łatwy w użyciu, ma port GNU Compiler Collection . Dzięki temu jest znacznie łatwiejszy do zastosowania niż procesory bez kompilatorów. Poświęcając szybkość w zamian za niewielkie rozmiary, przechowuje pośrednie wyniki obliczeń w pamięci, w stosie przesuwanym, a nie w rejestrach.

Zylin Corp. udostępnił ZPU jako open source w 2008 roku.

Stosowanie

Wiele projektów elektronicznych zawiera logikę elektroniczną w układzie FPGA. Posiadanie mikroprocesora jest marnotrawstwem, więc powszechne jest dodawanie procesora do elektronicznej logiki w FPGA. Często mniejszy, tańszy FPGA mógłby być użyty, gdyby tylko procesor zużywał mniej zasobów. Właśnie do takiej sytuacji zaprojektowano ZPU.

ZPU jest przeznaczony do obsługi różnych zadań systemu, które najlepiej obsługuje oprogramowanie, na przykład interfejs użytkownika. ZPU jest bardzo powolny, ale jego mały rozmiar pomaga umieścić dowolny potrzebny szybki algorytm w FPGA.

Inną kwestią jest to, że większość procesorów dla układów FPGA to procesory o zamkniętym źródle, dostępne tylko od konkretnego producenta układów FPGA. Czasami projekt musi mieć projekt, który można szeroko rozpowszechniać, do kontroli bezpieczeństwa, zastosowań edukacyjnych lub z innych powodów. Licencje na te zastrzeżone procesory mogą uniemożliwić takie użycie. ZPU jest open source.

Niektóre projekty wymagają kodu, który musi być mały, ale uruchamiany na procesorze, który z natury ma większy kod. Alternatywnie, projekt może skorzystać z szerokiego wyboru kodu, kompilatorów i narzędzi do debugowania dla GNU Compiler Collection. W takich przypadkach można napisać emulator, aby zaimplementować zestaw instrukcji ZPU na docelowym procesorze, a do wytworzenia kodu można użyć kompilatorów ZPU. Wynikowy system jest powolny, ale pakuje kod w mniej pamięci niż wiele procesorów i umożliwia projektowi korzystanie z szerokiej gamy kompilatorów i kodu.

Cechy konstrukcyjne

ZPU został zaprojektowany wyraźnie, aby zminimalizować ilość logiki elektronicznej. Ma minimalny zestaw instrukcji, ale może być zakodowany dla GNU Compiler Collection. Minimalizuje również liczbę rejestrów, które muszą znajdować się w układzie FPGA, minimalizując liczbę przerzutników. Zamiast rejestrów, wyniki pośrednie są przechowywane na stosie w pamięci.

Ma również mały kod, oszczędzający pamięć. Instrukcje maszyny stosowej nie muszą zawierać identyfikatorów rejestrów, więc kod ZPU jest mniejszy niż inne procesory RISC, o których mówi się, że zajmują tylko około 80% miejsca ARM Holdings Thumb2 . Na przykład podpisany natychmiast pomaga ZPU przechowywać 32-bitową wartość w maksymalnie 5 bajtach przestrzeni instrukcji i tylko w jednym. Większość procesorów RISC wymaga co najmniej ośmiu bajtów.

Wreszcie około 2/3 jego instrukcji można emulować za pomocą oprogramowania układowego zaimplementowanego przy użyciu pozostałych 1/3 „wymaganych” instrukcji. Chociaż wynik jest bardzo powolny, wynikowy procesor może wymagać zaledwie 446 tablic przeglądowych (miara złożoności FPGA, mniej więcej odpowiednik 1700 elektronicznych bramek logicznych).

ZPU ma wektor resetowania, składający się z 32 bajtów przestrzeni kodowej, zaczynając od lokalizacji zero. Ma również pojedyncze przerwanie czułe na krawędzie, z wektorem składającym się z 32 bajtów przestrzeni kodu rozpoczynającej się pod adresem 32. Wektory od 2 do 63 mają po 32 bajty przestrzeni, ale są zarezerwowane dla kodu emulującego instrukcje od 33 do 63.

Podstawowy ZPU ma 32-bitową ścieżkę danych. ZPU ma również wariant z 16-bitową ścieżką danych, aby zaoszczędzić jeszcze więcej logiki.

Narzędzia i zasoby

ZPU ma dobrze przetestowany port GNU Compiler Collection. Entuzjaści i inżynierowie oprogramowania sprzętowego przeportowali ECos , FreeRTOS i μClinux . Przynajmniej jedna grupa entuzjastów skopiowała popularne środowisko programistyczne Arduino i zaadaptowała je do ZPU.

Obecnie istnieje wiele modeli rdzenia ZPU. Oprócz oryginalnych rdzeni Zylin dostępne są również rdzenie ZPUino i rdzeń ZPUFlex. Rdzeń Zylin został zaprojektowany z myślą o minimalnej powierzchni FPGA i zawiera wersję 16-bitową. ZPUino ma praktyczne ulepszenia szybkości, może zastąpić emulowane instrukcje sprzętem i jest osadzony w strukturze system-on-chip. ZPUFlex jest przeznaczony do korzystania z zewnętrznych bloków pamięci i może zastąpić emulowane instrukcje sprzętem.

Projekty akademickie obejmują badania i ulepszenia efektywności energetycznej oraz badania niezawodności.

Aby poprawić szybkość, większość implementatorów zaimplementowała emulowane instrukcje i dodała pamięć podręczną stosu. Poza tym jeden z implementatorów powiedział, że architektura z dwoma stosami umożliwiłaby potokowanie (tj. zwiększenie szybkości do jednej instrukcji na cykl zegara), ale może to również wymagać zmian w kompilatorze.

Jeden z implementatorów zmniejszył zużycie energii o 46% dzięki pamięci podręcznej stosu i automatycznemu wstawianiu bramkowania zegara. Zużycie energii było wtedy z grubsza równoważne małemu Amber typu open source , który implementuje architekturę ARM v2a.

Częściami ZPU, które byłyby najbardziej wspomagane przez odporność na błędy, są szyna adresowa, wskaźnik stosu i licznik programów.

Zestaw instrukcji

„TOS” to skrót od „Top Of Stack”. „NOS” to skrót od „Next to the top Of Stack”.

Wymagany zestaw instrukcji ZPU
Nazwa Dwójkowy Opis
PUNKT PRZERWANIA 00000000 Zatrzymaj procesor i/lub przejdź do debuggera.
IM_x 1xxxxxxx Wypchnij lub dołącz podpisany 7-bitowy natychmiast do TOS.
SKLEPYSP_x 010xxxxx Rozłóż TOS i umieść go w stosie z przesunięciem od góry.
WCZYTAJ SP_x 011xxxxx Pobierz z wartości zindeksowanej na stosie i wepchnij ją do TOS.
EMULUJ_x 001xxxxx Emuluj instrukcję z kodem w wektorze x.
ADDSP_x 0001xxxx Pobierz z wartości indeksowanej na stosie i dodaj wartość do TOS.
POPPC 00000100 Wpisz adres z TOS i zapisz go na komputerze.
OBCIĄŻENIE 00001000 Wpisz adres i prześlij załadowaną wartość pamięci do TOS.
SKLEP 00001100 Zapisz NOS w pamięci wskazanej przez TOS. Pop oba.
PUSHSP 00000010 Wciśnij bieżące SP do TOS.
POPSP 00001101 Pop TOS i zapisać go do SP.
DODAĆ 00000101 Całkowite dodawanie TOS i NOS.
I 00000110 Bitowe AND z TOS i NOS.
LUB 00000111 Bitowe OR TOS i NOS.
NIE 00001001 Bitowe NIE z TOS.
TRZEPNIĘCIE 00001010 Odwróć kolejność bitów TOS.
NIE 00001011 Bez operacji. (Zwykle używany do pętli opóźniających lub tabel kodu).

Punkty kodowe od 33 do 63 mogą być emulowane przez kod w wektorach od 2 do 32: LOADH i STOREH (16-bitowy dostęp do pamięci), LESSTHAN (zestaw porównań 1 dla prawdy, 0 dla fałszu), LESSTHANOREQUAL, ULESSTHAN, ULESSTHANOREQUAL, SWAP (TOS z NOS), MULT, LSHIFTRIGHT, ASHIFTLEFT, ASHIFTRIGHT, CALL, EQ, NEQ, NEG, SUB, XOR, LOADB i STOREB (8-bitowy dostęp do pamięci), DIV, MOD, EQBRANCH, NEQBRANCH, POPPCREL, CONFIG, PUSHPC, SYSCALL, PUSHSPADD, HALFMULT, CALLPCREL