Soft-Core-Multiprozessor-Lösungen zur Implementierung in FPGAs Wenn mehrere Herzen schlagen

FPGA-basierende Embedded-Systeme, die sich mit einer Vielzahl von Soft-Core-Prozessoren ausstatten lassen, eröffnen Systementwicklern neue technische Möglichkeiten. Damit können nicht nur ASIC-Entwickler ihre System-on-Chips mit speziellen Funktionen auf optimale Leistung trimmen, sondern auch Anwender programmierbarer Logik. Die Aufteilung der Verarbeitungslast einer Applikation auf mehrere Soft-Cores bringt nicht nur mehr Flexibilität beim Entwurf mit sich, sondern auch die Möglichkeit, mit steigenden Leistungsanforderungen mithalten zu können.

Soft-Core-Multiprozessor-Lösungen zur Implementierung in FPGAs

FPGA-basierende Embedded-Systeme, die sich mit einer Vielzahl von Soft-Core-Prozessoren ausstatten lassen, eröffnen Systementwicklern neue technische Möglichkeiten. Damit können nicht nur ASIC-Entwickler ihre System-on-Chips mit speziellen Funktionen auf optimale Leistung trimmen, sondern auch Anwender programmierbarer Logik. Die Aufteilung der Verarbeitungslast einer Applikation auf mehrere Soft-Cores bringt nicht nur mehr Flexibilität beim Entwurf mit sich, sondern auch die Möglichkeit, mit steigenden Leistungsanforderungen mithalten zu können.

Entwickler von Embedded-Systemen können durch den Einsatz von mehreren Soft-Core-Prozessoren die Gesamtsystemleistung steigern oder auch Aufgaben aufteilen und damit gegebenenfalls einen Standard-Prozessor entlasten. Typischerweise werden mit 400 bis 800 MHz getaktete diskrete Prozessoren eingesetzt, um die unzähligen Aufgaben – relativ einfache wie auch sehr aufwendige – abzuarbeiten. Indem die Aufgaben nach Zeit- und Leistungs-Anforderungen partitioniert werden, ermöglichen mehrere Soft-Prozessoren eine effizientere Nutzung der Rechenleistung, während zusätzlich die gleiche oder sogar eine höhere Gesamtverarbeitungsleistung erreicht wird.

Die Anzahl von Soft-Core-Prozessoren, die in einem einzigen FPGA implementiert werden kann, hängt nur ab von den Ressourcen des Bausteins (zum Beispiel Logik und Speicher). Komplexe FPGAs beispielsweise können prinzipiell Hunderte von Soft-Core-Prozessoren integrieren. Es lassen sich auch verschiedene Soft-Core-Prozessoren – 16 oder 32 bit – implementieren, um ein Design in Bezug auf Rechenleistung, Logikfläche, Leistungsaufnahme etc. zu optimieren.
Codierungsalgorithmen können auf mehrere Prozessoren verteilt werden, je nachdem, welche Aufgaben zusammengehören. Und zeitkritische Tasks lassen sich dedizierten Prozessoren zuweisen, während weniger anspruchsvolle Aufgaben von einer oder mehreren anderen CPUs übernommen werden. Diese Flexibilität ermöglicht eine logische Gruppierung der Aufgaben und somit höhere Leistungsniveaus bei gleichzeitig reduzierter Taktfrequenz, was wiederum die Leistungsaufnahme des Systems senkt.

Embedded-Prozessoren in FPGAs

Heute stehen dem System-Entwickler Embedded-IP-Funktionen (Intellectual Property) wie CPUs, Signalverarbeitungseinheiten, Peripherie und standardmäßige Kommunikationsschnittstellen, die speziell für FPGAs entwickelt wurden, zur Verfügung. Der Multiprozessor-Ansatz senkt die Bauelementekosten, indem mehrere Prozessorkerne in ein FPGA integriert werden, wodurch z.B. die Leiterplatte kleiner werden kann. Damit sind auch weniger Signalleitungen zwischen den Prozessoren auf Leiterplattenebene erforderlich, und diese einfacheren Prozessorkerne laufen noch dazu mit einer niedrigeren Taktfrequenz. Beides führt dazu, dass auch die Anzahl der Leiterplatten-Schichten reduziert werden kann.

Wenn eine Aufgabe auf mehrere Prozessoren aufgeteilt werden kann, ist es einfacher, die einzelnen Programme zu schreiben, zu debuggen und zu warten. Damit sind enorme Kosteneinsparungen möglich. Die Code-Entwicklung sowie das Debuggen gehen schneller, und wenn das Produkt eine gewisse Reife erreicht hat, kann der Code leichter modifiziert werden, weil er wesentlich einfacher zu analysieren ist.

Multikanal-Anwendungen
Multikanal-Anwendungen können für den erforderlichen Systemdurchsatz mit Hilfe von mehreren Prozessoren auf einem Chip skaliert werden, wobei jeder Prozessor einen Teil des gesamten Kanaldurchsatzes übernimmt. Jeder Prozessor kann entweder genau den gleichen Code abarbeiten oder einige können die Algorithmen „on the fly“ wechseln, um sich den Systemanforderungen anzupassen. In manchen Fällen ist zusätzlich ein Master-Prozessor vorhanden, der die allgemeinen Aufgaben wie Systeminitialisierung, Statistik und Fehlerbehandlung übernimmt (Bild 1).

Serielle Verbindung von Prozessorkernen
Sind einzelne Prozessoren seriell in einer Kette verbunden, behandeln Systemarchitekten jeden einzelnen als eine Stufe in einer größeren Verarbeitungs-Pipeline (Bild 2). Jede CPU ist verantwortlich für einen Teil der gesamten Verarbeitungsaufgabe und jede CPU hat Zugriff auf den Datenspeicher (arbitrierte oder dedizierte Speicherschnittstellen, wenn der Speicher extern ist, oder Dual-Ported-Speicher, wenn er sich auf dem Chip befindet), um die Ergebnisse vom Ausgang der einen Stufe zum Eingang der nächsten zu „schieben“.

Prozessor-Companion
Diskrete Prozessor- und DSP-Chips, die mit einem FPGA verbunden sind, können von einer Hardware-Beschleunigung, Peripherie-Erweiterung oder Interface-Bridge profitieren, egal ob das FPGA eine CPU enthält oder nicht. Diverse Schnittstellen-IPs für die Chip-zu-Chip-Verbindung sind verfügbar, die den externen Zugriff auf Peripherie, Beschleunigungslogik und I/O-Schnittstellen in einem FPGA ermöglichen.

Erweiterung des Befehlssatzes

Diverse Prozessor-IP-Anbieter und FPGA-Implementierungen bieten die Möglichkeit, den Befehlssatz des Prozessors hardwaremäßig mit mächtigeren Befehlen für applikationsspezifische Algorithmen zu erweitern. Mit Hilfe der gängigen Lese-/Speicher-Operationen kann ein kundenspezifischer Logikblock mit Daten gefüttert werden, der wiederum zu einem Teil der Prozessor-ALU wird (Bild 3). In einigen Fällen können kundenspezifische Instruktionen Multizyklus-Operationen unterstützen und Zugang zu anderen Systemressourcen wie FIFOs und Pufferspeicher bieten. Typische Anwendungen kundenspezifischer Instruktionen sind beispielsweise Bit-Manipulationen oder komplexe numerische und logische Operationen.

Im Gegensatz zu einem Algorithmus, der mit Hilfe der normalen ALU-Ressourcen abgearbeitet wird, können kundenspezifische Instruktionen signifikante Leistungsvorteile bringen – und das, obwohl die normalen Lese- und Speicheroperationen des Prozessors genutzt werden. Ein Cyclic-Redundancy-Check-Algorithmus (CRC) für einen 64-K-Block mit einer kundenspezifischen Instruktion, die nur wenige Logikelemente benötigt, kann z.B. um den Faktor 27 schneller ausgeführt werden als mit herkömmlicher Software. Auf diese Weise lässt sich im System auch die Leistungsaufnahme reduzieren: Die gleichen Ergebnisse werden in gleicher Zeit, aber mit geringerer Taktfrequenz erreicht.

Wie Entwickler kundenspezifische Instruktionen erstellen können, hängt vom jeweiligen Prozessor-IP ab. Auf der einen Seite des Spektrums muss der Anwender einen neuen Compiler erzeugen, wenn er kundenspezifische Befehle hinzufügen will. Dieser kundenspezifische Compiler leitet dann die Aufrufe kundenspezifischer Instruktionen auf Basis einiger Applikationskriterien ab. Ein einfacherer, eleganterer Ansatz besteht darin, die Instruktion im C-Code aufzurufen, genauso wie eine normale Subroutine aufgerufen werden würde.