Smart Debugging, Navigieren leicht gemacht.
Schreiben Sie Ihren HDL-Code (Hardware Descriptive Language) immer richtig und simulieren Sie ihn, bevor Sie ihn auf die Hardware übertragen? Ich tue das. Sicherlich. Nun, meistens habe ich das getan. Zugegeben, manchmal habe ich es nicht so genau genommen und mußte daher im Nachhinein überprüfen, warum die Dinge auf der Platine nicht funktionierten….
Was macht man in so einer Situation? Wahrscheinlich überlegt man sich, wo etwas schief gelaufen sein könnte, und dann baut man einen internen Logikanalysator ein oder fügt einige Sonden hinzu. Entweder man implementiert also neu, fügt einige Sonden in das implementierte Design ein und erstellt dann einen Bitstrom neu. In all diesen Fällen verbringt man also einige Zeit damit, auf die Fertigstellung der Tools zu warten. Und in manchen Fällen kann es sogar passieren, daß der Fehler nicht mehr auftritt. Das ist dann die schlimmste Situation: Murphy’s Law.
Wäre es nicht schön, wenn man sich die Neuimplementierung und die manuelle Suche komplett sparen könnte? Ja, das wäre es sicherlich. Meine Kollegen Divipala Rajesh und Apurva Peri haben kürzlich ein Video erstellt, in dem sie zeigen, wie man genau das macht: Debuggen, ohne das Design zu verändern und ohne auf die Tools warten zu müssen.
Für diejenigen, die die schriftliche Form der eines Videos vorziehen, hat Martin Kellermann in diesem LinkedIn-Artikel ein Beispiel für SmartDebug auf einem kostengünstigen Entwicklungs-Board gezeigt:
Zu schön, um wahr zu sein? Nicht wirklich, das ist die Funktion namens SmartDebug im Libero SoC. Mit diesem Tool können Sie sich über JTAG mit Ihrem Microchip FPGA verbinden und alle Flipflops und alle Block-RAMs in Ihrem Design asynchron auslesen. Und das alles, ohne vorher irgendetwas zusätzliches getan zu haben!
Ich habe das mit einem sehr einfachen Design ausprobiert, die “Hello World” der FPGAs, ein paar blinkende LEDs. Ein bißchen mehr, ein LSRAM BlockRAM ist auch Teil des Designs, um das auch zu versuchen.
Ich habe einen 24-Bit-Zähler, bei dem die MSBs zwei LEDs umschalten und die unteren Bits die Adress- und Datenleitungen eines LSRAMs steuern. Der FCCC ist ein Clock Conditioning Circuit, eine PLL.
Die UND-Gatter sind eine alte, einfache und schmutzige Methode, um das LSRAM als Teil des Designs zu erhalten und es nicht heraus zu optimieren. Dieses Design habe ich für ein sehr einfaches, aber dennoch vielseitiges Board vorgesehen, das M2S010-MKR-KIT, auf dem ein SoC der SmartFusion®2 Serie mit der Bauteilnummer: M2S010-FGG484I bestückt ist.
Nach einem kurzen Implementierungslauf hatte ich den Bitstream, der über die On-Board USB zu JTAG Verbindung auf das FPGA übertragen wird. Danach starten Sie einfach das SmartDebug Feature aus der Libero GUI:
Damit erhalten Sie eine GUI, in der Sie entweder auf Logik aus Ihrem Design oder aus den RAMs wählen können:
Wenn das gewünschte RAM ausgewählt ist, können Sie dessen Inhalt asynchron auslesen und bekommen die entsprechenden Speicherwerte angezeigt:
Was ist hier los? Sind das die Daten, die hier erwartet werden?
Die ersten 32 Einträge sind 0 und danach sind die Einträge “irgendwas”. Schauen wir uns noch einmal an, womit der Speicher verbunden ist:
Die unteren fünf Adressbits sind mit dem Zähler verbunden und die 8 Datenbits sind mit 0 verbunden. Die ersten 32 Einträge werden also kontinuierlich mit 0 geschrieben. Das ist korrekt. Was ist mit den anderen RAM-Speicherplätzen? Nun, die Igloo2-LSRAMs werden beim Reset nicht initialisiert, daher sind zufällige Startwerte vorhanden. Aus dieser Perspektive ist das Verhalten also korrekt.
Nachdem die Datenleitungen auf einen 8-Bit-Zähler umgestellt wurden, wird die Übung wiederholt und das LSRAM erneut ausgelesen:
Das erste Auslesen funktioniert einwandfrei, die ersten 32 Einträge werden mit inkrementellen Werten gefüllt:
Ein erneutes Auslesen nach kurzer Zeit führt zu diesem Ergebnis:
Das Auslesen zeigt die Auswirkungen des asynchronen Lesens, die ersten sieben Adressen wurden aktualisiert, die folgenden 25 Adressen stammen aus dem vorherigen Schreibzyklus. Was auch hier möglich ist, ist die manuelle Eingabe von Daten in das LSRAM über dieses GUI, wie bei Adresse 0 geschehen:
In diesem Fall wird der Wert zwar überschrieben, aber in Fällen, in denen ein falscher ROM-Inhalt ein falsches Verhalten verursacht, ist dies eine einfache Möglichkeit, etwas zu beheben.
Prüfen der Logik
Ähnlich wie beim Auslesen von RAMs kann der gleiche Ansatz auf Flipflops angewendet werden:
Alle Daten werden hier ohne jegliche Vorbereitung des Designs gesammelt, nur basierend auf den Projektinformationen aus Libero und dem Auslesen der FPGA-Array-Daten über JTAG.
Mehrere Lesevorgänge zeigen hier, daß das CNT_net inkrementiert, allerdings sind die sichtbaren Schritte weit über die einzelnen Inkremente hinaus, wie es bei einem langsamen asynchronen Lesen über JTAG zu erwarten ist. Dieses Auslesen ist also ein guter Weg, um einige allgemeine Informationen über das Design-Verhalten oder über langsame Signale zu erhalten. Das untere Signal im Screenshot zeigt den Wert einer Entprellungskette von 4hF, also ordentlich auf ‘1’ am Eingang gezogen.
Auch hier kann bei den Flipflops der Ausgangswert über JTAG verändert werden.
Echtzeit-Verhalten
Bei asynchronen Lesevorgängen ist man wie oben gezeigt eingeschränkt. Mit dem LiveProbe-Feature kann man jedoch auch zwei beliebige Flipflop-Ausgänge aus dem Design auf zwei dedizierte FPGA-Pins routen, ohne Probes implementieren oder den Bitstream neu erstellen zu müssen. So kann man mit der Originalgeschwindigkeit des Signals sehen, was passiert.
Zur Anzeige dieser Signale benötigen Sie ein Oszilloskop:
Schlußfolgerung
Die SmartDebug-Funktion in Libero SoC ist ein wirklich leistungsfähiges Mittel, um ein erstes Debugging an einem Design durchzuführen, bevor man einen virtuellen Logikanalysator einsetzt, und kann viel Zeit im Labor sparen, da man nicht auf die Erstellung von Bitströmen warten muß. Aus meiner Sicht ist diese Funktion so leistungsfähig, daß jeder Benutzer von Microchip-FPGAs sie kennen sollte.
Und ja, Entwürfe müssen immer noch richtig simuliert werden, bevor sie korrekt in Hardware umgesetzt werden können.