Siebens Sachen

Was heißt schon alt?

TD4 4-Bit CPU


Wenn schon "Retro", dann auch richtig! "Richtig Retro" ist für mich auch ein Blick auf eine
möglichst elementare Ebene der Hardware. Schließlich wurden die frühen Systeme vom Schalter aufwärts entworfen. Einen schönen Einblick in die Konstruktion eines Computers bzw. einer CPU mit möglichst elementaren Bausteinen bietet die TD4 4-Bit CPU, die der japanische Informatiker Kaoru Tonami 2003 für Lehrzwecke entworfen hat. Man bekommt sie als Bausatz in einer einfachen Version und als Luxusausgabe mit unzähligen LEDs bei Budgetronics in Holland. Bei dieser Variante kann man dem Datenfluss recht gut folgen und so cool sieht sie aus, wenn man etwa 2000 richtig Lötpunkte gesetzt hat.

TD4

Sehr hübsch bunt - auch wenn man nicht so viel erkennen kann. Ein Blogbeitrag von Kevin Gibbs hat mir sehr geholfen, die Ideen hinter der TD4 zu verstehen. Besonders der Befehlsdekoder hatte mich interessiert, Bei so etwas wie einem Dekoder denke ich erst mal an Software. Aber irgendwann ist man natürlich an der elektronischen Basis angekommen und dann geht es nicht mehr um Software, sondern um jeden Draht und jedes Gatter. Längeres Lesen und Nachdenken habe ich schließlich im folgenden Blockschaltbild zusammengefasst.

TD4 (BLOCK)

Für’s Rechnen ist ein 4-Bit-Volladdierer (SN 74283, rechts im Diagramm) mit 2 mal 4 Eingangsbits plus Carry und 4 Ausgangsbits plus Carry zuständig. Der arbeitet asynchron, gibt also zu jedem Zeitpunkt und unabhängig vom Taktsignal die Summe von zwei 4-Bit-Zahlen als 4-Bit-Zahl aus, ggf. mit einem Übertrag. Das Ergebnis wird dann auf einen „4-Bit-Datenbus“ gestellt. Der Übertrag (Carry) wird in einem D-Flip-Flop (SN 7474) gespeichert und im Befehlsdekoder bei einem bedingten Sprung (JNC - Jump if no carry) berücksichtigt. Einen Input kann man über einen vierpoligen Schalter bereitstellen. Das Register OUT ist mit vier LEDs verbunden und bildet die einzige Ausgabe der TD4.

Der
Befehlspeicher ist ein "ROM" mit 16 Worten zu je 8 Bit und besteht aus einer Schaltermatrix. Die Zeilen der Matrix werden mit einem Vier-zu-Sechzehn-Multiplexer (SN 74154) angesteuert und die 8 gelesenen Bit werden in einem Buffer (SN 74540) zwischengespeichert. Programmieren ist Handarbeit! Von dort gelangen die niederwertigen Bits D0 bis D3 als Operand direkt an vier Dateneingänge des Addierers; die anderen werden vom Befehlsdekoder als Opcode verarbeitet. Das ist eine seltsame Designentscheidung, die Folgen hat.

Als
Register (Arbeitsspeicher) dienen vier 4-Bit-Zähler (SN 74161), bei denen zum Teil (REG A, REG B, OUT) die Zählfunktion abgeschaltet ist. Diese „Register“ arbeiten taktsynchron: Der aktuelle Wert auf dem Datenbus wird mit dem nächsten positiven Takt übernommen, wenn am Eingang PE (Parallel enable) ein logisches L angelegt wird. Wenn an SR (Reset) ein L anliegt, wird der Zähler beim nächsten positiven Taktimpuls zurückgesetzt. Ob der Zähler zählt oder nicht, entscheiden die Eingänge CET und CEP. Liegen sie auf L, wird nicht gezählt (REG A, REG B, OUT). Liegen sie auf H (PC), wird gezählt.

Für die Auswahl des zu beschreibenden Registers ist der
Befehlsdekoder zuständig und das ist der Teil der TD4, der mich am meisten interessiert hat. Wenn man im Wesentlichen in Software denkt, verlässt man sich darauf, dass die CPU schon irgendwie ihre Befehle ausführen wird. Letztlich ist aber auch eine CPU nur ein elektronisches Bauteil, das auf einen Input in Form von Nullen und Einsen eine Aktion ausführt. Intern müssen dann irgendwie Informationswege geöffnet und geschlossen werden. Das zeigt die TD4 sehr verständlich. Ich habe den Befehlsdekoder - und auch den Rest der TD4 - mit einem Simulator („digital“ von H. Neemann) nachgebaut und zeige hier, was der Befehlsdekoder aus dem Opcode 0110 macht (Das Carry lasse ich hier weg.)

Befehlsdekoder

Zum Einen werden vier Signale LOAD 0, LOAD 1, LOAD 2 und LOAD 3 generiert, die mit dem jeweiligen PE-Eingang der vier Register verbunden sind. Im Beispiel ist LOAD 1 auf L, was bedeutet, dass Register B beim nächsten Takt beschrieben werden wird. SEL A ist auf L und SEL B ist auf H. Das bedeutet, dass die beiden Multiplexer (SN 74153) den Schalterinput - auf dem Umweg über den Addierer - auf den Datenbus legen. Insgesamt wird also der Schalterinput im Register B gespeichert. Das Mnemonik für diese Aktion ist IN B.

Programme


Was kann man nun mit der TD4 machen? Ich zeige hier ein recht illustratives Programm. Es zählt immer wieder von 0 bis 15 und dann zurück nach 0. Beim Programmstart steht Register B auf 0. In einer Programmschleife wird es jedes mal um eins erhöht und sein Wert wird in Register A übertragen. Register A wird auch um eins erhöht und ist dann immer um eins größer als B. Es wird als Schleifenzähler genutzt. So wird verhindert, dass zwischen Vorwärts- und Rückwärtszählen die Ausgabe in den vier gelben LEDs am oberen Rand erscheint. Subtrahiert wird bei der Rückwärtszählung durch die Addition des Zweierkomplements von 0b0001, also 0b1111.

Zeile Mnemonic Opcode Operand Kommentar
0000 ADD B,0001 0101 0001 Beginn der Zählschleife
0001 OUT B 1001 0000 Register B wird angezeigt.
0010 MOV A,B 0001 0000 Register B wird nach A übertragen.
0011 ADD A,0001 0000 0001 Register A ist B um eins voraus.
0100 JNC 0000 1110 0000 Sprung nach 0000 -> Weiterzählen
0101 ADD B,1111 0101 1111 Subtrahiere 1 von B (Zweierkomplement)
0110 OUT B 1001 0000 Register B wird angezeigt.
0111 MOV A,B 0001 0000 Register B wird nach A übertragen.
1000 ADD A,1111 0000 1111 Wenn A Null ist, gibt es kein Carry.
1001 JNC 0000 1110 0000 Sprung zum Programmanfang
1010 JMP 0101 1111 0101 Es wird weiter rückwärts gezählt.

Und so sieht das in Aktion aus. Die helle rote LED rechts zeigt den Stand des Programmzählers und man erkennt sehr gut die beiden Programmschleifen: Die "obere" ist die Vorwärtsschleife und die "untere" die Rückwärtsschleife.