MERA-400 - asynchroniczne CPU (film, 41 minut)
Na kanale MERA 400 przyjrzano się nietypowemu procesorowi MERY 400, który wprowadza ciekawe rozwiązania technologiczne. Z pewnością większość z nas ma na myśli prostokątne lub kwadratowe układy scalone, gdy słyszy się termin "procesor". Jednak MERY 400 odstaje od tego standardowego wyglądu dzięki swoim sześciu płytkom drukowanym z mnóstwem układów TTL. Autor podzielił się szczegółami na temat architektury i budowy tego procesora, wyjaśniając, jak kilka pakietów pełni swoje role we wspólnym działaniu, by procesor mógł realizować zadania. W skład CPU wchodzi 530 różnych układów, głównie produkcji krajowych firm, a autor miał możliwość oszacować ilość tranzystorów, jakie w nim zawarto. Powiedział, że to około 20 tysięcy, odnosząc się do zasady Mura, która mówi o podwajaniu liczby tranzystorów w mikroprocesorach co dwa lata.
MERA 400 przybliżył również samą strukturę procesora. Pakiety odpowiedzialne za różne funkcje mają przypisane symbole, co pomaga w identyfikacji ich ról. Widać, jak konstruktorzy musieli uwzględnić kompaktowość układów w obudowie minikomputera. Diagramy pokazujące interakcje między różnymi komponentami oraz automaty ze stałymi czasami są istotnym elementem pracy MERY 400. W szczególności znaczną rolę odgrywa blok sterowania, który decyduje o sekwencji mikrooperacji, które mają być realizowane dla każdej instrukcji. To właśnie mikrooperacje stanowią fundament działania procesora.
Autor zwrócił uwagę na różne trudności związane z zarządzaniem czasem przy realizacji instrukcji. W przypadku procesora MERY 400 postawiono na asynchroniczność, co pozwala na uniknięcie ograniczeń wynikających z jednego zegara taktującego. Zamiast tego, różne komponenty procesora mogą działać w swoim własnym tempie, co w praktyce przekłada się na większą swobodę w wykonywaniu obliczeń. Asynchroniczne podejście, w którym nie ma okresowego taktu zegara, stało się świetnym rozwiązaniem dla tego konkretnego procesora, zwłaszcza, że musiał on radzić sobie z różnymi czasami propagacji sygnału.
MERA 400 podkreślił także, jak ważny jest odpowiedni czas przetwarzania danych. Użycie elementów opóźniających oraz sygnałów kontrolnych, takich jak sygnały POT czy GOT, pozwala na synchronizację działań bez potrzeby generowania zegara. Zastosowanie zestawów mikrooperacji w praktyce umożliwia wydajniejsze przetwarzanie danych i lepsze zarządzanie całym rozwiązaniem. Dodatkowo, autor przybliżył realia, w których powstawał procesor MERY 400, wskazując na wyzwania, z jakimi przyszło się zmierzyć jego twórcom.
Na końcu filmu, który osiągnął 113873 wyświetlenia i 3680 polubień w momencie pisania tego artykułu, autor zachęca widzów do dalszego odkrywania magicznego świata asynchronicznych procesorów, mając nadzieję, że jeszcze więcej takich innowacyjnych rozwiązań pojawi się na rynku komputerowym. MERA 400 podsumowuje, że technologia asynchroniczna posiada ogromny potencjał, który być może doświadczymy w przyszłości, w miarę jak rozwój technologiczny postępuje. Fani MERY 400 z niecierpliwością oczekują kolejnych interesujących informacji na temat tej unikalnej architektury.
Toggle timeline summary
-
Pozdrowienie.
-
Dyskusja na temat typowego wizerunku procesora.
-
Wzmianka o starszych projektach procesorów 8-bitowych.
-
Oczekiwanie na mały układ scalony.
-
Wprowadzenie do procesora MERY400.
-
Podsumowanie dyskusji z poprzedniego odcinka.
-
Skupienie na obudowie i architekturze CPU.
-
Wyjaśnienie pozycji pakietów procesora.
-
Każdy pakiet odpowiedzialny za funkcjonalność.
-
Budowa procesora z wykorzystaniem obwodów TTL.
-
Wykorzystanie krajowych i zagranicznych komponentów.
-
Łącznie 530 obwodów w CPU.
-
Dyskusja na temat liczby tranzystorów dla złożoności procesora.
-
Wykres ilustrujący prawo Moore'a.
-
Porównanie z innymi procesorami.
-
Osobne oszacowanie liczby tranzystorów dla MERY400.
-
Pozycja MERY400 wśród CPU.
-
Przegląd funkcji pakietu kontrolnego.
-
Złożoności wprowadzane przez ograniczenia projektowe.
-
Dyskusja na temat ograniczeń przestrzennych w obudowie CPU.
-
Wprowadzenie do bloków funkcjonalnych i ich działania.
-
Porównanie architektur procesorów.
-
Wprowadzenie do funkcji kontrolnych.
-
Identyfikacja mikrooperacji dla wykonania instrukcji.
-
Wyjaśnienie mikroprogramu w działaniu procesora.
-
Przegląd schematu kontrolnego MERY400.
-
Dyskusja o decyzjach projektowych wpływających na architekturę CPU.
-
Oczekiwanie na rozwiązania asynchroniczne w przyszłych komputerach.
Transcription
Dzień dobry. Kiedy słyszycie słowo procesor, to na myśl przechodzi Wam pewnie sporych rozmiarów kwadratowy układ scalony z mnóstwem padów lub pinów pod spodem. Jeśli jesteście z bardziej 8-bitowych czasów, to być może pomyślicie o układzie w podłużnej obudowie DIP z dwoma rzędami nóżek po bokach. Ale niemal na pewno pierwszym skojarzeniem nie będzie sześć płytek drukowanych o wymiarach 30x30 cm wypełnionych elektroniką. No, chyba że jesteście stałymi widzami kanału, bo właśnie tak wygląda procesor MERY400. W poprzednim odcinku poświęconym procesorowi opowiadałem o jego możliwościach. Dziś zajrzymy trochę głębiej. Będzie o obudowie i architekturze CPU. Pakiety procesora zajmują w jednostce centralnej pozycję od czwartej do dziewiątej. Każdy z nich odpowiedzialny jest tylko za fragment jego funkcjonalności. Dopiero zainstalowane na swoich miejscach, dzięki połączeniom na platerze systemu, działają wspólnie jako jednokompletne CPU. Procesor zbudowany jest w całości z układów TTL z bipolarnej serii 74, choć tu i ówdzie znajdziemy też układy z szybszej rodziny 74H. Na pakietach zdecydowanie dominują układy produkcji krajowego CEMI, ale bez trudu znajdziemy też układy TESLI czy TUNGSAM. Układy zachodnich producentów są rzadkością i są to niemal wyłącznie modele, których wschodnie odpowiedniki nie istniały. Na całe CPU składa się razem 530 takich układów. Czy to dużo? Trudno powiedzieć. Niewiele ta liczba mi mówi. Podobnie jak Wy przyzwyczajony jestem raczej do wyrażania złożoności procesorów za pomocą liczby tranzystorów, z których są zbudowane. Wartości te, naniesione na wykres dla różnych procesorów w kolejnych latach, obrazują prawo mura mówiące, że ilość tranzystorów w mikroprocesorach podwaja się co mniej więcej dwa lata. Procesory ujęte na tym wykresie to układy scalone, zbudowane z tranzystorów MOS, a więc technologicznie zupełnie inne niż procesor Amery 400. Ale ta różnica nie przeszkodzi mi oczywiście w naniesieniu na ten wykres również naszego minikomputera. Policzyłem ile jest w nim układów TTL danego typu i znając mniej więcej ich budowę oszacowałem ile tych tranzystorów w sumie jest. Wyszło mi, że około 20 tysięcy. Jeśli nanieść te 20 tysięcy na wykres, przyjmując rok 76 za debiut procesora, choć przypominam ta architektura powstała w roku 71, jako procesorka 202, to trafimy idealnie w trend prawa mura. Swoją drogą tuż obok Intela 8086, który już ostatnio posłużył nam za porównanie. Te 530 układów wlutowane jest na sześciu tak zwanych pakietach, płytkach drukowanych ze złączami krawędziowymi pozwalającymi na zainstalowanie ich w obudowie minikomputera. Każdy z nich ma swój symbol i nazwę mówiącą o jego głównej roli. Od góry w jednostce centralnej zainstalowane są kolejno. Pakiet sterowania o symbolu PX zawiadujący pracę procesora. Pakiet mikrooperacji PM, na którym powstają sygnały wyzwalające działanie poszczególnych funkcji CPU. Pakiet dekodera PD, na którym dekodowane są rozkazy odczytane z pamięci. Pakiet przerwań PP, gdzie obsługiwane są przerwania. Pakiet rejestrów PR, na którym mamy rejestr uniwersalny procesora. I pakiet arytmometru PA, zajmujący się dodawaniem, odejmowaniem i operacjami logicznymi. Nazwy pakietów wydawałyby się dość jednoznaczne, ale różne ograniczenia konstrukcyjne powodują, że robią one czasami więcej niż by to z nazwy wynikało. Projektując pakiety, konstruktorzy minikomputera musieli uwzględnić to, że miejsce na procesor w jednostce centralnej jest ograniczone, że na każdym z nich zmieści się około 100 układów, a styków na złączu krawędziowym, umożliwiających połączenia z innymi pakietami, jest 192. To powoduje, że lokalizacja niektórych obwodów podyktowana jest bliskością innych funkcji procesora. Na krawędzi każdego z pakietów znajdziemy jego pełny symbol. Środkowy człon to znane już Wam oznaczenie jego funkcji. Tuż zanim mamy wersję schematu, na podstawie którego pakiet powstał. W praktyce ten człon nigdy się nie zmienia, mimo że na pakietach pojawiały się zmiany względem oryginalnych schematów. Na początku oznaczenia mamy natomiast wersję płytki drukowanej. I ta literka dla odmiany zmieniała się kilkukrotnie w ciągu 10 lat produkcji MERY-400. Z tych sześciu pakietów tylko trzy ostatnie zajmują się faktycznym przetwarzaniem danych. Rolą pozostałych trzech jest niemal wyłącznie sterowanie działaniem tej drugiej połowy. Mając na uwadze ten podział pół na pół między sterowaniem a przetwarzaniem danych, spójrzmy teraz na schemat blokowy procesora, który znajdziemy w dokumentacji. Każdy występujący na nim element opatrzony jest oznaczeniem mówiącym na jakim pakiecie się on znajduje. Informacja bardzo przydatna, kiedy trzeba wyśledzić co się zepsuło, ale nam posłuży teraz za przewodnik. Na pakiecie rejestrów mamy przede wszystkim blok rejestrów uniwersalnych. Stąd wzięła się jego nazwa. Osobnym układem jest rejestr R0 przechowujący również flagi procesora. Ich wyjścia spotykają się na szynie L, z której dane przekazywane są dalej. Mamy tu też rejestr ładowania binarnego, łączący się z kolejną, wewnętrzną szyną KI. Teraz pakiet przerwań. Znajdziemy na nim rejestr zgłoszeń przerwań i rejestr przyjęć przerwań wraz z całą logiką obsługującą ich priorytety. Jest tutaj też rejestr statusu procesora SR, którego większą część stanowią maski przerwań, stąd jego lokalizacja na tym właśnie pakiecie. Na pakiecie arytmometru dzieje się chyba najwięcej. Mamy tam przede wszystkim jednostkę arytmetyczno-logiczną, rejestr AC i szynę A, z których pobiera ona argumenty operacji, oraz rejestr AT, w którym zapisywany jest jej wynik. Jest tutaj też główna wewnętrzna szyna procesora, szyna W, oraz rejestr adresowy i licznik rozkazów. Te dwa ostatnie wylądowały tutaj ze względu na ich połączenia z szynami A i W oraz funkcjonalną bliskość z sumatorem. Odsłoniłem zawartość dopiero trzech pakietów, tych przetwarzających dane, a schemat jest już właściwie kompletny. Co więc z kolejnymi trzema pakietami zajmującymi się sterowaniem? Na tym schemacie pokazane one są bardzo, bardzo symbolicznie. A pamiętajcie, to cała druga połowa procesora. Ten schemat skupia się wyłącznie na tym, jak dane wędrują przez kolejne etapy przetwarzania. I jeśli spojrzeć na procesor Mary 400 od tej strony, to nie różni się on szczególnie od innych procesorów o podobnej złożoności. Trochę rejestrów, jakieś liczniki, ALU, a wszystko połączone wewnętrznymi magistralami. Całe sterowanie na takim schemacie jest zazwyczaj pomijane lub przynajmniej bardzo mocno upraszczane. I tak właśnie jest tutaj. A pod tym niewinnym bloczkiem sterowania kryje się sporych rozmiarów elektroniczny potwór, który swoimi mackami mikrooperacji wpina się do wejść sterujących każdego z elementów na schemacie. I to właśnie ten niewinny bloczek zawierający sterowanie sprawia, że procesor Mary 400 jest inny niż wszystkie, z którymi się do tej pory spotkaliście. Zacznijmy od prostego przykładu, który pokaże, jakie jest właściwie zadanie takiego sterowania. Spróbujmy na piechotkę zasymulować czynności, jakie muszą zostać wykonane przy realizacji pojedynczej instrukcji programu. Załóżmy dla uproszczenia, że procesor pobrał ją już z pamięci i umieścił w rejestrze rozkazu IR. Najpierw instrukcja musi zostać zdekodowana. Dekoder rozkazu ma za zadanie rozpoznać rozkaz, który pojawia się na jego wejściu. Na tej podstawie ustawia swoje sygnały wyjściowe, które mówią, co to za rozkaz, do jakiej grupy należy, jakiego rodzaju argumentów używa, gdzie te argumenty się znajdują itd. Tych sygnałów sterowanie używa później do podejmowania decyzji o tym, co kolejno należy zrobić, żeby taki rozkaz zrealizować. Załóżmy, że nasza instrukcja to dodawanie, które ma zsumować zawartości rejestrów R1 i R2, a wynik zapisać z powrotem w rejestrze R1. Patrząc na schemat łatwo odgadniemy, że oba argumenty muszą pojawić się na wejściach sumotora, a jego wyjście trzeba wziąć i zapisać w rejestrze R1. Na oko zadanie brzmi prosto, ale co tak naprawdę procesor musi zrobić? Najpierw przygotować pierwszy z argumentów. Wybrany zostanie rejestr R2 i jego zawartość pojawi się na wyjściu bloku rejestrów. Tę wartość trzeba podać dalej na szynę L, następnie na szynę A i na szynę W. A z szyny W można ją zapisać do rejestru AC, skąd za chwilę odczytają arytmometr. Pierwszy składnik gotowy, teraz kolejny składnik. Trzeba wybrać rejestr R1, jego zawartość podać znów na szynę L, a potem na szynę A, skąd jest już osiągalna przez jednostkę arytmetyczno-logiczną. W AL-u trzeba teraz wybrać funkcję dodawania, następnie wynik, który pojawi się na wyjściu zapisać do rejestru AT, stamtąd podać go na szynę W, wybrać rejestr R1 i wreszcie zapisać w nim wynik. Ta seria kroków brzmi już mniej prosto, prawda? A to jest właśnie najważniejsze zadanie sterowania. Określenie, jakie operacje i w jakiej sekwencji muszą zostać wykonane z każdej z instrukcji, które procesor ma wykonywać. Ta operacja nazywa się mikrooperacjami, bo każda z nich to najprostsza, najmniejsza część, jaką procesor wykonuje. Niektóre z nich będą wykonywane równolegle. Np. podczas przesyłania pierwszego składnika dodawania w jednym kroku może jednocześnie nastąpić wybranie rejestru R2 i odpowiednie przełączenie szyn L, A i W. W ten sposób, za jednym zamachem, utorowana zostanie cała droga sygnału od rejestru R2 aż do rejestru AC. Ale już zapisanie tej wartości w rejestrze AC będzie osobnym drugim krokiem, kolejną mikrooperacją w sekwencji. I tutaj wychodzi następne zadanie sterowania. Żeby przepłynąć z rejestru R2 do rejestru AC, sygnał potrzebuje trochę czasu. I ten czas potrzebny na propagację sygnału sterowanie musi zapewnić. Możemy zresztą zobaczyć ten konkretny czas na własne oczy. Zmierza opóźnienie między sygnałem wyboru rejestru R2, a momentem, kiedy jeden bit jego zawartości pojawia się na wejściu rejestru AC. Około 90 nanosekund. Sterowanie więc nie może próbować zapisu do rejestru AC w 80 nanosekundzie, bo zapisze jakieś bzdury. Ale z drugiej strony nie ma sensu czekać 500 nanosekund, bo nie chcemy przecież, żeby procesor pracował wolniej niż na możliwe. Podsumowując, najważniejsze zadania sterowania są dwa. Określenie sekwencji mikrooperacji, które będą wyzwalane dla każdej z instrukcji procesora, oraz zapewnienie odpowiedniego czasu na wykonanie każdej z nich, czyli taktowanie. Zajmijmy się najpierw kwestią sekwencji mikrooperacji. Nie ma wyjścia. Gdzieś musi ona być zapisana. Dla każdej z instrukcji procesora. Kiedy wyliczałem kolejne kroki, które trzeba wykonać podczas realizacji dodawania, to mogliście sobie pomyśleć, że brzmi to trochę jak kolejne kroki jakiegoś ukrytego wewnętrznego programu procesora. Takiego mikroprogramu, bo składa się on z mikroinstrukcji. Jeśli takie było wasze skojarzenie, to wymyśliliście właśnie zasadę sterowania przynajmniej połowy procesorów, które powstały w ostatnich kilkudziesięciu latach. Mikroprogram. Ewoluowała ona oczywiście wraz z technologią, ale istota jest właśnie taka. W procesorze jest nieduży obszar szybkiej pamięci stałej, w której zapisane są kolejne mikroinstrukcje. Zestawy mikrooperacji, które musi on wykonać, realizując pojedynczy rozkaz pobrany z pamięci komputera. Tym wykonaniem steruje automat, którego zadanie z grubsza ogranicza się do wybierz mikroinstrukcję, wykonaj ją, przejdź do następnego kroku. I tak do końca sekwencji. Taki sposób określania sekwencji mikrooperacji znajdziemy chyba we wszystkich współczesnych procesorach CISK. Ale w procesorach RISC i czasami w niektórych szczególnych jednostkach wykonawczych procesorów CISK spotkamy inne rozwiązania. Takie, które może jest bardziej skomplikowane i mniej elastyczne, ale za to szybsze i nie potrzebuje żadnej dodatkowej pamięci. I choć procesor MERY400 to CISK, więc wydawałoby się, że nie ma żadnego innego drugiego sposobu na sterowanie. Zwróćcie uwagę, że w tych sekwencjach i grupach mikrooperacji dla różnych rozkazów będzie mnóstwo podobieństw. Instrukcje dodawania, odejmowania, sumy i iloczyny logicznego będą różniły się wyłącznie operacją ustawioną w arytmometrze. A skok względny to znów nic innego jak dodawanie, tyle że jakiejś stałej do licznika rozkazów, a więc jednym z argumentów będzie właśnie on, a nie rejestr uniwersalny. Jeśli by rozpoznać te podobieństwa, które mamy w procesorze z ich uwzględnieniem, to można każdą taką grupę funkcjonalnie nierozłącznych mikrooperacji powiązać ze stanem jakiegoś automatu sterującego ich wyzwalaniem. Wtedy kolejne stany uruchamiałyby różne grupy mikrooperacji, a warunkami przejść między stanami byłoby to jaka instrukcja jest wykonywana, jakich argumentów używa, jaki sposób adresowania został użyty czy podczas wykonania wystąpiły jakieś sytuacje wyjątkowe itd. W ten sposób sekwencja mikrooperacji wyznaczona byłaby tym, jak one zostały wykonywane podczas wykonywania danego rozkazu. Bez żadnej dodatkowej pamięci, jedynie garści jednobitowych rejestrów do pamiętania stanu automatu i proste elementy logiczne, które niezależnie od użytej technologii będą zawsze najszybsze. I takie sterowanie znajdziemy właśnie w procesorze MERY400. Do najprostszych to ten automat nie należy, nie oszukujmy się. Ma 24 stany, a jego opis zajmuje w dokumentacji 24 strony. Schemat przepływu danych, ale nie ma nic w stopniu skomplikowania tych układów. Nie będę Was zanudzał jego szczegółowym opisem, ale chciałbym dać Wam ogólny obraz tego jak jest zbudowany. Na rysunku pokazującym cały automat z lotu ptaka widać cztery bloczki kryjące główne pętle sterowania. Pętlę pobrania rozkazu i przygotowania argumentów, pętlę wykonania rozkazu, obsługę przerwań, o której nie wspominałem, a jest ona realizowana i można ją wykonać z pulpitu technicznego. Spójrzmy co kryje się w takim na przykład bloku pętli pobrania rozkazu. Składa się ona z siedmiu stanów z nazwami widocznymi w lewym górnym rogu każdego z nich. Każdy stan na tym schemacie to tabelka z dwoma kolumnami. Po lewej stronie są mikrooperacje, które w danym stanie mogą wystąpić, a po prawej warunki, w jakich są one uruchamiane. Czasami te warunki są puste, oznacza to, że dana mikrooperacja jest wyzwalana bezwarunkowo. Czasami ten warunek jest prosty. Na przykład do stanu P2 procesor wejdzie zawsze, kiedy rozkaz jest nieefektywny. Ale wejście do stanu P5 warunkowane jest już całkiem sporym wyrażeniem. Przyznacie, że na tym jednym kawałku automatu, a to tylko 7 z 24 jego stanów, dzieje się dużo. Ale prawdziwa jazda zaczyna się dopiero w pętli wykonania rozkazu. Jej schemat rozpościera się na kilka stron dokumentacji. Najpierw mamy ogólne spojrzenie opisujących to, co dzieje się podczas realizacji każdego z rozkazów. Kolumny tego opisu to kolejne grupy rozkazów. Grupy, ponieważ, jak mówiłem wcześniej, niektóre rozkazy są z punktu widzenia ich wykonania niemalże takie same. Natomiast wiersze to stany procesora, które mogą być odwiedzone podczas wykonywania rozkazu z danej kolumny. W komórkach tabeli mamy zestawy mikrooperacji. Poszczególne stany w pętli wykonania, podobnie jak stany w pętli pobrania rozkazu, mają swoje mikrooperacje bezwarunkowe, wykonywane zawsze. Takie mikrooperacje są przede wszystkim wykonywanym rozkazem, ale czasami też innymi dodatkowymi warunkami opisanymi po prawej stronie komórki. Numerki w lewym górnym rogu komórek mówią natomiast o kolejności, w jakiej stany są odwiedzane. Zamiast mikroprogramu mamy więc w procesorze MERY-400 sporych rozmiarów automat skończony, sterujący wszystkimi aspektami jego pracy. I to jego budowa wprost decyduje o tym, co kiedy w procesorze się dzieje. Jak mówiłem, nie jest to jakieś niespotykane rozwiązanie, ale dlaczego tak? Dlaczego automat, a nie mikroprogram? Co stało za taką decyzją architektoniczną? Na to pytanie niestety nie potrafię odpowiedzieć. Ale wiem, kto potrafi. Pani Ela, która razem z mężem, panem Andrzejem, odpowiedzialna jest za projekt zarówno procesora MERY-400, jak i jej poprzednika, K202. Przy K202 tak samo nazwa wskazuje, mikroprogramowanie, to jest programowanie. Czyli musi być komputer, na którym to się robi. Nie było ani języka do mikroprogramowania, ani kompilatora, mikroasamblera do mikroprogramowania, ani komputera, na którym on by mógł chodzić i wypluć tam mikroprogram, ani programatora do promów. Tego nie było. To znaczy to już na świecie istniało, ale myśmy tego nie mieli. Myśmy mieli kartkę A1, zresztą ogromne płakty i ołówki. Po pierwsze się nie dało, a po drugie to było związane z naszymi doświadczeniami. Moimi przy opracowywaniu arytmometru SAMA, to też był automat skończony i Karpińskiego przy CAR-65, on też zrobił sterowanie na automatu. Także to naturalnie, to narzędzie w ten sposób się projektowało wtedy. Przy K-202 to w ogóle nikt się nie zastanawiał. Zresztą nie było żadnej możliwości, żeby nawet podjąć inną decyzję, bo inaczej by maszyna nie powstała. Ale jak patrzę z historii, bo później jak pracowałam na komputerach, oprojektowałam komputery we Francji i w Stanach, to mikroprogramowałam. Ale to była fabryka do tego zrobiona. Były języki, na komputerach to się kombinowało, były symulatory, na których się sprawdzało, zanim się wypaliło. To trzeba było mieć kadr, czyli design, żeby to zrobić. Czyli trzeba było mieć jakiś komputer, matkę. Przyznacie, że główny powód wyboru takiego, a nie innego rozwiązania jest tyleż prozaiczny, co z perspektywy dzisiejszych czasów nieoczywisty. Wiedząc już, jak określana jest w naszym minikomputerze sekwencja mikrooperacji, możemy zająć się drugą sprawą. W jaki sposób zapewniany jest odpowiedni czas na ich realizację, mówiąc inaczej, jak taktować procesorów. Zacznijmy od czasów współczesnych. Wszystkie komercyjne procesory, z którymi spotykamy się na co dzień, są układami synchronicznie sekwencyjnymi. Sekwencyjności poświęciłem ostatnich kilka minut. Natomiast synchroniczne, to znaczy takie, w których kolejne kroki ich pracy, kolejne etapy przetwarzania danych, wyzwalane są za pomocą jednego, równo nieprzerwanie tykającego zegara. To oczywiście jest jak zwykle tylko połowa prawdy. We współczesnych implementacjach taki zegar dla niektórych elementów funkcjonalnych będzie np. bramkowany, tylko czasami dotrze do celu. Dla innych będzie dzielony przez jakąś wartość, także zwolni np. czterokrotnie, albo wprost przeciwnie, będzie przyspieszany. Jego częstotliwość może być też zmieniona tuż u źródła, zwiększana, kiedy potrzeba więcej mocy obliczeniowej i zmniejszana, kiedy trzeba oszczędzać energię. Ale zawsze gdzieś na początku jest ten jeden, równo nieprzerwanie tykający zegar. Wróćmy na chwilę do wcześniejszego przykładu i spróbujmy takiego najprostszego, synchronicznego sterowania użyć do wykonania fragmentu operacji dodawania w procesorze m.400. Pierwszym jej krokiem było wybranie rejestru ze składnikiem sumy i przesłanie go przez trzy kolejne szyny procesora. Zmierzyliśmy, że zajęło to 90 ns. Załóżmy, że w najgorszym przypadku potrzeba na to 100 ns, a więc nasz synchroniczny zegar mógłby mieć taki właśnie okres, albo patrząc od drugiej strony, częstotliwość 10 MHz. Po tych 100 ns, w drugim kroku zapiszemy przesłaną wartość w rejestrze AC, po czym arytmometr będzie mógł rozpocząć obliczenia. On też będzie potrzebował na swoje działania chwili czasu. Załóżmy, że 120 ns, a to 20 ns dłużej niż okres zegara, który przed chwilą ustaliliśmy. Nie ma więc wyjścia, trzeba zegar zwolnić, żeby arytmometr mógł się wyrobić. Ale poprzedni krok będzie również taktowany tym samym zegarem, więc stracimy tam 20 ns na nic. Ta wartość pojawi się na wejściu rejestru wynikowego sumatora. Będziemy ją mogli tam więc zapisać i przesłać szyną W dalej do rejestru uniwersalnego. Ta operacja jest prosta i skończy się powiedzmy w 80 ns. Ale nasz zegar musi mieć okres 120 ns ze względu na arytmometr, a więc stracimy kolejne 40 ns. Na tym krótkim odcinku straciliśmy już razem 60 ns. Można to na wiele sposobów próbować obejść, ale taki skwartowany czas zawsze będzie powodował, że stracimy tylko trochę. A jakby tej straty było mało, to musimy jeszcze założyć margines bezpieczeństwa na zmiany czasów propagacji sygnałów spowodowane zmianami temperatury, napięć zasilania, czy po prostu różnicami między egzemplarzami okładów scalonych. A gdyby tak zrobić to jakoś inaczej, bez jednego globalnego zegara i wynikającego z niego niepotrzebnego czekania. A najlepiej to jakoś tak, żeby nie trzeba było też uwzględniać marginesów bezpieczeństwa. Żeby każdy kawałek funkcjonalności był bezpośrednio za nim, od razu wiedział, że może zaczynać swoje zadanie. Ten pomysł zrodził zupełnie nową klasę okładów sekwencyjnych. Układy asynchronicznie sekwencyjne. Znajdziemy w niej również procesory. Nazywamy je zazwyczaj bezzegarowymi, bądź po prostu asynchronicznymi. I do tej klasy okładów należy też procesor MERY-400. Współcześnie dzielimy układy asynchroniczne na trzy grupy. Pierwsza grupa to układy samotaktujące się. Self-timed, jak mówią za oceanem. W przypadku takiego układu, zajmującym się jakimś pojedynczym etapem przetwarzania danych, związany jest jego własny element opóźniający. Wyzwalany jest on sygnałem rozpoczęcia przetwarzania, który przychodzi z poprzedzającego go bloku. Ten sygnał powoduje, że element opóźniający wysyła sygnał startu do logiki, której pilnuje. Niemal identyczny jak sygnał zegara w przypadku układów synchronicznych. Ale jednocześnie zaczyna się odliczanie czasu. Czasu potrzebnego na przetworzenie danych na tym konkretnym etapie wysyłany jest sygnał do kolejnego bloku. Sygnał mówiący, że dane są już gotowe i teraz jego kolej. I cykl się powtarza, przy czym tym razem ten czas, określany przez kolejny element opóźniający, może być już inny. A to rozwiązuje nasz podstawowy problem, tych nanosekund traconych w oczekiwaniu na kolejny takt synchronicznego zegara. Tego typu układ jest łatwy w realizacji, ale wciąż ma jedną wadę. Nie rozwiązuje problemu marginesów bezpieczeństwa, który tutaj też trzeba założyć, tak samo jak przy układach synchronicznych. Układ, który jest zainstalowany na podstawie elektromotory, czy napięć zasilania. Na to magiczne opóźnienie ustalane jest raz, podczas projektowania układu i staje się nieodłączną częścią danego etapu przetwarzania. Trzeba więc policzyć je z zapasem. To też oznacza, że dowolna zmiana w układzie wymusza na projektancie ponowne ustalenie tego dedykowanego opóźnienia. Tej wady pozbawiona jest druga grupa układów asynchronicznych. Układy niezależne od prędkości elementów, z angielska SPEED INDEPENDENT, są zainstalowane w szejku. Oprócz danych binarnych przesyłanych między kolejnymi blokami, mamy tutaj dwa dodatkowe sygnały sterujące, żądania i potwierdzenia, albo pytania i odpowiedzi, jak niekiedy są nazywane. Ich zadaniem jest pilnowanie, aby dane przetwarzane były dopiero wtedy, kiedy są gotowe, a z drugiej strony, żeby gotowe pozostały tak długo, jak będą potrzebne. W momencie, kiedy pierwszy blok skończył swoją pracę i wystawił na wyjściu dane, po czym odpowiada zwrotnym sygnałem potwierdzenia, co dla poprzedzającego bloku jest informacją, że dane są już niepotrzebne i może zacząć przetwarzanie kolejnej porcji. Protokół ten występuje w różnych wersjach i implementacjach, wśród których pojawiają się już takie, które wykraczają poza standardowe operacje bólowskie. Trzeba za to zapłacić dodatkową złożonością sterowania, ale rezultat jest wręcz magiczny. Wyobraźcie sobie mikroprocesor, który zawsze pracuje tak szybko, jak tylko może. I to nie zmniejszy. Jeśli ogrzać albo obniżyć napięcie, zwolni. Brzmi jak science fiction, prawda? Ten sposób realizacji asynchroniczności nie rozwiązuje natomiast ostatniego problemu, jaki nam został, o którym jeszcze nie wspominałem. Opóźnień wprowadzanych przez połączenia między kolejnymi blokami i różnic między czasami propagacji na liniach poszczególnych bitów danych. Z tym szczegółem potrafi sobie poradzić ostatnia grupa układów. Układy niewrażliwe na opóźnienia, a w ogóle czarna magia do uprawiania, której trzeba niestety wyjść poza normalne sygnały zero-jedynkowe. Każdy bit danych jest tutaj przesyłany dwoma liniami, ponieważ oprócz zera i jedynki może mieć jeszcze trzeci stan. Nul, czyli brak danych. A z tą informacją na każdym etapie można jednoznacznie stwierdzić, czy na wejściu już są wszystkie dane, czy być może któreś bity jeszcze nie są gotowe albo właśnie jeszcze nie dotarły do odbiorcy, bo płyną nieco dłuższą drogą. W tym rozwiązaniu występuje również zwrotne potwierdzenie, że dane zostały skonsumowane i że może on zacząć przetwarzać kolejną ich porcję. Takie układy zachowują wszystkie fantastyczne właściwości układów SI, a dodatkowo nie trzeba sobie zawracać głowy długością połączeń między kolejnymi elementami układu. Tutaj drobna uwaga formalna. Układy prawdziwie niewrażliwe na opóźnienia są niepraktyczne, bo nie realizują żadnej funkcji logicznej. Dlatego w praktyce spotkamy jedynie układy CUDA i quasi-delay-insensitive, które wprowadzają jedno drobne rozluźnienie pozwalające zastosować je do budowania układów przetwarzających dane. Ta drobna modyfikacja zbliża je do układów SI, o których mówiłem wcześniej i literatura czasami traktuje je równoważnie. Mamy więc trzy możliwe poziomy asynchroniczności, a każdy z nich bardziej zakręcony od poprzedniego. A to jeszcze nie koniec. Nie dość, że każdy z nich można zrealizować na kilka sposobów, to w złożonych układach asynchronicznych takich np. procesorach można je ze sobą dowolnie łączyć. Karygodnie, pobieżnie. Nie chcę Was zamęczać bardziej niż to konieczne dla ustalenia współczesnej perspektywy, z której spojrzymy zaraz na procesor MERY-400. Ale jeśli temat Was zainteresował, to gorąco polecam książkę profesora Jensa Sparsu Wstęp do projektowania układów asynchronicznych. Jest ona dostępna jako darmowy PDF. Link w opisie filmu. To świetne podsumowanie ostatnich 40 lat prac w tej dziedzinie. Napisane językiem na tyle zrozumiałem, na ile to możliwe w przypadku tematyki, które nie dostrzegałem. No ale wróćmy wreszcie do MERY-400. Jej asynchroniczny procesor wykorzystuje warianty dwóch z podejść, o których mówiłem. Zdecydowanie dominuje pierwsze z nich. Niemal cały procesor jest self-timed, czyli używa elementów opóźniających, które wyznaczają czas potrzebny na przetwarzanie danych na każdym etapie. Opowiadając o sekwencji mikrooperacji mówiłem, że ich grupy związane są ze stanami procesora. Wejście do danego stanu powoduje ich uruchomienie. Czas przeznaczony na wykonanie takiego zestawu mikrooperacji określany jest przez związany z nim element opóźniający. W MERY-400 tym najmniejszym samotaktującym się blokiem funkcjonalnym jest więc w praktyce pojedynczy stan procesora. Czy będąc bardziej precyzyjnym jest nim te kilka obwodów procesora, które biorą udział w przetwarzaniu danych w danym stanie procesora. Ale sposób implementacji tego rozwiązania odbiega od książkowego przykładu układów self-timed. Niektóre z nich będą potrzebowały niemalże takiego samego czasu na wykonanie swoich zadań. Można by więc użyć tych samych elementów opóźniających do taktowania różnych stanów. I dokładnie to zrobili projektanci procesora. Ale poszli w tej unifikacji jeszcze krok dalej. Takich taktów różnej długości jest w procesorze MERY-405. Układy, które je generują zostały zebrane w jednym centralnym układzie, a nie z konkretnego stanu CPU, czyli dwa nigdy nie wystąpią razem. Można więc było wyjścia tych układów zsumować i przesłać jedną linią do wszystkich obwodów procesora. Ten sygnał to sygnał strobu. Podawany jest on na wejścia zegarowe przerzutników, rejestrów i liczników w iloczynie z sygnałem wyzwolenia mikrooperacji. Innymi słowy, bramkowany jest sygnałem mikrooperacji, wyzwalając ją, gdy przychodzi na nią czas. Patrząc na realizację tego taktowania ten sygnał strobu rozprowadzony jest po procesorze niczym zegar w konstrukcjach synchronicznych. I to w tej konstrukcji strasznie mi się podoba. Mamy procesor asynchroniczny z jego główną zaletą, długością taktów dostosowaną do potrzeb, a jednocześnie sposób realizacji zapożycza główną zaletę taktowania synchronicznego, jego prostotę. Ale żeby zbyt prosto nie było. Część stanów procesora rzeczywiście używa tylko jednego sygnału strobu, wyzwalającego jedną grupę mikrooperacji. Ale do realizacji zadań używa dwóch osobnych zestawów mikrooperacji uruchamianych w sekwencji, ale wciąż w ramach jednego stanu. Dlatego mamy jeszcze jeden dodatkowy sygnał strobu, strob 2. Ten ma zawsze taką samą długość, a więc generowany jest przez jeden element opóźniający i doprowadzony jest tylko do wybranych stanów procesora. I tu kolejny kawałek układanki wpada na swoje miejsce, tym razem dotyczący schematu automatu. Możemy z niego wyczytać, które mikrooperacje wyzwalane są przednim, z dwoma gwiazdkami. Mało tego, dowiemy się też, że niektóre mikrooperacje wyzwalane są przednim zboczem sygnału, gwiazdka ze strzałką do góry, a inne tylnym, strzałka w dół. A niektóre w ogóle nie są wyzwalane zboczem, tylko poziomem sygnału. Te nie mają żadnej strzałki. Omówiliśmy to, jak w każdym ze stanów procesora wyzwalane są mikrooperacje, ale do kompletnego obrazu brakuje nam jeszcze jednej rzeczy. Czegoś, co powodowałoby przejścia między stanami procesora. Zobaczmy to w wielobitowym rejestrze. Każdy jego bit to jeden stan. Zawartość tego rejestru, które jest było-nie było jakąś informacją, daną, używana jest przez układy generujące sygnały strobów do podjęcia decyzji o tym, który strob należy w danym momencie wyzwolić. Mamy tu więc dwa współpracujące ze sobą asynchroniczne bloki funkcjonalne. Ten drugi, generator strobów, musi poczekać aż ten pierwszy, rejestr stanu automatu, przetworzy dane, które pojawiły się na jego wejściu. A to znaczy, że ten zapis aktualnego stanu automatu musi również podlegać asynchronicznemu taktowaniu, na takich samych zasadach jak taktowanie mikrooperacji. Potrzebujemy więc jeszcze jednego elementu opóźniającego, który efektywnie definiuje czas potrzebny na przejście z jednego stanu automatu do drugiego. Ten sygnał ma nazwę GOT i to ostatni z siedmiu sygnałów taktujących, jakie znajdziemy na pakiecie PX. Siedmiu. Tak jak i siedem jest potencjometrów na krawędzi pakietu, służą do strojenia długości czasów trwania poszczególnych opóźnień. Co jest kolejnym sprytnym, praktycznym rozwinięciem książkowych układów self-timed. Pokażę Wam teraz, jak te sygnały wyglądają podczas wykonania krótkiego programu. W ten sposób będziecie mogli na własne oczy zobaczyć, jak w praktyce wygląda takie asynchroniczne taktowanie procesora. Na ekranie oscyloskopu mamy trzy sygnały. GOT, strop 1 i strop 2. Wszystkie w logice ujemnej, oznacza to, że procesor taktowany jest tylko wtedy, kiedy pracuje. Przed włączeniem klucza start nie dzieje się nic. Po zatrzymaniu programu również nastaje cisza. Nie ma zawsze tykającego zegara. Zanim uruchomiłem procesor był on w stanie spoczynkowym P0. Podnosząc klucz start spowodowałem wykonanie mikrooperacji z tym stanem związanych. Odpowiada za to ten pierwszy impuls strobu pierwszego. Zanik impulsu strobu następuje pobranie rozkazu z pamięci. Po dłuższej przerwie, do której jeszcze wrócimy, pojawia się znów sygnał strobu pierwszego, tym razem dla stanu P1. Jego tylne zbocze wyzwala strop 2, a więc stan P1 jest jednym z tych, które odpalają dwa zestawy mikrooperacji. Tylne zbocze tego sygnału wyzwala kolejny sygnał GOT, który powoduje przejście procesora do kolejnego stanu. Tylne zbocze GOT wyzwala znów sygnał strop 1 dla tego stanu. Tylne zbocze strop 1 wyzwala sygnał GOT dla tego stanu itd. Widać na tych przebiegach obie rzeczy, o których mówiłem wcześniej. Po pierwsze, sygnał strobu drugiego pojawia się tylko w niektórych stanach procesora. Po drugie, o ile sygnały GOT i strop 2 mają zawsze tę samą długość, o tyle strop 1 czasami jest dłuższy, a czasami krótszy. Wyraźnie widać tutaj trzy różne długości impulsu. No i znów, całe to taktowanie można zrobić synchronicznie. Robiąc współczesną implementację procesora Mary 400 dla FPGA, jest to świetna technologia, a architektura procesora pozostała niezmieniona. Dlaczego więc w oryginalnym procesorze mamy ten szalony, asynchroniczny taniec, a nie prosty, równo tykający zegar? Tym razem łatwiej byłoby mi zgadywać, ale skoro mamy panią Elę na linii, to niech i na to pytanie autorka rozwiązania odpowie sama. Jakby mikroprogramowanie, automaty skończone, to automatycznie nie ma zegara. Bo zegar ma ciąg, co mu chcą mierzyć? Jaki czas? Powiedzmy na najgorszy przypadek, czyli operacja arytmometru z maksymalnym czasem propagacji przeniesienia. Bo to jest w komputerze ten czas najdłuższy. A później te inne operacje, które są krótsze, to co? To będą... Czekały dłużej, no bo już został ten zegar ustawiony. Czy na pamięć? Ale myśmy poza tym nigdy nie widzieli, na jakich elementach będzie procesor zrobiony. Przy K202 to były importowane elementy. Ale przy MER-ze to nigdy nie było wiadomo, czy to z demolu dupy i jaka naprawdę ma być szybkość. I wtedy do każdego właściwie egzemplarza się tą szybkość dobierało optymalną. I operacje trwały tyle, ile musiały trwać. I czas był nie na najgorszy przypadek, jakby przy zegarze musiało być, tylko na taki rzeczywisty czas. Operacje krótsze trwały krócej, logiczne przesłania, operacje arytmetyczne musiały trwać dłużej. A więc chodziło nie tylko o tę główną, praktyczną zaletę rozwiązań asynchronicznych, ale również o realia, w jakich procesor powstawał. I była jeszcze ta dziwna przerwa w stanie P1 między sygnałami GOT a strob 1. Jak mówiłem, w tym stanie następuje pobranie rozkazu z pamięci. I ma ono miejsce właśnie w tej dziurze. A dlaczego nie towarzyszą tej operacji żadne takty? Dlatego, że ten jeden, jedyny kawałek procesora, odpowiedzialny za dialog z magistralą, a więc również za pobranie słowa z pamięci, nie jest taktowany żadnym elementem opóźniającym. I wtedy od razu została przyjęta decyzja, że działa się asynchronicznie na zasadzie pytania-odpowiedź. Wszystko jest na interfejsie. Tak samo pytanie-odpowiedź, żeby do maksimum wykorzystać czas. Jak szybsza pamięć nawet mogła być w tej samej konfiguracji, że jeden egzemplarz pamięci krótszy, szybszy, długa, z cyklem dłuższym, z czasem dostępu dłuższym. Ten kawałek używa protokołu handshake'u z pytaniem i odpowiedzią. O którym mówiłem opisując drugi ze sposobów realizacji asynchroniczności. Można powiedzieć, że z perspektywy CPU dostęp do magistrali jest niezależny od prędkości elementów. W tym konkretnym przypadku niezależny od prędkości pamięci, z której rozkaz jest pobierany. Nieważne, czy podłączę do mojej Mary 400 wolną pamięć ferżytową Elwro, czy szybszą o 40% pamięć półprzewodnikową Computexu, czy zrobię współczesny moduł pamięci na kościach DDR4. To wszystko po prostu zadziała. Komunikując się po magistrali obie strony dialogu dogadują się co do tego, kiedy dane są gotowe i kiedy są już niepotrzebne. Procesor nie ma więc potrzeby odgórnego ustalania czasu trwania tego dialogu. Ale nie jest to niezależność od prędkości w rozumieniu podziału, który Wam wcześniej zaprezentowałem. Używamy co prawda protokołu handshake'u, ale druga strona tego dialogu działa używając elementów opóźniających. Ba, w środku może być nawet synchroniczna. Ale z punktu widzenia CPU nie jest to problem. I jeszcze jeden, ostatni już element układanki. Na pakiecie mikrooperacji są dwa dodatkowe potencjometry. A więc podejrzewać można, że jakieś dwa kolejne elementy opóźniające mają za ich pomocą ustalane swoje czasy. I faktycznie. Te elementy pilnują dwóch szczególnych stanów procesora. KC i PC. Koniec i początek każdego cyklu pracy. Pierwszy jest szczególny, bo wymaga więcej czasu niż drugi. Drugi natomiast jest dziwny, bo tak naprawdę występuje jednocześnie ze stanem P1. Dlatego musi być osobno taktowany. Ale idea jest tutaj taka sama jak dla wszystkich pozostałych stanów. Coś musi określić czas ich trwania. Po prostu służą do tego dwa osobne elementy opóźniające. Czy słuchając tych moich opowieści o procesorach asynchronicznych nie odnieśliście przypadkiem wrażenie, że jest to technologia przewyższająca procesory i nie jest to tak. W roku 1988 grupa badawcza Alana Martina z Kalifornijskiego Instytutu Technicznego zbudowała pierwszy asynchroniczny mikroprocesor. Miał on architekturę QDI quasi delay insensitive. Układ zasilany napięciem już nieco ponad 0,4 V działał i wykonywał dodawanie z szybkością 3 instrukcji na sekundę. Po podniesieniu napięcia do 1 V wynosiła ona już około 500 tysięcy instrukcji na sekundę. Przy 10 V 26 mln operacji na sekundę. Wyższym napięciem go zasilono. Wykonany w takiej samej technologii porównywalny synchroniczny procesor WISC miał bardzo podobną prędkość, ale zżerał 4 razy więcej energii. Układ zgodnie z teorią reagował też na temperaturę. Wersja wykonana w dwumikrometrowej technologii zasilana 5 V w temperaturze pokojowej robiła około 10 mln operacji na sekundę. Ochłodzona do prawie minus 200 stopni Celsjusza przyspieszała do 20 mln operacji na sekundę. Sama z siebie. W 1998 Philips wypuścił Pager, który na takiej samej baterii jak pagery konkurencji pracował dwa razy dłużej. Używał on asynchronicznej implementacji procesora 8051. W latach 95-98 Intel prowadził projekt o wdzięcznej nazwie Rapid, w ramach którego powstała asynchroniczna implementacja jednego z ówczesnych komercyjnych procesorów Pentium. Działała trzy razy szybciej niż jej synchroniczny i dodam do tego jeszcze o połowę mniejszy pobór energii, to mniej więcej teraz powinniście zadać pytanie, dlaczego wszystkie procesory nie są asynchroniczne? Z brutalną szczerością najlepiej odpowiada na nie pan Ken Stevens, który pracował nad Rapidem. Jeśli procesor jest trzy razy wydajniejszy, ale jego wprowadzenie na rynek zajmuje pięć razy więcej czasu, przegrywasz. Procesor z Pagera Philipsa, o którym wspomniałem chwilę temu, rodził się 10 lat. Jest to procesor, który jest bardzo trudny w tworzeniu, projektowaniu, trudny w testowaniu i debagowaniu. Wciąż uczymy się, jak je robić. Mimo już 70 lat rozwoju, ta technologia nadal jest z tyłu za rozwiązaniami synchronicznymi, które w międzyczasie nauczyliśmy się robić dobrze, szybko i efektywnie. Do projektowania okładów synchronicznych mamy doskonałe metody i narzędzia. W świecie asynchronicznym powoli one dopiero powstają. I mogą by współpracować, choćby z pamięciami i magistralami. Problemów jest wiele, ale może jest światełko nadziei. Taki np. Pentium 4, choć na zewnątrz synchroniczny, w środku używał asynchronicznych pomysłów zaczerpniętych z projektu Rapid. Czy współczesne, komercyjne procesory mają jakieś asynchroniczne fragmenty? Nie wiem, nie udało mi się znaleźć jednoznacznej odpowiedzi. Jeśli coś o tym wiecie, koniecznie dajcie znać w komentarzach. Ale ponieważ granice aktualnej nie są wykluczone, że rozwiązania asynchroniczne jeszcze się w naszych komputerach pojawią. Na co ja, fan asynchronicznej Mary 400, będę czekał z utęsknieniem. Do zobaczenia.