Spróbuję dać ci wyobrażenie o tym, w jaki sposób obwody cyfrowe są zaprojektowane do rozwiązywania problemów z przetwarzaniem cyfrowym, wykorzystując postawione problemy: w jaki sposób procesory implementują dodawanie i mnożenie.
Po pierwsze, usuńmy bezpośrednie pytanie: w jaki sposób język programowania skutecznie ocenia mnożenia i uzupełnienia. Odpowiedź jest prosta: zestawiają je w mnożenie i dodają instrukcje. Na przykład następujący kod:
a = 1 + 1;
b = a * 20;
jest po prostu skompilowany do czegoś takiego jak:
ADD 1 1 a
MUL a 20 b
(zauważ, że powyższy zestaw jest dla wyimaginowanego procesora, który nie istnieje, dla uproszczenia).
W tym momencie zdajesz sobie sprawę, że powyższa odpowiedź po prostu przesuwa problem i rozwiązuje go za pomocą magii sprzętowej. Kolejne pytanie brzmi oczywiście, jak działa ta magia sprzętowa?
Najpierw spójrzmy na prostszy problem: dodanie.
Najpierw wykonujemy znany problem, dodając w regularnej bazie 10 liczb:
17
+28
Pierwszym krokiem byłoby dodanie 7 i 8. Ale daje to 15, która jest więcej niż jedną cyfrą. Nosimy więc 1:
(1)
17
+28
= 5
Teraz dodajemy 1, 1 i 2 razem:
17
+28
=45
Z tego otrzymujemy następujące zasady:
gdy wynikiem dodawania jest więcej niż jedna cyfra, zachowujemy najmniej znaczącą cyfrę i przenosimy najbardziej znaczącą cyfrę do przodu
jeśli mamy cyfrę przeniesioną do naszej kolumny, dodajemy ją wraz z liczbami, które dodajemy
Teraz nadszedł czas, aby zinterpretować powyższe reguły w bazie 2 - algebra boolowska.
Tak więc w algebrze boolowskiej, dodanie 0 i 1 razem = 1. Dodanie 0 i 0 = 0. I dodanie 1 i 1 = 10, co jest więcej niż jedną cyfrą, więc przenosimy 1 do przodu.
Z tego możemy zbudować tabelę prawdy:
a b | sum carry
-------------------
0 0 | 0 0
0 1 | 1 0
1 0 | 1 0
1 1 | 0 1
Na tej podstawie możemy zbudować dwa obwody / równania boolowskie - jeden dla wyniku sumy, a drugi dla wyniku przeniesienia. Najbardziej naiwnym sposobem jest po prostu wypisanie wszystkich danych wejściowych. Dowolna tabela prawdy, bez względu na to, jak duże i złożone można przekształcić w tej formie:
(AND inputs in first row) OR (AND of inputs in second row) OR ...
Jest to w zasadzie suma postaci produktów. Patrzymy tylko na wyniki, które dają 1 i ignorujemy 0:
sum = (NOT a AND b) OR (a AND NOT b)
Zastąpmy AND AND i NOT symbolami języka programowania, aby ułatwić czytanie:
sum = (!a & b) | (a & !b)
Zasadniczo przekonwertowaliśmy tabelę tak:
a b | sum equation
-------------------
0 0 | 0
0 1 | 1 (!a & b)
1 0 | 1 (a & !b)
1 1 | 0
Można to bezpośrednio zaimplementować jako obwód:
_____
a ------------| |
\ | AND |-. ____
\ ,-NOT--|_____| \ | |
\/ `--| OR |----- sum
/\ _____ ,--|____|
/ `-NOT--| | /
/ | AND |-`
b ------------|_____|
Obserwatorzy czytający w tym miejscu zauważą, że powyższą logikę można faktycznie zaimplementować jako pojedynczą bramę - bramę XOR, która dogodnie ma zachowanie wymagane przez naszą tabelę prawdy:
_____
a ------------| |
| XOR |---- sum
b ------------|_____|
Ale jeśli twój sprzęt nie zapewnia ci bramki XOR, powyższe kroki opisują, jak możesz ją zdefiniować i wdrożyć w zakresie bramek AND, OR i NOT.
Sposób przejścia na bramkę logiczną na rzeczywisty sprzęt zależy od posiadanego sprzętu. Można je zaimplementować przy użyciu różnych mechanizmów fizycznych, o ile mechanizm zapewnia pewien rodzaj przełączania. Wdrożono bramki logiczne ze wszystkim, od strumieni wody lub zaciągów powietrza (płynów), tranzystorów (elektronika) po spadające kulki. To duży temat sam w sobie, więc po prostu go pomaluję i powiem, że możliwe jest zaimplementowanie bramek logicznych jako urządzeń fizycznych.
Teraz robimy to samo dla sygnału przenoszenia. Ponieważ jest tylko jeden warunek, w którym sygnał przenoszenia jest prawdziwy, równanie jest po prostu:
carry = a & b
Noszenie jest proste:
_____
a ------------| |
| AND |---- carry
b ------------|_____|
Łącząc je razem otrzymujemy tak zwany pół sumator:
_____
a ------;-----| |
| | XOR |---- sum
b --;---|-----|_____|
| | _____
| '-----| |
| | AND |---- carry
'---------|_____|
Nawiasem mówiąc, równania dla powyższego obwodu wyglądają następująco:
sum = a ^ b
carry = a & b
W połowie sumatora czegoś brakuje. Wdrożyliśmy pierwszą zasadę - jeśli wynik jest więcej niż jedna cyfra niż przeniesienie, ale nie wdrożyliśmy drugiej reguły - jeśli istnieje przeniesienie, dodaj ją wraz z liczbami.
Aby więc wdrożyć pełny sumator, obwód sumowania, który może dodawać liczby, które są więcej niż jedną cyfrą, musimy zdefiniować tabelę prawdy:
a b c | sum carry
---------------------
0 0 0 | 0 0
0 0 1 | 1 0
0 1 0 | 1 0
0 1 1 | 0 1
1 0 0 | 1 0
1 0 1 | 0 1
1 1 0 | 0 1
1 1 1 | 1 1
Równanie sumy jest teraz:
sum = (!a & !b & c) | (!a & b & !c) | (a & !b & !c) | (a & b & c)
Możemy przejść przez ten sam proces, aby wyliczyć i uprościć równanie i zinterpretować je jako obwód itp., Jak to zrobiliśmy powyżej, ale myślę, że ta odpowiedź jest zbyt długa.
Do tej pory powinieneś dowiedzieć się, jak zaprojektowana jest logika cyfrowa. Są inne sztuczki, o których nie wspomniałem, takie jak mapy Karnaugh (używane w celu uproszczenia tabel prawdy) i kompilatory logiczne, takie jak espresso (abyś nie musiał ręcznie uwzględniać równań boolowskich), ale podstawową zasadą jest to, co mam przedstawione powyżej:
Rozłóż problem, aż będziesz mógł pracować na poziomie jednego bitu (cyfry).
Zdefiniuj pożądane wyniki za pomocą tabeli prawdy.
Przekształć tabelę w równanie boolowskie i uprość równanie.
Interpretuj równanie jako bramki logiczne.
Przekształć obwód logiczny w rzeczywiste obwody sprzętowe, wdrażając bramki logiczne.
W ten sposób naprawdę rozwiązuje się podstawowe (a raczej niskopoziomowe) problemy - mnóstwo tabel prawdy. Prawdziwa twórcza praca polega na rozkładaniu złożonego zadania, takiego jak dekodowanie MP3 do poziomu bitowego, aby można było pracować nad nim przy użyciu tabel prawdy.
Niestety nie mam czasu na wyjaśnienie, jak zaimplementować mnożenie. Możesz spróbować złamać go, ustalając zasady działania mnożenia, a następnie interpretując go w formacie binarnym, a następnie próbując rozbić go na tabele prawdy. Lub możesz przeczytać Wikipedię: http://en.wikipedia.org/wiki/Binary_multiplier