Kalkulator na układach TTL, czyli rozgrzewka przed…
Artykuł jest wstępem, prologiem do cyklu obszernych publikacji na temat aktualnie tworzonego przeze mnie komputera na układach TTL. Opowiada historię mojego niekonwencjonalnego wyboru, dzięki, któremu zacząłem podążać indywidualną drogą w swym elektronicznym świecie.
Lekka nutka filozofii
Nazywam się Rafał Wiśniewski. W maju bieżącego roku minęło właśnie 10 lat od pomysłu, a w zasadzie od spontanicznej myśli, która zmieniła moje elektroniczne życie o 180 stopni. Po latach porównuję to do wyimaginowanego modelu wszechświata, który był w idealnej symetrii, w idealnej równowadze termodynamicznej i ni stąd, ni zowąd nagle ten poukładany ład za pośrednictwem przypadku, wiru destabilizacji zaczął przekształcać się w strukturę chaosu. Ale ten chaos był tylko pozorny, bo z niego powstał kierunek zmian, a w zasadzie nowa droga stworzenia, która dąży do elektronicznej nieskończoności – cokolwiek to znaczy…
Osobiście cieszę się, że doznałem takiego olśnienia. Olśnienia, które uczyniło mnie szczęśliwym i spełnionym w płaszczyźnie dziedziny, jaką jest elektronika. Bardzo zapragnąłem być wolnym człowiekiem w dziedzinie, z którą utożsamiam się od dawien dawna. Co to znaczy wolnym? Trudne pytanie, niekiedy nawet retoryczne, lecz w moim mniemaniu to stan, w którym nie muszę mieć narzuconej woli świata, mody, sugestii innych osób. To stan, w którym jestem artystą, nie patrzę na ekonomię, nie patrzę na poświęcony czas, nie szukam za wszelką cenę poklasku i docenienia. Nie patrzę też na to, że już niemal wszystko wymyślono i to na wiele różnych możliwych sposobów. To wszystko jest bez znaczenia, to wszystko jest nieistotne. Istotne jest jedynie to, że wolność absolutnego wyboru na tej płaszczyźnie jest bezcenna. Nie da się tego kupić ani stworzyć z niczego. To trzeba poczuć, zachłysnąć się tym i utożsamiać się z tym bez względu na wszystko. Wtedy można powiedzieć, że jest się wolnym człowiekiem w swojej dziedzinie.
To wszystko spowodowało, że wróciłem do beztroskiego dzieciństwa, w którym poznawałem się z elektroniką i uczyłem się jej. Wymyślałem i budowałem najprzeróżniejsze urządzenia – z różnym skutkiem, ale to tylko uczyło pokory i powodowało jeszcze większą chęć poznawczą. Mam wiele sentymentalnych wspomnień z tamtego okresu, które na zawsze wyryły tęsknotę w moim umyślę, tęsknotę do projektowania, tworzenia i budowania urządzeń elektronicznych po swojemu, w całym znaczeniu tego słowa.
Zapewne to wszystko i jeszcze więcej zmiennych spowodowało, a w zasadzie zrodziło ten impuls, który poczułem ponad 10 lat temu. Zapragnąłem stworzyć kalkulator, kalkulator na kultowych układach TTL. Kalkulator w stylu retro bez użycia jakichkolwiek specjalizowanych układów. Wszystko na podstawowych funktorach logicznych… Pamiętam do dzisiaj jak kotłowało mi się wtedy w głowie. Jak nie przespałem tej pierwszej nocy, próbując pojąć jak działa kalkulator, jak i na jakiej zasadzie wykonuje działania matematyczne. Pochłonęło mnie to całkowicie, oprócz pracy w hurtowni budowlanej prowadziłem równolegle firmę naprawiającą sprzęt RTV, z której całkowicie zrezygnowałem i zawiesiłem działalność. Już mnie to nie satysfakcjonowało, naprawa sprzętów nie przynosiła mi radości jak kiedyś. Radością i sensem stało się projektowanie, tworzenie i konstruowanie ponad wszystko… I tak jest do dzisiaj!
Opis koncepcji urządzenia
Prezentowane urządzenie jest niekonwencjonalnym kalkulatorem, który nie zawiera żadnego specjalizowanego układu scalonego, takiego jak mikroprocesor, CPLD, FPGA, itd. Nie ma również typowej wyspecjalizowanej pamięci RAM ani ROM. Cała logika sterująca zbudowana jest z podstawowych układów cyfrowych w technologii TTL takich jak bramki logiczne, bufory, multipleksery, różnego rodzaju dekodery, przerzutniki, liczniki, rejestry przesuwające, dzielniki częstotliwości, komparatory i sumatory. W zarysie prezentuje to fotografia 1.
Mniej więcej jedna piąta wymienionych układów logicznych tworzy zaprojektowany przeze mnie procesor z 59 instrukcjami, w których może znajdować się od jednej do kilkunastu funkcji wykonawczych, które mogą być warunkowane jedną z 40 funkcji warunkowych. Nietypową pamięć RAM wykonałem na 99 sztukach czterobitowych uniwersalnych rejestrów przesuwających 74LS194, co sumarycznie daje 396 bitów – fotografia 2.
Natomiast pamięć ROM jest pamięcią diodową o łącznej pojemności 3840 bitów (fotografia 3).
Kalkulator składa się z czterech rejestrów: rejestry wprowadzania wartości A i B, które w trybie standardowym są 12-cyfrowe, rejestru pamięci M, który również jest 12-cyfrowy oraz rejestru wartości W, który jest 24-cyfrowy (dzięki temu np. mnożenie dwóch liczb 12-cyfrowych zawsze da maksymalny wynik 24-cyfrowy bez przepełnienia). Skonstruowany przeze mnie kalkulator działa na zasadzie trójpodziału władzy: władza ustawodawcza, czyli pamięć ROM, władza wykonawcza, czyli logika dekodująca instrukcję oraz władza sądownicza, czyli logika warunkująca zdekodowaną instrukcję.
Kalkulator ten realizuje następujące funkcje: niezależne wprowadzanie w aktywnym rejestrze (A lub B): cyfr od 0 do 9, ciągu 00, załączanie punktu dziesiętnego, cofanie wprowadzonych wartości, wyświetlanie liczby PI, zmianę znaku liczby, wprowadzanie obliczonego wyniku z rejestru W do aktywnego rejestru, zamianę argumentów w rejestrach wprowadzania, kopiowanie aktywnego rejestru wprowadzania do rejestru pamięci M, kopiowanie rejestru M do aktywnego rejestru wprowadzania, kasowanie błędu ERROR, rejestru M i całego urządzenia. Urządzenie to obsługuje następujące działania: dodawanie, odejmowanie, mnożenie, dzielenie, potęga kwadratowa, dzielenie przez odwrotność, pierwiastek kwadratowy i kompleksowe działania na procentach. Kalkulator prawidłowo obsługuje wszystkie działania na liczbach ujemnych i zgłasza wyjątki błędu ERROR takie jak: pierwiastek kwadratowy z liczby ujemnej, dzielenie przez zero oraz w przypadku działań na procentach takich jak dodawanie lub odejmowanie, gdy wystąpi przepełnienie.
Każde wybrane działanie matematyczne obrazowane jest na matrycy diod LED, która wyświetla odpowiedni symbol. Przykład przedstawiony jest na fotografii 4.
Klawiatura składa się z 33 przycisków – fotografia 5, które są w pełni interaktywne (te, które są podświetlone są aktywne, reagują na daną sytuację w czasie rzeczywistym, np. nie można wprowadzić zera do aktywnego rejestru wartości, gdy nie ma włączonego punktu dziesiętnego lub nie ma już wprowadzonej przynajmniej jednej cyfry większej od zera).
Kalkulator ten ma tryb podglądu przetwarzających się algorytmów w czasie rzeczywistym, co jest bardzo cenną funkcją (fotografia 6). Z tego powodu rejestry wprowadzania wartości A i B są wtedy 24-cyfrowe. Tryb ten może być automatyczny, czyli ze zwolnioną prędkością zegara obserwujemy przetwarzające się instrukcje (trybów ustawień prędkości jest 16) lub ręczny, gdzie przeznaczonym do tego przyciskiem podajemy pojedyncze impulsy zegarowe do sekwencera.
Tryb, o którym mowa oprócz tego, że na wyświetlaczach rejestrów obrazuje przetwarzający się algorytm, uruchamia jeszcze dodatkowo 16 wyświetlaczy, które dla odróżnienia są w kolorze zielonym (pozostałe „robocze” wyświetlacze są czerwone).
Wyświetlają one następujące informacje: dane wyjściowe ROM wraz z aktywnym w danej chwili ich adresem – wszystko to w kodzie szesnastkowym, wartości dziesiętne trzech liczników specjalnych (licznik pozostałych cyfr do policzenia pierwiastka kwadratowego, licznik pozostałych przesunięć w cząstkowej operacji arytmetycznej takiej jak dodawanie lub odejmowanie, licznik uniwersalny używany w algorytmach do różnych funkcji), wartości dziesiętne trzech liczników argumentów (licznik ilości powtarzanych dodawań dla mnożenia, dwa liczniki powtarzanych odejmowań dopóki A≥B dla dzielenia i pierwiastkowania).
Oprócz tego uaktywnia się również 36 diod LED „diagnostycznych”, które wyświetlają chwilowy stan obwodów zaangażowanych w przetwarzający się algorytm. Są to między innymi sygnały z sekwencera, sygnały uruchomionych bieżących wariantów, sygnały egzekwowania instrukcji, sygnały obsługujące pamięć ROM, sygnały relacji między wartościami liczb rejestrów A i B oraz między ich punktami dziesiętnymi, sygnały z arytmometru oraz sygnały załączonych funkcji pomocniczych. Również w tym trybie uaktywnia się 240 diod LED w pięciu kolorach, diody te sprzężone są bezpośrednio z kolumnami pamięci ROM. Ich kolory obrazują, jaki typ instrukcji wykonywany jest w danej chwili – mogą to być standardowe instrukcje (kolor żółty), instrukcje resetowania (kolor zielony), instrukcje ładowania równoległego (kolor pomarańczowy), instrukcje skoku (kolor niebieski) oraz instrukcje warunkowe (kolor czerwony).
Omówienie składowych bloków funkcjonalnych
Dla lepszego zrozumienia budowy i działania tego dość skomplikowanego urządzenia, warto przeanalizować schemat blokowy, który bardzo uprościłem, pokazany jest on na rysunku 7.
Składa się on z 27 modułów, które bardzo ogólnikowo opiszę:
Aktywator/dezaktywator przycisków klawiatury kalkulatora. Obwody zawarte w tym module mają za zadanie w czasie rzeczywistym wygaszać, a co za tym idzie wyłączać odpowiednie przyciski bądź grupy przycisków. Są to warstwy warunkowe nadrzędne o priorytetach 0 i 1, które chronią przed różnymi anomaliami takimi jak np. minus zero, wprowadzenie zera lub ciągu zer, jako pierwszych, doprowadzenie do przepełnienia rejestrów wprowadzania, czego konsekwencją byłoby wyrzucenie najstarszej cyfry oraz wielu innych niewłaściwości, których w sumie jest szesnaście.
Klawiatura kalkulatora. Moduł ten ma zadanie wykrywać interakcje ze światem zewnętrznym i wstępnie przygotować zakodowany sygnał załączonego klawisza do dalszej obróbki. Robocza klawiatura jest multipleksowana, podzielona jest na dwie grupy (grupa A zawiera 15 klawiszy, grupa B składa się z 16 klawiszy). Niezależnym klawiszem jest nadrzędny klawisz AC, który resetuje całe urządzenie. Również do tego modułu należy przycisk LT, który testuje wszystko, co świeci pod filtrem z pleksi. Poczwórny mikroprzełącznik, który ustawia częstotliwość zegara w trybie standardowym (wybór szesnastu prędkości zegara od 310 Hz do 1,25 MHz). Przełączniki, które ustawiają urządzenie w tryb diagnostyczny automatyczny (kolejne cztery przełączniki umożliwiają w tym trybie wybór szesnastu prędkości zegara od 0,002 Hz do 155 Hz), lub krokowy ręczny – w tym trybie aktywny jest klawisz CLK dzięki któremu możemy podawać pojedyncze sygnały zegarowe bezpośrednio do sekwencera.
Sterownik klawiatury kalkulatora. Moduł ten wytwarza wszystkie sygnały sterujące multipleksowaną klawiaturą kalkulatora. Obwody w nim zawarte zapobiegają błędom w przypadku naciśnięcia więcej niż jednego przycisku, gdy wciśniemy jakikolwiek przycisk pozostałe automatycznie są dezaktywowane. Sygnałem wyjściowym tego modułu jest impuls aktywujący pięciobitowy adres załączonego przycisku.
Selektor aktywacji funkcji, procedur i programów obliczeniowych. Podstawową funkcją tego modułu jest zdekodowanie pięciobitowego adresu załączonego przycisku oraz sterownie matrycą diod LED, obrazującą wykonywane działanie matematyczne.
Matryca diod LED wyświetlająca znaki działań arytmetycznych i znak równości. Moduł ten ma za zadanie graficzne wyświetlanie symboli działań takich jak: dodawanie, odejmowanie, mnożenie, dzielenie, pierwiastkowanie, potęgowanie kwadratowe, dzielenie przez odwrotność, symbol procentów przy dodawaniu, odejmowaniu, mnożeniu i dzieleniu. Matryca ma organizację – 10 na 10, lecz efektywnie użytych jest w niej 88 diod (pozostałe 12 nie jest potrzebne ze względu na to, iż nie biorą one udziału w projekcji znaku). Znak równości to dwa wiersze diod LED po 10 sztuk.
Starter funkcji, procedur i programów obliczeniowych. Najważniejszym zadaniem tego modułu jest kompleksowe sterowanie pamięcią ROM. Również w tym module następuje załadowanie adresu początkowego wybranego algorytmu do odpowiedniego obszaru w pamięci stałej, w której razem zaimplementowanych jest piętnaście algorytmów.
Generator sygnału zegarowego wraz z preselektorem impulsów sekwencyjnych. Moduł ten jest sercem urządzenia, dzięki generatorowi kwarcowemu i dzielnikowi częstotliwości wytwarza impulsy zegarowe o odpowiednich częstotliwościach, związanych z uruchomionym trybem pracy kalkulatora. Podzespół ten wytwarza dwanaście sygnałów sekwencyjnych, które są przetwarzane w kolejnym module.
Selektor impulsów sterujących cyklem programowym (sekwencer). Jest to bardzo ważna jednostka zarządzająca pracą całego urządzenia. Jest to dość skomplikowany moduł, który obsługuje cztery procedury sterujące:
PROCEDURA STARTOWA – Procedura ta uruchamiana jest na początku każdego przetwarzanego algorytmu w urządzeniu. Jej zadanie polega na załadowaniu adresu początkowego wybranego algorytmu do licznika pamięci ROM, przełączeniu multipleksera obsługującego ładowane dane dla licznika pamięci ROM w tryb pobierania danych z ośmiobitowego rejestru, podwójnej inkrementacji licznika BDP (aktywne tylko w przypadku działania na procentach i uruchomionej procedurze programu obliczeniowego), aktywacji wariantu A (wykonywanie algorytmów), resetowaniu sekwencera. Procedura startowa uruchamiana jest tylko raz w całym przetwarzaniu wybranego algorytmu.
PROCEDURA STANDARDOWA – Procedura ta zawsze jest uruchamiana po procedurze startowej. Jej zadanie polega na wpisaniu danych LSB z pamięci ROM do ośmiobitowego rejestru, wykonaniu bieżącej linijki programu, inkrementacji licznika pamięci ROM (przejście do następnej linijki programu), resetowaniu sekwencera. Procedura standardowa wykonywana jest wiele razy podczas przetwarzania wybranego algorytmu.
PROCEDURA SKOKU – Procedura skoku może wystąpić praktycznie w każdym miejscu wykonywanego algorytmu jeden bądź wiele razy. Jej zadanie polega na wpisaniu danych LSB z pamięci ROM do ośmiobitowego rejestru (w tym przypadku jest to ośmiobitowy adres pamięci ROM), wykonaniu bieżącej linijki programu (w tym przypadku jest to instrukcja skoku, co w konsekwencji uruchamia wariant E), wpisaniu danych z ośmiobitowego rejestru do licznika pamięci ROM (skok do zaadresowanej komórki pamięci ROM), resetowaniu sekwencera. Po wykonaniu wszystkich kroków w tej procedurze następuje automatyczne przełączenie na procedurę standardową.
PROCEDURA PĘTLI INSTRUKCJI PROGRAMU – Procedura pętli instrukcji programu może wystąpić praktycznie w każdym miejscu wykonywanego algorytmu jeden bądź wiele razy. Jej zadanie polega na wpisaniu danych LSB z pamięci ROM do ośmiobitowego rejestru, wykonaniu bieżącej linijki programu (w tym przypadku może to być aktywacja pętli CU, która uruchomi wariant C lub aktywacja pętli CARYT, która uruchomi wariant C i D), inkrementacji licznika pamięci ROM (przejście do następnej linijki programu, instrukcja w niej zawarta będzie powtarzana do momentu osiągnięcia zera przez licznik CU lub CARYT), aktywacji wariantu B (wykonywanie aktywnej pętli), resetowaniu sekwencera, wykonaniu bieżącej linijki programu objętej aktywną pętlą, tak długo aż stan liczników CU lub CARYT zmniejszanych w kolejnym kroku nie osiągnie zero, zresetowaniu wariantów B, C, ewentualnie D wraz z przejściem do następnej linijki programu, kolejnym zresetowaniu sekwencera. Po wykonaniu wszystkich kroków w tej procedurze następuje automatyczne przełączenie na procedurę standardową.
Sterownik znaków liczb w rejestrach. Moduł ma za zadanie zarządzać znakami „minus” w czterech rejestrach urządzenia.
Sterownik punktów dziesiętnych liczb w rejestrach. Moduł ten kompleksowo steruje położeniem punktów dziesiętnych we wszystkich czterech rejestrach urządzenia. Liczniki binarne punktów dziesiętnych ADP i BDP mogą zliczać w górę i w dół, ładować dane równoległe krzyżowo pomiędzy sobą lub z liczników punktów MDP lub WDP albo z zaprogramowanych wartości. Licznik MDP obsługuje równolegle ładowanie danych z licznika ADP lub BDP. Natomiast licznik WDP może zliczać w górę i w dół oraz ładować dane równolegle z arytmometru albo z zaprogramowanych wartości. Wszystkie liczniki mogą być niezależnie resetowane.
Zespół liczników specjalnych. Moduł ma za zadanie obsługiwać algorytmy, które potrzebują wykonać jakąś instrukcję n razy. Podzespół ten składa się z trzech skonsolidowanych liczników BCD: sześciobitowego licznika CU, którego maksymalny stan to 25; dwunastobitowego licznika CARYT, którego maksymalny stan to 120 oraz z sześciobitowego licznika CSQRT, którego maksymalny stan to 22. Również w tym module znajdują się trzy czterobitowe liczniki BCD: CAA, CAB i CAW.
Sterownik ustawiania trybów pracy skonsolidowanych rejestrów. Moduł ma za zadanie ustawiać odpowiednie poziomy logiczne na wejściach trybu pracy wszystkich skonsolidowanych czterech rejestrów urządzenia: A, B, M i W. Istnieją cztery możliwości przygotowania skonsolidowanych rejestrów do pracy: blokada, przesuw danych w lewo lub w prawo oraz ładowanie danych równolegle. W moim urządzeniu istnieje dwadzieścia kombinacji przygotowania składowych skonsolidowanych rejestrów do pracy.
Multipleksery obsługujące dane dla przesuwu w lewo w skonsolidowanych rejestrach. Moduł ma za zadanie dostarczać odpowiednie dane do wejść szeregowych SL skonsolidowanych trzech rejestrów urządzenia: A, B i W. W tym przypadku istnieje 13 kombinacji dostarczania danych do składowych skonsolidowanych rejestrów.
Multipleksery obsługujące dane dla przesuwu w prawo w skonsolidowanych rejestrach. Moduł ma za zadanie dostarczać odpowiednie dane do wejść szeregowych SR skonsolidowanych czterech rejestrów urządzenia: A, B, M i W. W tym przypadku istnieje również 13 kombinacji dostarczania danych do składowych skonsolidowanych rejestrów.
Należy nadmienić, że kolejna, dwudziesta siódma kombinacja dostarcza do składowych skonsolidowanych rejestrów dane do wejść szeregowych SL i SR. Natomiast ostatnie dwie kombinacje: 28 i 29 służą do ładowań równoległych, więc stany na wejściach szeregowych nie mają znaczenia.
Skonsolidowany rejestr M. Moduł ma za zadanie dekodować położenie punktu dziesiętnego MDP na wyświetlaczach; zapamiętywać wprowadzane dane MBR odpowiedzialne za aktywacje wyświetlaczy; zapamiętywać wprowadzane dane M odpowiedzialne za wartości dziesiętne pierwszych dwunastu cyfr (LSB); prezentować na kolejnych dwunastu wyświetlaczach (MSB) wartości specjalne odczytywane ze strategicznych modułów kalkulatora w trybie krokowym ręcznym lub automatycznym; kontrolować na bieżąco czy wartość wprowadzonej liczby M jest różna od zera dla przedziału pierwszych dwunastu cyfr LSB.
Skonsolidowany rejestr A. Moduł ma za zadanie na bieżąco dekodować położenie punktu dziesiętnego ADP na wyświetlaczach lub ewentualnie zamrozić jego lokalizację; zapamiętywać wprowadzane dane ABR odpowiedzialne za aktywację wyświetlaczy; zapamiętywać wprowadzane dane A odpowiedzialne za wartości dziesiętne cyfr lub ewentualnie zamrozić wyświetlaną wartość; odczytywać stan znaku „minus” AZ i ewentualnie zamrozić jego status na wyświetlaczu; przełączać pomiędzy trybem 12- a 24-cyfrowym; kontrolować na bieżąco czy wartość wprowadzonej liczby A jest różna od zera dla przedziału pierwszych dwunastu cyfr LSB.
Skonsolidowany rejestr B. Moduł ma za zadanie na bieżąco dekodować położenie punktu dziesiętnego BDP na wyświetlaczach lub ewentualnie zamrozić jego lokalizację; zapamiętywać wprowadzane dane BBR odpowiedzialne za aktywację wyświetlaczy; zapamiętywać wprowadzane dane B odpowiedzialne za wartości dziesiętne cyfr lub ewentualnie zamrozić wyświetlaną wartość; odczytywać stan znaku „minus” BZ i ewentualnie zamrozić jego status na wyświetlaczu; przełączać pomiędzy trybem 12- a 24-cyfrowym; kontrolować na bieżąco czy wartość wprowadzonej liczby B jest różna od zera dla przedziału pierwszych dwunastu cyfr LSB.
Skonsolidowany rejestr W. Moduł ma za zadanie na bieżąco dekodować położenie punktu dziesiętnego WDP na wyświetlaczach; zapamiętywać wprowadzane dane WBR odpowiedzialne za aktywację wyświetlaczy; zapamiętywać wprowadzane dane W, odpowiedzialne za wartości dziesiętne cyfr.
Należy dodać, że wszystkie wyjścia równoległe skaskadowanych składowych rejestrów liczb i aktywacji wyświetlaczy oraz wyjścia dekoderów 1 z 12 lub 1 z 24 podłączone są do wejść 12- lub 24-bitowych multiplekserów, na których wyjściach powstają szeregowe informacje podawane w danej chwili na odpowiedni wyświetlacz (dla punktu dziesiętnego i aktywacji wyświetlaczy jest to po jednym wyjściu, natomiast dla danych BCD są to cztery wyjścia).
96-bitowy komparator. Moduł ten ma za zadanie porównywać na bieżąco wartość bezwzględną wprowadzonych liczb rejestrów A i B. Moduł ten przyspiesza algorytmy, które badają relację między wartościami rejestrów, np. kontynuuj odejmowanie A–B dopóty A≥B, gdyby nie komparatory trzeba by było badać czy powstało przepełnienie na ostatniej cyfrze MSB – gdyby było, świadczyłoby to o tym, że A<B. Więc trzeba by było przywrócić poprzedni stan rejestrów poprzez operację A+B.
Selektor funkcji warunkowych. Moduł ma za zadanie zezwalać na wykonanie bieżącej przygotowanej instrukcji w przetwarzanym algorytmie pod warunkiem spełnienia aktywnej jednej z czterdziestu funkcji warunkowych, (gdy instrukcja nie jest warunkowana – „sygnał” instrukcji przechodzi transparentnie). Moduł również na bieżąco monitoruje stan dwóch warunków: CU=0? oraz CARYT=0? w ewentualnej uaktywnionej którejś procedurze pętli instrukcji programu w sekwencerze.
Dekoder funkcji wykonawczych. Gdy z selektora funkcji warunkowych sygnał zezwalania dotrze do wejścia strobującego dekodera 1 z 64 – nastąpi wykonanie instrukcji, która przez dodatkową logikę wyjściową może zawierać od jednej do kilkunastu funkcji. Moduł ten dekoduje 59 instrukcji.
Podsumowując działanie dwóch ostatnich modułów należy stwierdzić, że w pierwszej fazie cyklu dane z pamięci ROM ustawiają i przygotowują niezbędne obwody urządzenia oraz przygotowują bieżącą instrukcję przetwarzanego algorytmu do wykonania. Odnosząc się do analogii z bronią palną: w powyższym etapie broń zostaje załadowana i przygotowana jest do strzału. Natomiast w drugiej fazie cyklu następuje próba wykonania bieżącej instrukcji w przetwarzanym algorytmie. Gdy instrukcja nie podlega warunkowaniu lub warunek, który ją obejmuje zostaje spełniony wtedy następuje wykonanie bieżącej instrukcji. W przeciwnym wypadku warunek obejmujący instrukcję nie zostaje spełniony, w związku z czym bieżąca instrukcja nie zostaje wykonana. Na tym etapie – odnosząc się do broni palnej – następuje wystrzał pocisku z wycelowanej broni do odpowiedniego miejsca na tarczy składającej się z 59 pól (dekoder instrukcji). O tym, do którego miejsca na tarczy zostaje wycelowana broń decyduje instruktor, czyli pamięć ROM 🙂 Selektor funkcji warunkowych zadecydował jaki nabój zostanie załadowany – w przypadku ostrej amunicji pozostaje ślad na tarczy (instrukcja została wykonana), w przypadku ślepego pocisku tarcza zostaje nienaruszona (brak wykonania instrukcji).
4-bitowy arytmometr BCD, 5-bitowy arytmometr BIN. Moduł ma za zadanie wykonywać dwie podstawowe operacje arytmetyczne: dodawanie (ADD) oraz odejmowanie (SUB). Arytmometr BCD operuje na wartościach dziesiętnych cyfr z rejestrów: A, B, W. Natomiast arytmometr BIN operuje na wartościach dwójkowych z liczników punktów dziesiętnych: ADP, BDP, WDP. Arytmometr BCD realizuje następujące funkcje: A+B=W, A–B=W, B–A=W, A+B=A, A–B=A, B+W=W. Z kolei arytmometr BIN: ADP+BDP=WDP, ADP–BDP=WDP, 0–WDP=WDP. W tym przypadku dzieje się to w zamkniętym zapętlonym zbiorze 24-elementowym (wartości od 0 do 23).
3840-bitowa pamięć ROM. Moduł jest pamięcią stałą, zbudowaną z elementów dyskretnych, pojedynczy bit w stanie wysokim reprezentuje dioda przełączająca, diod tych jest około 1100 szt. Pamięć ma ośmiobitowe adresowanie oraz szesnastobitowe wyjścia danych. Jej organizacja to 240 na 16 bitów, gdzie pierwsze osiem bitów, licząc od LSB, ustawia multipleksery punktów dziesiętnych, multipleksery skonsolidowanych rejestrów, tryb pracy skonsolidowanych rejestrów, multipleksery arytmometru, w komórkach tych mogą się też znajdować 6-bitowe adresy funkcji warunkowych, 8-bitowe adresy skoków oraz dane w postaci BCD dla liczników specjalnych. Reasumując, dane te są argumentami wejściowymi dla funkcji instrukcji wykonawczych. Kolejny obszar jest 6-bitowym kodem instrukcji wykonawczej, ostatni 2-bitowy obszar kończąc na bicie MSB służy do warunkowania instrukcji wykonawczych. W pamięci tej znajduje się piętnaście algorytmów:
– DIG (wpisywanie cyfr od 0 do 9 lub ciągu 00 do aktywnego rejestru),
– MS (kopiowanie aktywnego rejestru do rejestru M),
– MR (kopiowanie rejestru M do aktywnego rejestru),
– WRC (przeniesienie zawartości rejestru W do aktywnego rejestru),
– AB (zamiana krzyżowa zawartości rejestrów A i B),
– BK (cofanie ostatniej wprowadzonej cyfry w aktywnym rejestrze),
– PI (załadowanie liczby PI do aktywnego rejestru),
– ADD/SUB (dodawanie lub odejmowanie arytmetyczne rejestrów A i B),
– MUL (mnożenie arytmetyczne rejestrów A i B),
– DIV (dzielenie arytmetyczne rejestrów A i B),
– SQRT (pierwiastkowanie kwadratowe aktywnego rejestru),
– X2 (podnoszenie do kwadratu aktywnego rejestru),
– 1/X (dzielenie przez odwrotność aktywnego rejestru),
– +%-% ( przeniesienie zawartości rejestru W zawierającego wynik działania: [(B/100)×A] do rejestru B),
– ACW (pozycjonowanie ku prawej stronie wyniku w rejestrze W poprzez pozbywanie się niepotrzebnych zer z lewej i prawej strony).
Stworzony język maszynowy, który koduje wszystkie instrukcje jest mojego autorstwa.
Transkoder DEC/HEX dla rejestru M. Moduł ma za zadanie przekształcać wartość powyżej 9DEC na znaki heksadecymalne, tj. A, B, C, D, E, F. W normalnym trybie na wejścia podawane są sygnały do 9DEC, więc konwersja nie występuje, jednak w trybie diagnostycznym niektóre sygnały wejściowe przyjmują wartość do 15DEC. W związku z tym, że sygnały powyżej 9DEC przyjmują wartość dwucyfrową konieczne jest ich przekształcenie na wartość HEX. Dzięki takiemu rozwiązaniu czterobitowa wartość zawsze znajdzie się tylko na jednym wyświetlaczu.
Dekodery i obwody sterujące zespołem 105 wyświetlaczy LED. Moduł ma zadanie całkowite dekodowanie sygnałów ze skonsolidowanych rejestrów: A,B,W oraz częściowo ze skonsolidowanego rejestru M na kod wyświetlania cyfr lub znaków na wyświetlaczach siedmiosegmentowych. Moduł podzielony jest na pięć podstawowych zbiorów zbudowanych z wyświetlaczy LED: zbiór podstawowy rejestru M zawiera 13 wyświetlaczy, natomiast zbiór specjalny zawiera ich 17, zbiory rejestrów: A, B i W zawierają po 25 sztuk. Wszystkie wyświetlacze są multipleksowane.
Sterownik multipleksowania wyświetlaczy. Moduł ma za zadanie wytworzyć odpowiednie impulsy sterujące, które z odpowiednią częstotliwością sekwencyjnie załączają kolumny wyświetlaczy siedmiosegmentowych LED. Moduł ten też zawiera obwód, który usuwa całkowicie efekt poświaty tzw. duszków, dzięki odpowiednio dobranym czasom wyświetlania bieżącej i ładowanej kolejnej cyfry. Znajdują się tu również obwody wyłączania wyświetlaczy w przypadku ewentualnej awarii generatora, co jest bardzo ważne ze względu na specyficzne sterowanie elementami mocy.
Zespół diod LED wyświetlających sygnały kontrolne w trybie diagnostycznym. Moduł ma za zadanie wyświetlanie sygnałów kontrolnych, które obrazują poprawną pracę urządzenia.
Całe urządzenie napędzane jest zasilaczem liniowym, dającym jedno napięcie +5 V (fotografia 8).
Zasilacz ten oparty jest na kostce LM723 i to jest jeden z dwóch analogowych układów scalonych zastosowanych w tym projekcie. Użyty transformator jest transformatorem toroidalnym o napięciu znamionowym 9 V, jego wydajność prądowa to 18 A. Napięcie zbijane jest do odpowiedniej wartości na czterech równolegle połączonych tranzystorach mocy BDP 491, przedstawionych na fotografii 9.
Urządzenie pobiera do 12 A prądu (pobierany prąd jest cały czas wskazywany na wbudowanym wskazówkowym amperomierzu), w pierwszych testach zauważyłem, że po ponad dwugodzinnej ciągłej pracy transformator bardzo się przegrzewa, więc musiałem dodać aktywne chłodzenie w postaci wentylatora z zasilacza ATX i problem minął całkowicie. Od strony sieciowej urządzenie zabezpieczone jest dwoma warystorami i oczywiście bezpiecznikiem topikowym. Natomiast od strony wtórnej zabezpieczeń jest kilka. Zabezpieczenie nadprądowe opiera się na obwodach w kostce LM723 i ogranicza z grubsza prąd do 18 A. Zabezpieczenia nadnapięciowe oparte są na bardzo szybkich dwukierunkowych transilach – jest ich razem sześć sztuk i są rozmieszczone w różnych miejscach urządzenia. Dodatkowym elementem, który przy okazji niweluje bardzo krótkie przepięcia jest filtr EMI serii BNX.
Podsumowanie, nieuniknione błędy oraz wyciągnięte wnioski
Planowałem, że projekt ten ukończę w ciągu roku, jednak czas ten wydłużył się prawie sześciokrotnie – nauczyłem się wtedy determinacji i bezwzględnego „trwania przy swoim”. Pierwsza wersja urządzenia miała być tylko czterodziałaniowym kalkulatorem, bez możliwości podglądania algorytmów. Jednak od tego pomysłu odwiódł mnie mój serdeczny przyjaciel Pan Piekarski z Warszawy, który nadał temu urządzeniu prym bardziej dydaktyczny. Muszę przyznać, że uwielbiam duże projekty, robione na podstawowych „cegiełkach” elektroniki – dzięki temu wiem jak to wszystko dokładnie działa, widząc każdy obwód z osobna. Tak jak wspomniałem, mam straszny sentyment do elektroniki retro i dlatego cały ten projekt zrobiony jest w tym stylu. Każdy zastosowany tu element nie jest zbyt nowoczesny, użyłem dużo polskich układów i tranzystorów jeszcze z CEMI, duże kondensatory elektrolityczne są z Elwy, przez te wszystkie lata szukałem stylowych elementów i kiedy nadarzała się okazja kupowałem je na różnych aukcjach i w sklepach internetowych. Pierwsza wersja projektu miała powstać na sześciu płytkach dwustronnych o łącznej powierzchni ponad 1,5 m2 – nawet zaprojektowałem te płytki… Jednak zdałem sobie sprawę, że wiele strategicznych połączeń okazało się zbyt długimi, a na elementy kondycjonujące sygnały nie było już fizycznie miejsca. Musiałem zmienić koncepcję i postanowiłem jeszcze raz zaprojektować PCB, ale tym razem jedną ośmiowarstwową o wymiarach 720 mm na 500 mm i grubości 2 mm – fotografia 10.
Tę płytkę i również te poprzednie projektowałem ręcznie, bez użycia auto routera. Topologia tej płytki jest następująca: warstwa zasilania, sześć warstw sygnałowych (im bardziej wymagający sygnał tym niższa warstwa) i wylewka masy na samym dole – rysunek 11.
W związku z tym, że płytka ta była bardzo droga z racji zamówienia jednej sztuki musiałem wyeliminować jak najwięcej możliwych błędów. Poświęciłem ogromną ilość czasu na bardzo dogłębne przeanalizowanie każdego zaprojektowanego modułu, obwodu i połączeń między nimi, czego skutkiem było sporządzenie bardzo dokładnej, szczegółowej dokumentacji technicznej na prawie tysiącu stronach A4. Opłacił się ten pomysł, bo dzięki temu wyeliminowałem ponad 30 błędów różnej maści. Nie korzystałem z żadnej symulacji komputerowej do sprawdzania obwodów – zasadę działania różnych bloków i modułów wyobrażałem sobie w pamięci z uwzględnieniem jak największej ilości możliwych pozornych problemów. Nie będąc do końca pewnym niektórych zastosowanych rozwiązań przenosiłem je na płytkę stykową o ile nie były zbyt skomplikowane. Po sporządzeniu dokumentacji elektronicznej przyszedł czas na skrupulatne sprawdzenie zaimplementowanych algorytmów. Tu też krok po kroku sprawdzałem każdą instrukcję, każdą funkcję, różne zależności, itd. Również w tym przypadku powstała opasła dokumentacja, dzięki której udało mi się wyeliminować kilka błędów. Dopiero po tych zabiegach i poprawieniu wszystkich błędów na płytce zdecydowałem się ją zamówić. Płytkę zamówiłem w Chinach przez polską firmę pośredniczącą z Gdańska (laminat FR4, podwójna zielona soldermaska, warstwa opisowa od strony TOP, grubość miedzi we wszystkich warstwach 35 μm). Płytkę otrzymałem po miesiącu od zamówienia i rozpoczął się ręczny montaż kilku tysięcy elementów, co potwierdza fotografia 12.
Wszystkie elementy są przewlekane, nie ma żadnego elementu SMD, to też był jeden z moich postulatów.
Pod wszystkie układy scalone są wlutowane podstawki – praktycznie każda z nich ma wbudowany kondensator odsprzęgajacy (fotografia 13).
Zdecydowana większość elementów jest na stronie TOP, natomiast około 200 sztuk znajduje się po stronie BOTTOM – głównie tranzystorów sterujących wyświetlaczami, co przedstawia fotografia 14.
Montaż zajął mi prawie trzy miesiące i, powiem szczerze, przy takich gabarytach płytki i ilości wlutowanych elementów płytka stawała się coraz cięższa i trzeba było bardzo uważać, aby jej nie uszkodzić. Na etapie montażu też pojawiło się kilka problemów z elementami, które musiałem szlifować o ułamki milimetra, aby dobrze osadziły się w swoich miejscach. Z racji tego, że miałem do polutowania około 16000 punktów lutowniczych zużyłem prawie 0,5 kg cyny! Przyszedł w końcu upragniony czas na uruchamianie… Ze względu na to, że wszystkie układy miały swoje podstawki, (co okazało się być też wielkim atutem) uruchamiałem ten projekt etapami. Tu dała o sobie znać kolejna niedogodność, a mianowicie w niektórych miejscach tak zagęściłem układy scalone, że nie mogłem ich wstawić w podstawki. Okazało się, że każdy układ DIP jest trochę dłuższy w porównaniu ze swoją podstawką – pozostało szlifowanie około stu sztuk układów…
Uruchamianie szło całkiem sprawnie i coraz więcej bloków urządzenia zaczynało działać prawidłowo. Gdy udało mi się uruchomić urządzenie w całości przyszedł czas na finalne testy. Niestety kilka błędów się ujawniło, czego zresztą się spodziewałem, bo przecież nic nie jest idealne… Przy niektórych obwodach musiałem zmienić wartości rezystorów, w innych miejscach je dolutować. Musiałem również dolutować w paru newralgicznych miejscach kilka kondensatorów o pojemności pojedynczych nanofaradów, aby zdławić niepożądane szpilki. Lecz dwa błędy okazały się bardziej skomplikowane… Jeden związany był z obliczeniami procentowymi, a drugi z algorytmem pierwiastka kwadratowego. Z racji tego, że zostawiłem sobie furtki w postaci niewykorzystanych funktorów logicznych (intuicja podpowiedziała mi, żeby ich wejść nie podłączać do warstw zasilających) problemy były do opanowania.
Aby wyeliminować pierwszy błąd wykorzystałem trzy bramki NOT, dwie AND i jedną NOR i od strony druku wykonałem odpowiednie połączenia kynarem z innymi obwodami (fotografia 15).
Przy drugim błędzie było o wiele więcej zachodu, gdyż błąd dotyczył skrojonego na miarę algorytmu. Dzięki temu, że urządzenie ma tryb diagnostyczny mogłem znaleźć dokładną przyczynę. Okazało się, że porównywanie relacji między rejestrami wartości A i B nie było w tym miejscu gdzie potrzeba. Po bardzo wnikliwej, długiej analizie musiałem zastosować następujące zmiany: w pięciu instrukcjach zmodyfikować ich warunkowanie, w jednej zmienić dane BCD dla licznika CU w dwóch zmienić adresy skoków, dwie scalić w jedną. Dzięki temu scaleniu otrzymałem wolną kolumnę w pamięci ROM, do której podłączyłem dodatkową logikę, która warunkuje w odpowiednim miejscu jedną z instrukcji skoku. Konsekwencją tej przebudowy było wylutowanie 14 diod z odpowiednich kolumn pamięci ROM i wlutowanie dodatkowych 22 diod od strony druku. Musiałem też przesunąć siedem instrukcji o jedno miejsce do przodu, a jedną kolumnę podłączyć o 15 miejsc dalej. Przesunięcia te zrealizowałem dodatkową podstawką na jednym z dekoderów pamięci ROM (fizycznie ją zmodyfikowałem lutując siedem pinów dekodera o jedno miejsce dalej). Dodatkowa logika zawiera jeden przerzutnik typu D, jedną bramkę OR i AND oraz jedną diodę przełączającą. Podobnie jak poprzednio tu też od strony druku wykonałem połączenia kynarem do odpowiednich obwodów urządzenia. Operacja okazała się pełnym sukcesem, w związku z czym algorytm działa prawidłowo. Ironią losu było to, że sytuacja dotycząca błędnie liczonego pierwiastka śniła mi się kilka razy w ciągu tych lat pracy nad kalkulatorem. Chciałbym też podkreślić, że ten błąd ujawniał się tylko w niektórych pierwiastkowanych liczbach – w dokumentacji dotyczącej algorytmów przeanalizowałem bardzo dokładnie przykład na √2, a tu ten błąd nie występował… Przyszedł w końcu czas na osadzenie płyty PCB wraz z układami zasilającymi na jakimś stojanie. Zaprojektowałem stojan z płyty meblowej, wykonawstwo wraz z wywierceniem około setki otworów powierzyłem znajomemu stolarzowi. Już na bardzo wczesnym etapie zaplanowałem na PCB ponad sześćdziesiąt otworów M2 i M3, dzięki którym po zastosowaniu metalowych gwintowanych tulejek dystansowych przykręciłem ją do frontowej płyty stojana. Po przeciwnej stronie czołowej płyty stojana przykręciłem plastykową transparentną obudowę z obwodami sieciowymi zawierającymi m.in. transformator toroidalny wraz z mostkiem Graetza na diodach Schottky w stylowych metalowych obudowach DO4, potężny radiator z tranzystorami mocy oraz obsadziłem dwa wielkie kondensatory po 10000 μF każdy. Tu też, aż wstyd się przyznać, w pierwszej wersji zasilacza zamówiłem transformator na specjalne zamówienie o napięciu nominalnym 5,5 V (tak, żeby wytracać jak najmniej mocy na tranzystorach) i wszystkimi możliwymi sposobami nie mogłem uzyskać stabilizacji na wyjściu, zabrakło dosłownie 1,5 V, które sumarycznie gubiłem na każdym przewodzie i elementach półprzewodnikowych – trochę zgubiła mnie myśl, że przecież na tak prostym obwodzie nie da się pomylić…
Kalkulator ten składa się z: 477 układów scalonych i z takiej samej ilości podstawek, 370 rezystorów, 7 drabinek rezystorowych, 165 kondensatorów, 1678 diod przełączających, 4 diod prostowniczych, 6 transili, 400 diod LED, 105 wyświetlaczy 1” LED, 270 tranzystorów, 33 podświetlanych przycisków, 7 przełączników i kilkunastu innych elementów (fotografia 16, fotografia 17). Zastosowanych elementów mechanicznych, takich jak śruby, dystanse, podkładki, nakrętki jest około 250 sztuk.
Zdaje sobie sprawę, że jest to projekt karkołomny i mało kto w dzisiejszych czasach podejmuje się w pojedynkę takich zadań i to w dodatku typowo hobbystycznie. Jednak elektronika jest moją życiową pasją od niepamiętnych czasów i cały czas mnie inspiruje.
Tym projektem chciałbym udowodnić, że nawet nie mając żadnego wykształcenia elektronicznego i pracując w zupełnie innej branży, można osiągać swoje zamiary przez samodoskonalenie i zdobywanie niezbędnej wiedzy. I przede wszystkim trzeba ciężką, systematyczną pracą dążyć uparcie do postawionego sobie celu. Spróbowałem policzyć ile godzin zajął mi ten projekt – wyszło prawie 6000, z czego połowa to żmudna nauka na własnych błędach i ciągłe zmienianie koncepcji. Tu muszę podziękować za nieskończoną cierpliwość swojej żonie Monice…
Moim marzeniem jest w dalszym ciągu zarażanie entuzjazmem i dzielenie się zdobytą wiedzą teoretyczną oraz praktyczną na bazie tego urządzenia z różnymi osobami, czującymi w dziedzinie elektroniki takie samo pozytywne zakręcenie jak ja.
Niedawno miałem przyjemność zaprezentowania tego projektu we Wrocławiu, na konferencji „Hardware Design Masterclasses”, którą organizował Rafał Stępień, gdzie byłem jednym z prelegentów:
https://doktortronik.pl/hardware-design-masterclasses-2024-podsumowanie/.
Uzupełnieniem tego artykułu jest film, w którego drugiej części Autor obszernie wyjaśnia okoliczności powstania oraz działanie swojego kalkulatora.
Rafał Wiśniewski
rafi8112@interia.pl