Warum sehen wir einen einheitlichen Speicheradressraum in ARM Cortex-M-Core-basierten MCUs, obwohl sie eine Harvard-Architektur haben?

Die meisten ARM Cortex-M-Kern-basierten MCUs haben eine Harvard-Architektur (mit Ausnahme von Cortex-M0 und M0+).

Was ich nicht verstehe, ist, warum wir nur einen Speicheradressraum sehen. Zum Beispiel sehen wir in tge STM32F4 nur einen einheitlichen Speicheradressraum:

Geben Sie hier die Bildbeschreibung ein

Wenn ARM Cortex-M-basierte MCUs (in den meisten Fällen) über eine Harvard-Architektur verfügen, warum sehen wir dann nicht zwei separate Speicheradressräume – einen für Daten und einen für Codeanweisungen – anstelle von einem?

Sind Sie sicher, dass es sich um echtes Harvard handelt und nicht um modifiziertes Harvard?
scheint modifiziertes Harvard zu sein - sie nennen es "Harvard-Bus": community.arm.com/support-forums/f/…
Ja, danke für die Klarstellung, ich war nicht genau genug, es ist modifiziertes Harvard
Na dann bitte. "Modified Harvard" bedeutet normalerweise nur eine Leistungsoptimierung auf einem einheitlichen Adressraum, zB geteilter L1d/i-Cache und/oder geteilte Busse zu RAM und Flash. (Wie en.wikipedia.org/wiki/… darauf hinweist, würden geteilte Adressräume bedeuten, dass Sie eine Anweisung zum Laden des Programmspeichers benötigen, wenn Sie als Daten darauf zugreifen möchten und somit immer noch "modifizierte Harvard" sind, was ARM hat nicht, aber AVR tut es. Ohne das wäre mit geteilten Adressräumen echtes Harvard.)
Ich denke, der Begriff „Harvard-Architektur“ ist in diesem Jahrzehnt etwas veraltet, da kaum eine Architektur so einfach ist

Antworten (3)

Wenn Sie zufällig einen STM32F4-Chip auswählen und sich das Datenblatt ansehen , sehen wir in Abschnitt 2.2 ein Blockdiagramm des Chips.

Wir sehen, dass die CPU drei (!) Busse hat, die mit I-BUS, D-BUS und S-BUS bezeichnet sind. Alle gehen zur "AHB-Bus-Matrix" und der D-BUS geht auch zu einem "CCM-Daten-RAM".

Ich habe nach "Cortex-M4 S-Bus" gesucht und diese Seite von ARM gefunden, die die Busse beschreibt , die den Unterschied zwischen den Bussen beschreibt: Für Adressen kleiner als 0x20000000 wird der D-Bus für den Datenzugriff und der I-Bus verwendet für Befehlszugriffe. Für Adressen ab 0x20000000 wird der S-Bus sowohl für Befehls- als auch für Datenzugriffe verwendet.

Der Prozessor fungiert also unterhalb von 0x20000000 als Harvard-Architektur und darüber von Neumann.

Wenn wir jedoch zurück zum Chipdatenblatt gehen, sehen wir in Abschnitt 2.2.7 (nach dem Seitenumbruch) ein Diagramm der AHB-Busmatrix, die die verschiedenen Busse mit verschiedenen Speicherkomponenten auf dem Chip verbindet. Wir sehen, dass der I-Bus und der D-Bus Zugriff auf dieselben Speicherkomponenten haben: Flash-Speicher (über ACCEL), SRAM1 und FSMC Static MemCtl. Indem wir also eine Harvard-Architektur nehmen und dann die I- und D-Busse mit demselben Speicher verbinden, verwandeln wir sie in eine sogenannte von-Neumann-Architektur. Wir können davon ausgehen, dass jeder Speicherbereich auf allen Bussen, auf die zugegriffen werden kann, dieselbe Adresse hat, da das Datenblatt sonst etwas anderes sagen würde. Es ist praktisch, dass jeder Speicher nur eine Adresse hat. Es wäre möglich, den Prozessor so anzuschließen, dass sich die Anweisung bei 0x00000000 von den Daten bei 0x00000000 unterscheidet.aber die Designer des STM32F405xx haben das nicht getan .

Es gibt einen kleinen Unterschied: Der "Data CCM"-Speicher kann nicht für Anweisungen verwendet werden, da er nur am D-Bus angeschlossen ist. Ihre Speicherkarte zeigt "data CCM" nicht unter 0x20000000 an, also schätze ich, dass dieser Unterschied auf Ihrem Chip nicht existiert. Es kann jedoch andere Unterschiede zwischen dem I-Bus und dem D-Bus geben.

Danke für deine ausführliche Antwort! Nur noch eine Sache: Wenn sich die Anweisung bei 0x00000000 von den Daten bei 0x00000000 unterscheiden würde, würde das bedeuten, dass wir im Speicherlayout zwei Speicheradressräume sehen würden, richtig?
@gvg ja, aber ich glaube nicht, dass der Chip das tut. Beachten Sie, dass der Adressraum bei 0x20000000 und höher derselbe wäre, da er denselben Bus verwendet.
Ja, ich meinte diese letzte Frage allgemein, nicht in dem speziellen Fall, den Sie zuvor beschrieben haben. Vielen Dank für die erneute Hilfe und Antworten!
Einige STM32-Modelle haben Anweisungs-CCM, das ebenfalls Zugriffsbeschränkungen hat. Aber selbst dann werden die Adressen auf dem Hauptbus nicht für andere Zwecke verwendet. Mit 4 GB Adressraum für einen Chip mit weniger als 1 MB Speicher muss nicht doppelt verwendet werden.
Ja, selbst wenn die Busse mit völlig getrennten Speicherabschnitten verbunden wären, wäre es eine gute Idee für den Chipdesigner, ihnen unterschiedliche Adressen zuzuweisen, um Programmierfehler zu erkennen.

Die ARM-Cortex-Teile werden als „Harvard-Architektur“ beworben, aber sie sind wirklich modifizierte Harvard-Architektur .

Insbesondere verwenden sie separate Daten- und Befehls-Caches, und (wenn ich mich richtig erinnere) werden einige Speicherbereiche nicht als Befehlsspeicher verwendet. Aber der gesamte Speicherplatz ist als Daten verfügbar, auch wenn zumindest ein Teil davon als Anweisungen verfügbar ist.

Die meisten Maschinen, die sich heute "Harvard-Architektur" nennen, haben keine vollständig getrennten Speicherbereiche und sind daher eine Art modifiziertes Harvard.

Und wie muss ich mir das vorstellen? Ich meine, es gibt 1 Speicher, an den separate D- und I-Busse angeschlossen sind (deshalb Harvard oder genauer gesagt modifiziertes Harvard in unserem Fall, wie Sie zuvor erklärt haben) und der Speicher kann lösen, dass er uns sowohl Daten als auch Anweisungen geben kann die selbe Zeit? Ich meine, aus irgendeinem Grund kommt es mir seltsam vor, dass es nur ein Speicher / Speicherplatz ist, aber dennoch Daten und Anweisungen gleichzeitig geben kann.
@gvg Zwei Möglichkeiten - entweder gibt es einen separaten Befehlsspeicher und einen separaten Datenspeicher, aber Sie können mit einer Geschwindigkeitsstrafe auf den falschen zugreifen (da es eine Art Crossover-Bus gibt) - oder es gibt nur einen Speichersatz, aber zwei separate Caches. Da es sich um ein eingebettetes System handelt, ist das erste nicht unwahrscheinlich.
@ user253751 ok, und dann sind wir wieder am Anfang meines Problems ... also nehmen wir die erste von Ihnen erwähnte Möglichkeit an, damit es einen separaten Befehls- und Datenspeicher gibt. Aber sollten wir in diesem Fall nicht auch zwei getrennte Speicherbereiche im Speicherlayout sehen?
@gvg nein, der Chip würde es schaffen, die Anfrage abhängig von der Adresse stattdessen an die richtige Speichereinheit weiterzuleiten, aber es würde eine Geschwindigkeitsstrafe geben, wenn der Chip Anweisungen und Daten von derselben Speichereinheit abrufen müsste, weil dies nicht möglich wäre beide im selben Taktzyklus. Wenn der Chip so funktionierte. Ich weiß nicht, ob das so funktioniert.
@gvg Der Speicher Ihres PCs besteht aus mindestens 16 und manchmal mehr als 128 einzelnen DRAMs. Der Speichercontroller handhabt das Kombinieren dieser zu einem einheitlichen Speicherbereich, da das Vorhandensein eines nicht einheitlichen Speichers aus Software-Perspektive ärgerlich ist. MCUs funktionieren normalerweise auf die gleiche Weise, wobei Tonnen von unterschiedlichem Speicher in einem einzigen Adressraum abgebildet werden.
@ user253751 ok, so tief im Inneren gibt es / könnten mehr Speichereinheiten sein, aber sie sind vor uns verborgen, und es ist gelöst, dass sie als ein einziger, einheitlicher Speicheradressraum erscheinen. Verstehe ich es richtig?
@gvg Harvard hat nicht nur einen separaten Befehlsspeicher und Datenspeicher. Das ist eine gute Vereinfachung. Aber es vermittelt nicht genau die spezifischen Details für die Abgrenzung, die die interne Architektur der CPU selbst ist. ... Was draußen passiert, ist dann eine Frage des Ausgleichs einer Vielzahl von technischen Belangen . Und hier finden Sie Variationen von Themen. Wenn TIm seine Antwort nicht erweitert und ich Zeit finde, etwas zu schreiben, kann ich etwas zur Klärung hinzufügen. Aber denken Sie daran, dass dies ein Inside-Baseball-CPU-Design ist, das nur ein paar notwendige Details definiert. +1 auf dein Q.
@ user253751: Diese Frage bezieht sich auf Cortex-M-Mikrocontroller; Die meisten von ihnen haben keinen Cache und werden normalerweise mit Anweisungen (und konstanten Daten) aus Flash verwendet. Der geteilte Bus ist also normalerweise RAM vs. Flash, nicht zwei Pfade zum selben RAM.
@PeterCordes nach meinen Recherchen (siehe meine Antwort) in dem Chip, den ich mir angesehen habe, waren es zwei separate Pfade zum selben RAM. Es gab auch eine Cache-Einheit ("Adaptive Real-Time Memory Accelerator"), die beide Busse gleichzeitig bedienen konnte.
@ user253751: Ah, ich verstehe, interessanter Punkt über eine potenzielle Harvard-MCU, die vom Board-Anbieter in einer Von-Neumann-Konfiguration verkabelt wurde. Danke.
@jonk wie ich es sehe bedeutet "von Neumann" ein Bus, "Harvard" bedeutet zwei völlig getrennte Busse und alles dazwischen ist "modifiziertes Harvard" (aus irgendeinem Grund nie "modifiziert von Neumann")
@user253751 Genau zusammengefasst die unterschiedlichen Busarchitekturen! Bitte vergessen Sie mich nicht in 10 Jahren, wenn Sie mit dem Konzept der "modifizierten von Neumann-Architektur" Ihre Milliarden verdienen ;-)
@gvg es ist das gleiche wie modifiziertes Harvard, aber mit einem anderen Namen auf der Schachtel
@ user253751 Der Begriff hat im Laufe meines Lebens viele Änderungen erfahren, von einer frühen Definition, die nicht mehr viel verwendet wird, bis hin zu neueren, bei denen es einfach um das Zwischenspeichern zwischen I und D geht. Für mich verändert es meine Herangehensweise an das CPU-Design. (Vor drei Jahrzehnten lernte ich diese Begriffe direkt von Patterson – und während einiger Tage persönlicher 1:1-Zeit mit Dr. Hennessey, als ich MIPS 1985/1986 mehrmals besuchte.) Wenn ich mir die Mühe mache, eine Art Antwort zu schreiben, Ich werde mehr schreiben. Ansonsten belasse ich es einfach, dass ich eine persönliche Perspektive habe und belasse es dabei.

Viele Programme müssen in der Lage sein, hartcodierte Konstanten in ihnen zu verwenden. Um zum Beispiel eine Operation wie „x=12345“ (in fast jeder gebräuchlichen Sprache) durchzuführen, braucht man ein Mittel, um die Zahl 12345 in ein Register zu bekommen. Es gibt mindestens vier Ansätze, mit denen dies erreicht werden kann:

  1. Einige Architekturen wie ältere Versionen des PIC verfügen über Befehle, die größer sind als der größte unmittelbare Wert, den man möglicherweise laden möchte, und ermöglichen daher das Einfügen beliebiger Werte als Teil des Befehls, ohne dass Mittel erforderlich sind, um den Coderaum als Daten zu behandeln.

  2. Einige Architekturen wie MIPS und einige neuere ARM-Varianten verfügen über Anweisungen, die die Hälfte eines Registers laden können und die zusammen mit einem folgenden "ODER sofort" verwendet werden können, um die andere Hälfte zu laden, wiederum ohne Mittel zu benötigen, um den Coderaum als Daten zu behandeln .

  3. Einige Architekturen wie ältere Versionen von ARM enthalten eine Anweisung zum Abrufen eines beliebigen Werts von einer Adresse, die sich in der Nähe des aktuell ausgeführten Codes befindet. Während der ARM über Möglichkeiten verfügt, einige Zahlen als unmittelbare Konstanten auszudrücken, wird erwartet, dass Code, der größere Werte verwenden muss, die erforderlichen Zahlen im Codebereich in der Nähe des Codes platziert hat, der sie benötigt, damit sie mit dem Wert „Laden in der Nähe“ abgerufen werden können " Anweisung. Dieser Ansatz erfordert die Fähigkeit, Code und Datenraum austauschbar zu behandeln.

  4. Es wäre für eine Architektur möglich, Konstanten zu verwenden, die in einem schreibgeschützten oder vorinitialisierten Bereich des Datenraums gespeichert sind. Dieser Ansatz würde nicht die Fähigkeit erfordern, Code- und Datenraum austauschbar zu behandeln, aber wenn er auf einen Mikrocontroller angewendet wird, könnte es erforderlich sein, eine fest verdrahtete Partition zwischen Code- und Datenspeicherung (z. B. 12 KB Code und 4 KB Daten) zu haben. Ich kenne keine aktuellen Designs, die einen solchen Ansatz verwenden, wäre aber nicht überrascht, wenn einige frühe Computer dies tun würden. Wenn ein Anweisungssatz eine Anweisung zum Laden eines Werts von einer bestimmten der ersten 1024 Stellen enthielt, könnten ein Compiler und Linker die Dinge so anordnen, dass, wenn zwei Kompilierungseinheiten beide den Wert 0x08675309 benötigen, dieser nur einmal darin gespeichert werden müsste Tisch.unterschiedliche Konstanten, würde aber erfordern, dass Konstanten, die von unterschiedlichen Funktionen verwendet werden, in jeder Funktion, in der sie verwendet werden, dupliziert werden.

Während die meisten dieser Ansätze mit nicht verwandten Code- und Datenadressräumen gut funktionieren würden, wurde der ARM-Ansatz Nr. 3 entwickelt, der die Fähigkeit erfordert, beliebige Konstanten an Adressen zu platzieren und zu laden, die sich unter den Adressen befinden, an denen Code platziert und ausgeführt wird.