Warum brauchen Mikrocontroller eine Uhr?

Warum müssen Anweisungen in festgelegten Zeitintervallen (dh unter Verwendung einer Uhr) verarbeitet werden? Können sie nicht nacheinander ausgeführt werden - unmittelbar nachdem die vorherige Anweisung abgeschlossen ist?

Besonders hilfreich wäre eine Analogie zur Notwendigkeit von Uhren in Mikrocontrollern.

Es gibt asynchrone Prozessoren.
Wie würden Sie feststellen, "wenn die vorherige Anweisung abgeschlossen ist"? Wenn Sie darüber nachdenken, müssten Sie wissen, wann die Frage "Ist die vorherige Anweisung abgeschlossen?" Berechnung abgeschlossen wurde, und wenn die Berechnung „Ist die Berechnung „Hat die vorherige Anweisung abgeschlossen?
Logikgatter sagen nicht, wann sie fertig sind. Das Signal ist einfach für einige Zeit unbestimmt, bevor es sich auf einen stabilen Wert einpendelt. Im Wesentlichen ermöglicht die Uhr dem Design zu wissen, wann sich die Logik auf einen korrekten Wert eingestellt hat. Fortgeschrittene Strategien wie Mikrobefehle helfen, indem sie Maschinenbefehle in kleinere Teile zerlegen, sodass ein ADD 4 Takte dauern kann, während der Speicherzugriff Hunderte von Ticks dauern kann.

Antworten (8)

Ein oder zwei anschauliche Beispiele können hier helfen. Betrachten Sie die folgende hypothetische Schaltung:

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Angenommen, zu Beginn sind sowohl A als auch B hoch (1). Der Ausgang des AND ist daher 1, und da beide Eingänge des XOR 1 sind, ist der Ausgang 0.

Logikelemente ändern ihren Zustand nicht sofort - es gibt eine kleine, aber signifikante Ausbreitungsverzögerung, wenn die Änderung des Eingangs verarbeitet wird. Angenommen, B geht auf Low (0). Das XOR sieht den neuen Zustand sofort an seinem zweiten Eingang, aber der erste Eingang sieht immer noch die "veraltete" 1 vom UND-Gatter. Infolgedessen geht der Ausgang kurz hoch - aber nur, bis sich das Signal durch das UND-Gatter ausbreitet, wodurch beide Eingänge des XOR niedrig werden und der Ausgang wieder niedrig wird.

Die Störung ist kein gewünschter Teil des Betriebs der Schaltung, aber solche Störungen treten immer dann auf, wenn sich die Ausbreitungsgeschwindigkeit durch verschiedene Teile der Schaltung aufgrund der Menge an Logik oder sogar nur der Länge der Drähte unterscheidet .

Eine wirklich einfache Möglichkeit, damit umzugehen, besteht darin, ein flankengetriggertes Flipflop wie folgt auf den Ausgang Ihrer kombinatorischen Logik zu setzen:

schematisch

Simulieren Sie diese Schaltung

Jetzt werden alle auftretenden Störungen durch das Flipflop vor dem Rest der Schaltung verborgen, das seinen Zustand nur aktualisiert, wenn die Uhr von 0 auf 1 wechselt. Solange das Intervall zwischen steigenden Taktflanken lang genug ist, damit sich Signale ausbreiten können Weg durch die kombinatorischen Logikketten sind die Ergebnisse zuverlässig deterministisch und störungsfrei.

Vielen Dank, dass Sie die Ausbreitungsverzögerung fast sofort erwähnt haben, das sind wahrscheinlich 99% der Antwort.
Ein Arbeitsbeispiel dafür in Aktion kann auf den digitalen I/O-Peripheriegeräten von Mikrocontrollern von Microchip (und anderen) beobachtet werden. Wenn Sie die PORT-Register verwenden, um Ausgänge (anstelle des LATCH) mit aufeinanderfolgenden Read-Modify-Write-Befehlen zu aktualisieren, ist es möglich, den Zustand des Pins zu lesen, während er seinen Zustand ändert. Siehe Abschnitt 10.2.2 der dsPIC33E/24E- Dokumentation für weitere Details.
Verstehe ich es richtig, dass sequentielle Schaltungen dringend getaktet werden müssen, nicht nur weil sie Störungen bekommen, sondern auch weil aufgrund dieser Störung ein Flip-Flop möglicherweise den falschen Wert speichert?

Ich habe das Gefühl, dass viele dieser Antworten nicht genau die Kernfrage treffen. Der Mikrocontroller hat eine Uhr, einfach weil er sequentielle Logik ausführt (und von ihr gesteuert wird) .

In der Theorie digitaler Schaltungen ist sequentielle Logik eine Art Logikschaltung, deren Ausgabe nicht nur vom aktuellen Wert ihrer Eingangssignale abhängt, sondern auch von der Folge vergangener Eingaben, der Eingabehistorie. Dies steht im Gegensatz zur kombinatorischen Logik, deren Ausgabe nur eine Funktion der aktuellen Eingabe ist. Das heißt, die sequentielle Logik hat einen Zustand (Speicher), während die kombinatorische Logik dies nicht tut. Oder mit anderen Worten, sequentielle Logik ist kombinatorische Logik mit Gedächtnis.

Sowie:

Der Hauptvorteil der synchronen Logik ist ihre Einfachheit. Die Logikgatter, die die Operationen an den Daten durchführen, benötigen eine begrenzte Zeit, um auf Änderungen an ihren Eingängen zu reagieren. Dies wird als Ausbreitungsverzögerung bezeichnet. Das Intervall zwischen den Taktimpulsen muss lang genug sein, damit alle Logikgatter Zeit haben, auf die Änderungen zu reagieren, und ihre Ausgänge auf stabile Logikwerte "einschwingen", bevor der nächste Taktimpuls auftritt. Solange diese Bedingung erfüllt ist (abgesehen von bestimmten anderen Details), ist die Schaltung garantiert stabil und zuverlässig. Dies bestimmt die maximale Betriebsgeschwindigkeit einer Synchronschaltung.

Kurze Antwort: Manager wollen einen einfachen, testbaren Funktionsnachweis, bevor sie Millionen (oder mehr) Dollar für ein Design ausgeben. Aktuelle Tools geben asynchronen Designs diese Antworten einfach nicht.

Mikrocomputer und Mikrocontroller verwenden typischerweise ein Taktschema, um eine Zeitsteuerung sicherzustellen. Alle Prozessecken müssen das Timing über alle Spannungs-, Temperatur-, Prozess- usw. Auswirkungen auf die Signalausbreitungsgeschwindigkeit hinweg aufrechterhalten. Es gibt keine aktuellen Logikgatter, die sich sofort ändern: Jedes Gatter schaltet abhängig von der zugeführten Spannung, der Ansteuerung, der es antreibt, und der Größe der Geräte, die zu seiner Herstellung verwendet werden (und natürlich des Prozessknotens). (Gerätegröße), in dem es hergestellt wird, und wie schnell DIESER Prozess tatsächlich ausgeführt wird --- DIESER Durchgang durch die Fabrik). Um zum „sofortigen“ Schalten zu gelangen, müssten Sie Quantenlogik verwenden, und das setzt voraus, dass Quantengeräte sofort schalten können; (Ich bin nicht sicher).

Die getaktete Logik beweist, dass das Timing über den gesamten Prozessor hinweg über die erwartete Spannung, Temperatur und Verarbeitungsvariablen hinweg funktioniert. Es gibt viele Software-Tools, die dabei helfen, dieses Timing zu messen, und der Netzprozess wird "Timing Closure" genannt. Das Takten kann (und tut es meiner Erfahrung nach) irgendwo zwischen 1/3 und 1/2 der in einem Mikroprozessor verwendeten Leistung liegen.

Warum also nicht asynchrones Design? Es gibt, wenn überhaupt, nur wenige Timing-Closure-Tools, die diesen Designstil unterstützen. Es gibt, wenn überhaupt, nur wenige automatisierte Place-and-Routing-Tools, die mit einem großen asynchronen Design umgehen und es verwalten können. Nicht zuletzt genehmigen Manager NICHTS, was keinen unkomplizierten, computergenerierten Funktionsnachweis hat.

Der Kommentar, dass asynchrones Design „eine Menge“ Synchronisierungssignale erfordert, die „viel mehr Transistoren“ erforderten, ignoriert die Kosten für das Routing und die Synchronisierung einer globalen Uhr und die Kosten aller Flip-Flops, die das Taktsystem benötigt. Asynchrone Designs sind (oder sollten es sein) kleiner und schneller als ihre getakteten Gegenstücke. (Man nimmt einfach den EINEN langsamsten Signalpfad und verwendet diesen, um ein "Bereit"-Signal an die vorhergehende Logik zurückzukoppeln).

Asynchrone Logik ist schneller, weil sie nie auf eine Uhr warten muss, die woanders um einen weiteren Block verlängert werden müsste. Dies gilt insbesondere für Register-zu-Logik-zu-Register-Funktionen. Asynchrone Logik hat keine mehrfachen „Einrichten“- und „Halten“-Probleme, da nur die Endsenkenstrukturen (Register) diese Probleme haben, im Gegensatz zu einem Pipeline-Satz von Logik mit eingestreuten Flip-Flops, um die logischen Ausbreitungsverzögerungen zum Takten zu verteilen Grenzen.

Kann es getan werden? Sicherlich sogar auf einem Milliarden-Transistor-Design. Ist es schwieriger? Ja, aber nur, weil der NACHWEIS, dass es auf einem ganzen Chip (oder sogar einem System) funktioniert, viel aufwendiger ist. Das Timing auf Papier zu bekommen, ist für jeden Block oder jedes Subsystem ziemlich direkt. Es ist viel schwieriger, dieses Timing in einem automatisierten Place-and-Route-System zu kontrollieren, da die Tools NICHT dafür ausgelegt sind, den viel größeren potenziellen Satz von Timing-Einschränkungen zu bewältigen.

Mikrocontroller haben auch eine potenziell große Menge anderer Blöcke, die mit (relativ) langsamen externen Signalen verbunden sind, was zu der ganzen Komplexität eines Mikroprozessors beiträgt. Das macht das Timing etwas komplizierter, aber nicht viel.

Das Erzielen eines "Zuerst-Ankommen"-"Sperr"-Signalmechanismus ist ein Schaltungsentwurfsproblem, und es gibt bekannte Wege, damit umzugehen. Rennbedingungen sind ein Zeichen für 1). schlechte Designpraxis; oder 2). Externe Signale kommen in den Prozessor. Das Takten führt tatsächlich eine Signal-gegen-Takt-Race-Bedingung ein, die sich auf "Set-up"- und "Hold"-Verletzungen bezieht.

Ich persönlich verstehe nicht, wie ein asynchrones Design in eine blockierte oder andere Race-Bedingung geraten kann. Das könnte durchaus meine Einschränkung sein, aber wenn es nicht beim Eingeben von Daten in den Prozessor passiert, sollte es in einem gut entworfenen Logiksystem NIEMALS möglich sein, und selbst dann, da es passieren kann , wenn die Signale eingehen, entwerfen Sie, damit umzugehen.

(Ich hoffe das hilft).

Alles in allem, wenn Sie das Geld haben ...

Natürlich hängt es von dem Chip ab, den Sie bauen – zum Beispiel neigt neuronale Netzwerkhardware dazu, asynchron zu sein, weil das eigentlich das Einfachste ist – das, was sie emulieren, ist asynchron . Wir bauen meistens synchrone sequentielle Hardware, weil die Software/Firmware auch meistens synchron und sequentiell ist (insbesondere im "sequentiellen" Teil - asynchroner Code wird immer häufiger verwendet). Tatsächlich ist es viel einfacher, sich mit einem sequentiellen, synchronen System vertraut zu machen, insbesondere wenn die meisten Programmierungen in Sprachen erfolgen, die sequentiellen Code fördern.
Ereignisse in der realen Welt finden zu unvorhersehbaren Zeiten statt. Wenn ein Gerät eine Taste hat und einen Codepfad ausführen soll, wenn es "früh genug" gedrückt wird, und einen anderen Codepfad ausführen soll, wenn dies nicht der Fall ist, dann, wenn keine quantenmechanischen Einschränkungen vorliegen, zwischen einem Moment, in dem die Taste gedrückt wird wo ein Tastendruck früh genug erfolgen würde, um den alternativen Codepfad auszulösen, und ein Moment, in dem ein Tastendruck "zu spät" wäre, es einen genauen Moment geben würde, in dem ein Tastendruck ein Verhalten "zwischen" den beiden verursachen würde (z was dazu führt, dass einige Bits des Programmzählers geändert werden ...
... aber nicht andere). Ohne quantenmechanische Einschränkungen könnte die Zeit zwischen dem letzten Moment, in dem der Schub die Verzweigung verursachen würde, und dem ersten Moment, in dem ein Schub dies eindeutig verfehlen würde, beliebig klein gemacht, aber nicht auf Null reduziert werden. Quantenmechanische Grenzen können es wahrscheinlich machen, dass jeder Knopfdruck entweder früher genug erfolgt, um registriert zu werden, oder spät genug, um sauber zu versagen, aber der Beweis, dass es niemals einen Quantenzustand geben wird, der einen Knopfdruck in der tödlichen Zwischenzeit erlauben würde, wäre im Allgemeinen undurchführbar.
Die Verwendung von synchroner Logik vereinfacht die Analyse von Situationen, in denen das System auf ein wirklich asynchrones Ereignis reagieren muss, erheblich, indem sichergestellt wird, dass Wettlaufbedingungen eine sehr geringe Wahrscheinlichkeit haben, einem sehr kleinen Teil des gesamten Geräts zu entgehen. Das Analysieren dieses kleinen Teils des Geräts, um sicherzustellen, dass es unwahrscheinlich ist, dass Rennbedingungen entkommen, ist ein viel leichter zu handhabendes Problem, als zuzulassen, dass Rennbedingungen fast überall auftreten, und zu versuchen, ihre Auswirkungen zu analysieren, um zu beweisen, dass sie mit annehmbarer Wahrscheinlichkeit keine Probleme verursachen.

Mikrocontroller müssen eine Uhr verwenden, weil sie in der Lage sein müssen, auf Ereignisse zu reagieren, die jederzeit auftreten können, einschließlich nahezu gleichzeitig mit anderen externen Ereignissen oder Ereignissen, die von den Controllern selbst erzeugt werden, und haben oft mehrere Schaltkreise, die wissen müssen, ob dies der Fall ist ein Ereignis X geht einem anderen Ereignis Y voraus. Es spielt keine Rolle, ob alle diese Schaltkreise entscheiden, dass X Y vorausgegangen ist, oder alle diese Schaltkreise entscheiden, dass X Y nicht vorausgegangen ist, aber es wird oft entscheidend sein, dass, wenn einer der Schaltkreise entscheidet, dass X vorausgegangen ist Y, dann müssen alle dies tun. Leider ist es schwierig sicherzustellen, dass Schaltungen innerhalb einer begrenzten Zeit einen garantierten Konsens darüber erreichen, ob X vor Y steht, oder sogar einen Konsens darüber erzielen, ob sie einen Konsens erreicht haben oder nicht. Synchrone Logik kann dabei enorm helfen.

Durch das Hinzufügen einer Uhr zu einer Schaltung kann garantiert werden, dass ein Subsystem keine Wettlaufbedingungen erfährt, es sei denn, eine Eingabe in das System ändert sich in einem sehr kleinen Fenster relativ zur Uhr, und es kann auch garantiert werden, ob die Ausgabe eines Geräts in ein anderes eingespeist wird , ändert sich die Ausgabe des ersten Geräts im kritischen Fenster des zweiten Geräts nicht, es sei denn, die Eingabe an das erste Gerät ändert sich innerhalb eines noch kleineren kritischen Fensters. Das Hinzufügen eines anderen Geräts vor diesem ersten Gerät stellt sicher, dass sich die Eingabe für das erste Gerät in diesem kleinen Fenster nicht ändert, es sei denn, die Eingabe für das neue Gerät ändert sich innerhalb eines wirklich winzigen Fensters. Aus praktischer Sicht, es sei denn, man versucht absichtlich, ein Konsensversagen zu verursachen,

Es ist sicherlich möglich, vollständig asynchrone Systeme zu entwerfen, die "so schnell wie möglich" laufen, aber wenn ein System nicht extrem einfach ist, wird es schwer zu vermeiden sein, dass ein Design durch eine Race-Bedingung ins Stolpern gerät. Während es Möglichkeiten gibt, Rennbedingungen zu lösen, ohne Uhren zu benötigen, können Rennbedingungen oft viel schneller und einfacher gelöst werden, indem Uhren verwendet werden, als dies ohne sie der Fall wäre. Obwohl die asynchrone Logik Race-Conditions oft schneller als die getaktete Logik lösen kann, stellen die Fälle, in denen dies nicht möglich ist, ein großes Problem dar, insbesondere angesichts der Schwierigkeit, dass Teile eines Systems einen Konsens darüber erzielen, ob sie einen Konsens erzielt haben oder nicht. Ein System, das durchgehend eine Million Anweisungen pro Abschnitt ausführen kann, ist im Allgemeinen nützlicher als eines, das manchmal vier Millionen Anweisungen pro Sekunde ausführen kann, aber möglicherweise aufgrund von Rennbedingungen für Millisekunden (oder länger) am Stück stehen bleiben könnte.

Dabei ist zu beachten, dass es sich bei den zu entscheidenden Zuständen auch um interne handeln kann – etwa das Ergebnis einer arithmetischen Operation. Verzögerungen aufgrund der Leitungslänge können dazu führen, dass ein Teil der MCU das Ergebnis sieht – und, ohne Uhr, darauf reagiert – vor anderen Teilen.
@NickJohnson: Wenn die Reihenfolge, in der Operationen ausgeführt werden, niemals von Dingen abhängt, die noch nicht berechnet wurden, können diese Probleme problemlos gelöst werden, wenn jeder Abschnitt wie eine ALU "gültige" Eingaben und eine "gültige" Ausgabe und Dinge hat können so angeordnet werden, dass sie in deterministischer Reihenfolge geschehen. Wo die Räder abfallen, ist, wenn die Reihenfolge, in der Operationen auftreten, vom Timing abhängen sollte (z. B. wenn man eine Reihe paralleler Operationen hat, die einen gemeinsam genutzten Speicherbus verwenden müssen und zwei von ihnen nahezu gleichzeitige Anforderungen ausgeben, von denen eine entschieden wird sollte erstmal gehen...
... und worauf man warten sollte, kann hartnäckig sein. Wenn man vorher entscheidet, welches zuerst gehen soll, können solche Probleme vermieden werden, aber wenn sich herausstellt, dass das Gerät, das zuerst gehen soll, erst lange nach dem anderen bereit ist, kann die Leistung stark darunter leiden .
Deshalb ist es so schwierig, ins All zu gehen, die Wahrscheinlichkeiten ändern sich ungünstig.

MCUs sind nur ein sehr komplexes Beispiel einer synchronen sequentiellen Logikschaltung. Die einfachste Form ist wohl das getaktete D-Flip-Flop (D-FF), also ein synchrones 1-Bit-Speicherelement.

Es gibt Speicherelemente, die asynchron sind, zum Beispiel das D-Latch, das (in gewisser Weise) das asynchrone Äquivalent des D-FF ist. Eine MCU ist nichts weiter als ein Haufen Millionen solcher grundlegender Speicherelemente (D-FF), die mit Tonnen von Logikgattern zusammengeklebt sind (ich vereinfache es zu stark).

Kommen wir nun zum Punkt: Warum verwenden MCUs intern D-FFs anstelle von D-Latches als Speicherelemente? Es dient im Wesentlichen der Zuverlässigkeit und dem einfachen Design: D-Latches reagieren, sobald sich ihre Eingänge ändern, und ihre Ausgänge werden so schnell wie möglich aktualisiert. Dies ermöglicht unangenehme unerwünschte Wechselwirkungen zwischen verschiedenen Teilen einer Logikschaltung (unbeabsichtigte Rückkopplungsschleifen und Rennen). Das Entwerfen einer komplexen sequentiellen Schaltung unter Verwendung asynchroner Bausteine ​​ist von Natur aus schwieriger und fehleranfälliger. Synchronschaltungen vermeiden solche Fallen, indem sie den Betrieb der Bausteine ​​auf die Zeitpunkte beschränken, zu denen die Taktflanken erkannt werden. Wenn die Flanke ankommt, erfasst eine synchrone Logikschaltung die Daten an ihren Eingängen, aktualisiert ihre Ausgänge jedoch noch nicht. Sobald die Eingänge erfasst sind, werden die Ausgänge aktualisiert. Dadurch wird die Gefahr vermieden, dass ein Ausgangssignal auf einen nicht vollständig erfassten Eingang zurückgeführt wird und (einfach gesagt) alles durcheinander bringt.

Diese Strategie des "Entkoppelns" der Eingabedatenerfassung von der Ausgabeaktualisierung ermöglicht einfachere Entwurfstechniken, was sich in komplexeren Systemen für einen gegebenen Entwurfsaufwand niederschlägt.

Was Sie beschreiben, wird als asynchrone Logik bezeichnet . Es kann funktionieren, und wenn es funktioniert, ist es oft schneller und verbraucht weniger Strom als synchrone (getaktete) Logik. Leider hat die asynchrone Logik einige Probleme, die ihre breite Verwendung verhindern. Ich sehe vor allem, dass für die Implementierung viel mehr Transistoren erforderlich sind, da Sie eine Menge unabhängiger Synchronisationssignale benötigen. (Mikrocontroller erledigen viel Arbeit parallel, ebenso wie CPUs.) Das wird die Kosten in die Höhe treiben. Der Mangel an guten Design-Tools ist ein großes Hindernis im Vorfeld.

Mikrocontroller werden wahrscheinlich immer Uhren benötigen, da ihre Peripherie normalerweise die Zeit messen muss. Timer und PWMs arbeiten in festen Zeitintervallen, ADC-Abtastraten wirken sich auf ihre Bandbreite aus, und asynchrone Kommunikationsprotokolle wie CAN und USB benötigen Referenzuhren zur Taktwiederherstellung. Normalerweise möchten wir, dass CPUs so schnell wie möglich laufen, aber das ist bei anderen digitalen Systemen nicht immer der Fall.

Eigentlich sehen Sie die MCU als eine komplette Einheit, aber die Wahrheit ist, dass sie selbst aus verschiedenen Gattern und TTL- und RTL-Logiken besteht, oft FF-Arrays, die alle das Taktsignal einzeln benötigen.

Um genauer zu sein, denken Sie daran, einfach auf eine Adresse zuzugreifen aus dem Speicher, kann diese einfache Aufgabe selbst mehrere Operationen beinhalten, wie das Bereitstellen des BUS für die Datenleitungen und die Adressleitungen.
Der beste Weg zu sagen ist, dass die Anweisungen selbst in kleinen Betriebseinheiten auftreten, die Taktzyklen erfordern, diese kombiniert für Maschinenzyklen , die verschiedene MCU-Eigenschaften wie Geschwindigkeit (FLOPS ** in komplizierten MCUs), Rohrauskleidung usw. berücksichtigen.

Reaktion auf Kommentar von OP

Um ganz genau zu sein, gebe ich Ihnen ein Beispiel, es gibt einen Chip namens ALE(Address Latch Enable) Normalerweise zum Zweck des Multiplexens des unteren Adressbusses zum Übertragen von Adresse und Daten auf denselben Pins verwenden wir einen Oszillator (der Intel 8051 verwendet einen lokalen Oszillator von 11,059 MHz als Taktgeber), um die Adresse und dann die Daten abzurufen.

Wie Sie vielleicht wissen, sind die grundlegenden Teile der MCU CPU, ALU und interne Register usw., die CPU (die s/g steuert) sendet die Adresse an alle Adresspins 16 im Fall von 8051, dies geschieht zum Zeitpunkt T1 und danach die Adresse ist die entsprechende Matrix der Kondensatorspeicherung (Ladung als Signal) ( *Speicherzuordnung* ) wird aktiviert und ausgewählt.

Nach der Auswahl wird das ALE-Signal aktiviert, dh der ALE-Pin wird beim nächsten Takt, sagen wir T2, auf High gesetzt ( normalerweise ein High-Signal, aber Änderung je nach Design der Verarbeitungseinheit ), danach verhalten sich die unteren Adressbusse wie Datenleitungen, und Daten werden geschrieben oder gelesen (je nach Ausgang am RD/WR Pin-der MCU).
Sie können deutlich sehen, dass alle Ereignisse zeitlich aufeinander folgen

Was würde passieren, wenn wir keine Uhr verwenden? Dann müssen wir die asynchrone Taktmethode ASQC verwenden. Dies würde dann jedes Gatter vom anderen abhängig machen und zu Hardwarefehlern führen. Außerdem wird dadurch das Pipe-Lining von Anweisungen unmöglich, lange abhängig und unregelmäßig Zeit, um die Aufgabe abzuschließen.
Es ist also etwas Unerwünschtes

So etwas macht Sinn. Aber warum benötigen diese verschiedenen Abteilungen der MCU das Taktsignal, um zu funktionieren? Was würde theoretisch passieren, wenn sie keine Uhr verwenden würden?
@Martin, Logikgatter ändern den Zustand sofort, wenn sich ihr Eingang ändert. Getaktete, sequentielle Logik wertet ihre Eingänge nur während eines Taktereignisses aus. Dies ist das Grundprinzip, das digitale Speicherschaltungen antreibt. Es gibt uns die Möglichkeit, Daten mit absoluter Kontrolle selektiv von einem Ort zum anderen zu verschieben, was die Erstellung von Allzweckhardware ermöglicht, die über Software programmiert werden kann, um zu tun – nun, alles.
@SeanBoddy: Logikgatter verändern den Zustand nicht sofort, es gibt eine kurze Verzögerung, die auf einem Oszilloskop sichtbar ist. Wenn wir keine Uhr verwenden würden, könnten die Unterschiede in diesen Timings zwischen den Komponenten dazu führen, dass Race-Conditions zu falschen Ergebnissen führen.
@BlueRaja - na gut, gute Gummibonbons, wie wäre es damit. Vielleicht gehe ich durch 4 Jahre Leistungselektronik-Notizen und 8 Jahre Navy-Training zurück, um herauszufinden, wo ich diese eine Sache verpasst habe.

Das grundlegende Problem, das eine Uhr löst, besteht darin, dass Transistoren keine wirklich digitalen Geräte sind: Sie verwenden analoge Spannungspegel an den Eingängen, um den Ausgang zu bestimmen, und brauchen eine begrenzte Zeit, um den Zustand zu ändern. Sofern Sie nicht, wie in einer anderen Antwort erwähnt, in Quantengeräte einsteigen, gibt es einen Zeitraum, in dem die Eingabe von einem Zustand in einen anderen übergeht. Die hierfür benötigte Zeit wird durch die kapazitive Belastung beeinflusst, die von Gerät zu Gerät unterschiedlich sein wird. Dies bedeutet, dass die verschiedenen Transistoren, aus denen jedes Logikgatter besteht, zu leicht unterschiedlichen Zeiten reagieren. Der Takt wird verwendet, um die Ausgänge der Komponentengeräte zu "verriegeln", sobald sie sich alle stabilisiert haben.

Betrachten Sie als Analogie die Kommunikationstransportschicht SPI (Serial Peripheral Interface). Eine typische Implementierung davon verwendet drei Leitungen: Data In, Data Out und Clock. Um ein Byte über diese Transportschicht zu senden, setzt der Master seine Data-Out-Leitung und aktiviert die Clock-Leitung, um anzuzeigen, dass die Data-Out-Leitung einen gültigen Wert hat. Das Slave-Gerät tastet seine Daten in der Leitung nur dann ab, wenn es vom Taktsignal dazu angewiesen wird. Wenn es kein Taktsignal gäbe, wie würde der Slave wissen, wann er die Daten in der Leitung abtasten muss? Er könnte es abtasten, bevor die Leitung durch den Master gesetzt wurde oder während des Übergangs zwischen Zuständen. Asynchrone Protokolle wie CAN, RS485, RS422, RS232 usw. lösen dies durch die Verwendung einer vordefinierten Abtastzeit, einer festen Bitrate und (Overhead-)Framing-Bits.

Mit anderen Worten, es ist eine Art allgemeines Wissen erforderlich, um festzustellen, wann alle Transistoren in einem Satz von Gattern ihren Endzustand erreicht haben und die Anweisung abgeschlossen ist. In dem (100 blauen Augen) Puzzle, das im obigen Link angegeben ist und in dieser Frage zu Maths Stack Exchange ausführlich erklärt wird, fungiert das „Orakel“ als Uhr für die Menschen auf der Insel.