MSP430: Pipeline Architektur

Nach außen ist der MSP430 der MSP430. Allerdings hat sich am CPU Kern auch einiges getan und nicht alles wird offensiv kommuniziert. TI dokumentiert etwa im Code Composer Studio User’s Guide for MSP430 (Revision SLAU157Y, stand Mai 2013) im Kapitel „Using the Integrated Debugger, Breakpoint Types“ drei unterschiedliche Architekturen, MSP430, MSP430X und MSP430Xv2, allerdings bleiben bis auf die Erweiterung des Adressbusses auf 20 bit bei den X-Architekturen weitere Details verborgen.

Ein weiterer erheblicher Unterschied zwischen MSP430 und MSP430X ist die neu eingeführte three stage pipeline architecture. Dabei werden Taktzyklen in denen der Bus ungenutzt bliebe, etwa während die CPU einen Befehl verarbeitet, genutzt um den nächsten Befehl schon zu holen (siehe auch Wikipedia Artikel zur Pipeline Architektur).

Mit folgendem Programm lassen sich Auswirkungen dieser Architekturänderung demonstrieren:
[c]#include

void main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

P1OUT &= ~BIT0; // Reset P1.0
P1DIR |= BIT0; // P1.0 Output

P1OUT |= BIT0; // P1.0 high
__delay_cycles(1000); // 1 ms @ 1 MHz, DCO default
P1OUT &= ~BIT0; // P1.0 low

while(1); //
}[/c]

Lässt man das Programm zum Beispiel auf einem MSP430F5529 oder MSP430F5438A (MSP430Xv2) laufen und misst die Zeit welche der Port 1.0 ein high Signal liefert beträgt diese Zeit 1 ms, also 1000 Zyklen. Die Funktion __delay_cycles() fügt 1000 NOP Befehle ein, der DCO läuft in der Grundeinstellung mit 1 MHz.
Wird an der while(1) Schleife allerdings ein Breakpoint gesetzt ändert sich die delay Zeit von 1 ms auf rund 4 ms (zumindest beim MSP430F552x und beim MSP430F543xA). Diesen Effekt kann man bei MSP430 Derivaten welche nicht die MSP430X oder Xv2 Architektur haben nicht feststellen. Hier bleibt die delay Zeit immer 1 ms, egal ob an der while(1) Schleifen ein Breakpoint gesetzt wird oder nicht (etwa beim MSP430G2452 bzw. allen MSP430G2xxx Derivaten).

Wird der Breakpoint gesetzt passiert folgendes:
Der aktuelle Befehl 1 (P1OUT &= ~BIT0;) wird gerade ausgeführt, der Befehl 2 (hier ist der Breakpoint gesetzt) wird in die Pipeline geladen. Die EEM „sieht“ beim Befehl 2 einen Breakpoint und hält die CPU an welche allerdings noch an Befehl 1 arbeitet. Die EEM schaut auf den Bus, weiß allerdings nicht was die CPU gerade wirklich tut. Nun ist Befehl 1 halb ausgeführt, die CPU allerdings angehalten. In diesem Zustand (Befehl 1 noch nicht fertig ausgeführt) findet dann einiges an JTAG Kommunikation statt und die Pipeline wird geleert. Wenn die Pipeline leer ist wird Befehl 1 noch fertig ausgeführt. So kommt es zu den 4 ms delay bis der Port wieder getoggelt wird.
Die ursprüngliche MSP430 Architektur ohne Pipeline holt den nächsten Befehl (die while(1) Schleife mit dem Breakpoint) erst wenn der alte Befehl vollständig abgearbeitet wurde (der Port wieder auf low ist).

Sollte der Effekt beim debuggen stören kann er durch einfügen von zwei NOP Befehlen (also zwei __no_operation(); vor der while(1) Schleife) beseitigt werden. Dann werden die zwei NOPs in die Pipeline geladen und befinden sich in der Ausführung, wenn die while(1) Schleife mit dem Breakpoint geladen wird. Das Port toggeln ist dann schon fertig abgearbeitet und das delay dauert genau 1 ms. Zwei NOP Befehle, da die Pipleline drei Stages (Stufen) hat. Es können also zusätzlich zum aktuellen Befehl immer schon bis zu zwei folgende Befehle geladen werden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert