Forum: Mikrocontroller und Digitale Elektronik FPU für ARM7


von Gerd (Gast)


Lesenswert?

Hallo,
ich entwickle grade ein eigenes kleines Board mit einem ARM7 
Mikrocontroller. Ein FPGA soll da auch mit drauf, ich dachte an das 
Modell EP2C8 von Altera.
Der FPGA wird hauptsächlich als IO-Baustein benutzt (er macht ne PWM und 
steuert viele parallele IO-Ports).
Frage: da ich gerne floating point nutzen würde für gewisse 
Berechnungen, dachte ich mir könnte man vielleicht im FPGA eine kleine 
FPU integrieren? Der Mikrocontroller kann den FPGA über das externe 
Speicherinterface ansprechen wie ein statisches RAM. Ich hab in den 
Adressbereich gewisse register gemappt, sodass man z.B. die PWM 
einstellen kann und dergleichen.
Frage: Wäre so eine FPU prinzipiell machbar? Könnt ihr mir dazu 
vielleicht sogar ein paar Anregungen geben? Eine weitere Frage wäre 
dann, wie ich das ganze in meinem Programmcode für den Mikrocontroller 
so einbaue, dass es für den Compiler transparent ist. Sprich, wenn ich 
folgendes Programmiere

float a, b, c;
a = 1.23;
b = 2.34;
c = a * b;

Dann soll der Compiler das nicht softwaremässig ausrechnen, sondern soll 
meine FPU ansprechen, die das dann in Hardware macht.

Ist mein Vorhaben realisierbar?

: Verschoben durch Admin
von Iulius (Gast)


Lesenswert?

Machbar ist das schon, die Frage ist ob es sich für solch ein Level 
überhaupt lohnt.

Ich weiß nun nicht wie viele Takte der ARM7 für eine Multiplikation 
bräuchte, aber selbst bei gleichem Takt von FPGA und Controller wären es 
dann mindestens 2.

Bei Divisionen ggf noch viel mehr(kommt auf den Takt des ARM an).


Im compiler würde ich das über eine Funktion lösen, also mult(a,b) -> 
welche dann eben die entsprechenden schreib und lesebefehle ausführt.

Eventuell kann man aber auch die Aktionen auf den Operator auftauschen, 
da ich von ARM bzw den Compilern dazu jedoch nichts verstehe kann ich 
dazu nichts sagen.


Also machbar auf jeden Fall, wirklich lohnen tut es sich im Allgemeinen 
jedoch erst bei umfassenderen Berechnungen. Typischerweise Berechnungen 
die im Gegensatz zum Controller parallelisiert werden können.

von Xenu (Gast)


Lesenswert?

Von Xilinx bekommt man sowas sogar geschenkt:

http://www.xilinx.com/support/documentation/ip_documentation/floating_point_ds335.pdf

Damit es für den Compiler transparent wird, müsstest Du selber am 
Compiler etwas ändern. Eigene Funktionen zu schreiben ist da wohl 
einfacher.

von (prx) A. K. (prx)


Lesenswert?

Da wär's netto wahrscheinlich einfacher und schneller, wenn man den ARM7 
(oder ein Äquivalent) gleich komplett ins FPGA reinschmeisst.

von 900ss (Gast)


Lesenswert?

Ich denke, dass das schon beschleunigt, da ja floating point Operationen 
nicht in 2 Takten erledigt sind. Das das ein Workaround ist... schon 
klar. Aber unter den gegebenen Umständen ist die Lösung meiner Meinung 
nach gut. Es sei denn, es kommen kaum solche Operationen vor. Dann ist 
es den Aufwand wahrscheinlich nicht wert. Auch nicht, wenn die SW eh 
genug Zeit hat, die Berechnungen zu erledigen.

Und machbar ist das sicher. Ein paar Register für die Werte und eines 
für die Operationen. Status und Ergebnis kann dann in weiteren Registern 
abgeholt werden.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Machbar ist das, ohne dass du etwas am Compiler ändern musst. Du 
kompilierst den Code mit Floating-Point-Befehlen, fängst die undefined 
instruction exceptions ab, und gibst die Arbeit da an den Coprozessor 
ab. Auf diese Weise ist z.B. Soft-Floating-Point im Linux-Kernel 
implementiert.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

das ist dann aber sicher nicht mehr schneller als -msoft-float.

- Exception tritt auf
- Eintritt in den Handler
- Setzen von FPGA Registern (da extern geht das auch nicht beliebig 
schnell)
- Warten bis das FPGA soweit ist
- Auslesen des Ergebnis
- Laden der internen Register mit dem Ergebnis
- Austritt aus dem Handler

Floating point in Software ist übrigens gar nicht so schlimm wie man 
sich das vorstellt.

Matthias

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Andreas Schwarz schrieb:
> Machbar ist das, ohne dass du etwas am Compiler ändern musst. Du
> kompilierst den Code mit Floating-Point-Befehlen, fängst die undefined
> instruction exceptions ab, und gibst die Arbeit da an den Coprozessor
> ab.

Ist zwar sehr clever, führt aber dazu, dass das alles noch langsamer 
wird. Das endet dann in einer großen switch-case Anweisung im undef 
Handler, die auch erstmal bearbeitet werden will.

Wenn eine FPU unbedingt nötig sein sollte, dann sollte man sich auch 
einen Prozessor mit FPU gönnen. Alles andere ist gebastelt. Die Frage 
ist, ob der OP das machen will weil's Spaß macht und scheinbar elegant 
ist, oder weil ein dringender Bedarf besteht ("Software läuft nicht, da 
der Prozessor mit floating point Berechnungen voll ausgelastet ist und 
Festkomma nicht in Frage kommt").

Auf jeden Fall eine Kosten-Nutzen Analyse durchführen.

Gruß
Marcus
http://www.doulos.com/arm/

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Ja, viel kann man sich von dieser Exception-Lösung nicht erwarten. 
Irgendwo gibt es einen Benchmark der "direktes" Soft-Float mit 
Soft-Float per Exception vergleicht; letzteres ist um eine Größenordnung 
langsamer, wenn ich mich richtig erinnere.

von Iulius (Gast)


Lesenswert?

>> Wenn eine FPU unbedingt nötig sein sollte, dann sollte man sich auch
einen Prozessor mit FPU gönnen

Diese Ansicht könnte man auch unbegrenzt weiter betreiben.

Dann wären plötzlich Grafikkarten auch sinnlos und Asics für Mpeg 
braucht wohl auch niemand mehr, kaufe man doch sich einfach einen 
Controller der schnell genug dafür ist.

Ganz nach dem Motto : sollen sie doch Kuchen essen !

Weiß auch nicht was an einem CoProzessor-Konzept Gebastel ist. Viel mehr 
ist das doch Standard weil sinnvoll. Man laste jeden Chip mit der Art 
von Funktionen aus für die er gemacht ist und alles wird gut.


Der FPGA ist beim OP nunmal vorhanden deswegen spricht auch nichts 
dagegen den zu benutzen wenn es wirklich zu einem Speedup führt.

Hatte zwar eigentlich vermutet der ARM7 würde das auch recht schnell 
können aber dem ist wohl nicht so und dann lohnt es sich allemal.

Sonderlich viel Aufwand ist das nun wirklich nicht wenn die ganze 
Kommunikation eh schon steht.



Tut mir Leid, ich muss mich so stark dafür einsetzen. Dieses 
Thema(Auslagerung von rechenintensiven Aufgaben auf einen FPGA) ist der 
Grund warum ich überhaupt zu meinen Lieblingen gekommen bin :)

von Gerd (Gast)


Lesenswert?

Hallo,
sorry dass ich mich so spät erst wieder melde. Ich war unterwegs...

Cool, so viele Beiträge!

Also, der FPGA ist am externen Memory Interface des ARM7 angebunden über 
einen 16 Bit breiten Bus. Der ARM läuft mit 80 MHz, und kann auch mit 
dieser Geschwindigkeit auf den Bus zugreifen, ich denke das sollte nicht 
das Problem sein.
Und genau so, wie das weiter oben beschrieben wurde, wollte ich das auch 
machen: über die UNDEF-Exception. Eigentlich hätte ich erwartet, dass 
das schneller ist, als in Software zu rechnen, nun bin ich ein bisschen 
erstaunt, dass dem nicht so sein soll? :-O
Eine weitere denkbare Lösung wäre wie folgt:
Man kompiliert mit Sofware-floating Point. Der Compiler sucht dann ja 
nach bestimmten Funktionen; wenn ich im Code zum Beispiel eine 
float-Addition habe, dann generiert der Compiler an dieser Stelle dann 
in wirklichkeit nicht das

c = a * b;

sondern das:

c = fmul(a, b);

Wobei fmul eine Funktion ist, die softwaremässig zwei float-Zahlen 
addiert.
Wenn ich jetzt das Symbol fmul auf meine eigene float-addition 
'verbiegen' würde, dann hätte ich da bereits eine fertige Funktion, die 
die beiden Operanden bekommt, diese nur noch in den FPGA schaufeln muss 
und die Ergebnisse dann wieder ausliest.
Ich wage mal zu behaupten, dass dies allemal schneller wäre, als 
softwaremässig zu rechnen, oder täusche ich mich da?

Des weiteren frage ich mich natürlich, ob mein doch schon relativ 
kleiner FPGA zumindest für eine bescheidene FPU reicht. Wenn er 
wenigstens dividieren könnte, wäre das schon eine ziemliche 
Erleichterung, denn der ARM7 hat keine Instruktion für Dividieren.

Warum ich das machen will:
Es soll nur ein Experiment sein. Schauen ob es geht, und ob es eine 
Verbesserung beim Rechnen bringt. Es ist also nur eine Spielerei, aber 
wie bereits korrekt gesagt wurde:
Der FPGA sitzt eh schon auf dem Board, und er ist nur recht wenig 
ausgelastet (ein paar IOs, ein paar PWMs). Da könnte man doch noch was 
machen mit! :-)

von (prx) A. K. (prx)


Lesenswert?

Gerd schrieb:

> Wobei fmul eine Funktion ist, die softwaremässig zwei float-Zahlen
> addiert.

Hoffentlich nicht ;-)

von Gerd (Gast)


Lesenswert?

> Hoffentlich nicht ;-)

Äääh, multipliziert natürlich :-D Danke AK!

von (prx) A. K. (prx)


Lesenswert?

Hübsche Tabelle über die Performance von ARM7 bei Fliesskommrechnung bei 
48MHz, für deine 80MHz entsprechend skalieren:
http://www.smxrtos.com/ussw/gofast/gofast_arm_cwk.htm

Jetzt rechne mal zusammen, wieviel Takte für die Operandenübertragung 
zum FPGA draufgehen, plus Overhead der Funktion. Dazu kommt dann noch 
eine vom Aufwand der FPGA-Implementierung abhängige Anzahl Takte (ein 
kombinatorischer Multiplier frisst recht viel Platz). Dann kriegt du 
eine Vorstellung davon, ob sich das lohnt.

von Purzel H. (hacky)


Lesenswert?

Eine FPU wird in den seltensten Faellen benoetigt. Wer brauch denn schon 
einen dynamischen Bereich von 10^306 fuer einen Single. Ein Int32 hat 
aber mehr signifikante Stellen wie ein Single.

von (prx) A. K. (prx)


Lesenswert?

Mini Troll schrieb:

> Eine FPU wird in den seltensten Faellen benoetigt. Wer brauch denn schon
> einen dynamischen Bereich von 10^306 fuer einen Single.

Welches single precision format hat diesen Exponentenbereich? IEEE 754 
jedenfalls nicht.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Gerd schrieb:
> Wenn ich jetzt das Symbol fmul auf meine eigene float-addition
> 'verbiegen' würde, dann hätte ich da bereits eine fertige Funktion, die
> die beiden Operanden bekommt, diese nur noch in den FPGA schaufeln muss
> und die Ergebnisse dann wieder ausliest.

Das ist auf jeden Fall der Weg den es zu gehen gilt. Sobald du das über 
Exceptionhandling machst wird laaaaangsam. Wenn du wissen willst was 
dein FPGA-Programm dann schlagen soll schau mal hier:

http://gcc.gnu.org/viewcvs/trunk/gcc/config/arm/ieee754-sf.S?revision=148210&view=markup

Das ist die Softfloat Implementierung des GCC

> Ich wage mal zu behaupten, dass dies allemal schneller wäre, als
> softwaremässig zu rechnen, oder täusche ich mich da?

Wie schnell kann dein FPGA nach dem Laden der Register das Ergebnis 
berechnen? In einem einzelnen Takt dürfte das ja auch nicht machbar 
sein.

> Warum ich das machen will:
> Es soll nur ein Experiment sein. Schauen ob es geht, und ob es eine
> Verbesserung beim Rechnen bringt.

Dann mach es. Du wirst dabei viel lernen. Das es wirklich (deutlich) 
schneller wird denke ich nicht aber das soll dich nicht abhalten.

Evtl. lohnt sich aber ein Blick eine Ebene höher. Was machst du mit den 
Floatberechnungen? Lohnt es sich evtl. den ganzen Algorithmus auf das 
FPGA auszulagern?


Matthias

von Gerd (Gast)


Lesenswert?

Hallo,
also der FPGA bekommt seinen Takt von einem 50 MHz Quarzoszillator. 
ABER! er hat zwei PLL's drin. Wenn man möchte, könnte man dann doch 
damit den Takt auf sagen wir mal 200 MHz vervielfachen, und dann mit 
diesem schnelleren Takt die Berechnungen durchführen. Oder nicht? Das 
sollte dann ja auch nochmal schneller sein.
Dass es sich lohnt vom Aufwand her habe ich schon von Anfang an 
bezweifelt, aber versuchen möchte ich es trotzdem. Wie Matthias gesagt 
hat - weil ich dabei einiges zu lernen beabsichtige. Und wer weiss, 
vielleicht kann man das ja auch brauchen?

Frage:
Kennt jemand eine gute FPU-Implementierung auf einem FPGA? Auf Opencores 
habe ich bereits geschaut. Gibts noch mehr?

von (prx) A. K. (prx)


Lesenswert?

Gerd schrieb:

> ABER! er hat zwei PLL's drin. Wenn man möchte, könnte man dann doch
> damit den Takt auf sagen wir mal 200 MHz vervielfachen, und dann mit
> diesem schnelleren Takt die Berechnungen durchführen. Oder nicht?

Das hängt etwas davon ab, wie deine FPU arbeitet. Wenn du nicht genug 
Platz für einen mindestens partiellen kombinatorischen Multiplizierer 
hast, dann muss der Takt so schnell werden wie möglich und wie die 
internen Laufzeiten zulassen(!). Und es wird dann trotzdem nicht 
reichen.

Wenn du andererseits einen solchen drin unterbringst, dann wird dessen 
Performance nicht primär vom maximal theoretisch möglichen Takt des 
FPGAs bestimmt, sondern massgeblich von der Durchlaufzeit des CSA-Trees.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Iulius schrieb:
> Diese Ansicht könnte man auch unbegrenzt weiter betreiben.
>
> Dann wären plötzlich Grafikkarten auch sinnlos und Asics für Mpeg
> braucht wohl auch niemand mehr, kaufe man doch sich einfach einen
> Controller der schnell genug dafür ist.

Kommt auf die Anwendung an. Ich kann durchaus nachvollziehen, weshalb 
jemand das unter Umständen lieber mit Hardware von der Stange erledigen 
möchte.

> Ganz nach dem Motto : sollen sie doch Kuchen essen !

Wenn der Kuchen letztlich günstiger ist, warum nicht.

> Weiß auch nicht was an einem CoProzessor-Konzept Gebastel ist.

Weil eine professionelle Anwendung verlangt, mehr oder weniger 
umfangreiche Doku zu lesen (IEEE754), zu verstehen(!), das Verstandene 
umzusetzen, Dokumentation zu erstellen, die korrekte Funktion zu 
verifizieren, usw.

Bei einem Controller mit FPU hat sich die Arbeit schon jemand anderes 
gemacht. Schneller als die FPGA Lösung ist es sowieso.

> Sonderlich viel Aufwand ist das nun wirklich nicht wenn die ganze
> Kommunikation eh schon steht.

Nun ja...

> Tut mir Leid, ich muss mich so stark dafür einsetzen. Dieses
> Thema(Auslagerung von rechenintensiven Aufgaben auf einen FPGA) ist der
> Grund warum ich überhaupt zu meinen Lieblingen gekommen bin :)

Gegen auslagern kritischer Funktionen ist ja nichts einzuwenden. Nur 
muss man eben sorgfältig abschätzen ob man unterm Strich, unter 
Einbeziehung  des zweifellos höheren Entwicklungsaufwands, was davon 
hat. In einem kommerziellen Projekt würde ich bei dieser 
Anwendungsbeschreibung eher davon abraten. Für ein Proof-of-Concept, 
oder eine Spielerei wie in diesem Fall ist das allemal eine nette 
Aufgabe.

Gruß
Marcus
http://www.doulos.com/arm/

von Iulius (Gast)


Lesenswert?

Ja wie ich oben schon geschrieben habe : ich hielt es ursprünglich auch 
nicht für so sinnvoll weil ich nicht vermutet habe das sich eine 
Multiplikation überhaupt signifikant beschleunigen ließe.

Wenn ich mir aber die smxrtos seite ansehe und der arm7 für eine 
multiplikation >1µs benötigt, dann sehe ich da doch die möglichkeit das 
zu schaffen.


Der einzig wirkliche Aufwand ist doch dabei die Kommunikation.
Der ep2c8 hat 36 multiplier eingebaut, also kann der das ziemlich fix.

Habs grad mal probiert, der standardwizard schafft selbst bei 64bit 
floating point eine multiplikation in ~55ns, also mit nicht ganz 20mhz.

Damit sind auch nur 50% der internen multiplier belegt sowie 11% der LE.
(man könnte also sogar 2 einbauen)

Single precion sind es sogar fast 40mhz die erreicht werden bei ~4%(20% 
mult) FPGA Belegung.


Selbst das (wizard-und-einmal-hingeklickt-Lösung) ist, zumindest im 
vergleich zu oben verlinkter Tabelle, mehr als 20mal so schnell.

Wenn man also die Kommunikation in entsprechender Zeit schafft, dann 
spricht nichts dagegen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.