Hallo zusammen Ich bin Newbie in der FPGA-Entwicklung. Ich habe einen mathematischen Algorithmus, den ich in C simuliert habe. Allgmein benötige ich die arithmetischen Operationen add, sub, mul, div, sqrt sowie Vergleiche im floating oder fixed point format. Nun möchte ich das Ganze irgendwie in einen FPGA bringen, habe aber momentan nicht das Wissen dazu. Dabei kam ich auf folgende Idee. Ich weiss allerdings nicht ob es so Sinn mach: 1.) Ich lasse mir den Algorithmus von jemand der davon etwas versteht z.B. mit einem professionellen Tool ähnlich einem Programmmodul synthetisieren. 2.) Wenn ich es richtig verstanden haben, dann gibt ja professionelle Tools die direkt c-Code synthetisieren können. Das wäre noch besser, dann müsste ich immer nur für den Compilierservice was bezahlen:) 3.) Die einfache Logik stöpsle ich schliesslich selber zusammen. Am Ende setze ich die Programmmodule zusammen und bringe sie auf den FPGA 4.) Habt ihr vielleicht Erfahrung wie viel so eine Synthese kostet? Mit ist klar, dass es auf die Komplexität des Algorithmus abhängt. Dir kompilzierteste Gleichung sieht etwa so aus z:=d * x*x + sqrt(b*c-4*a); In der Sprache C sieht der Algorithmus sehr einfach aus. Ich arbeitemit der kostenlosen Quartus II Web edition und einem Cyclone EP1C6Q240C8 Liege ich hier gedanklich daneben oder was hält ihr von diesem Desgingansatz? Falls nicht, wer kann so etwas? Selbstverständlich würde ich dafür auch was bezahlen, es muss aber im Hobbybudget bleiben. Beste Grüsse Geri
Egal, ob Du jetzt selbst von C nach VHDL wandelst, oder es machen lässt, es wird Schweine-Geld kosten. Mein Tipp wäre: - VHDL lernen - Fixed Point Arithmetik verstehen - Module selber schreiben - Alles selber synthetisieren Wenn keine Zeit dann: - jemanden suchen, der das alles für Dich macht Wenn keine Kohle: - siehe "mein Tipp wäre" Hobbybudget ist etwas "unklar" ;-) Manche haben Hobbys, die Tausende kosten :-o Was ist das für Algorithmus? Vielleicht hat da jemand schon was gemacht und kann Dir helfen :-) Kest
@Gerhard: Du solltest dich vielleicht nochmal genauer mit dem Unterschied zwischen "Programmiersprache" (C/C++, Pascal, etc.) und "Hardwarebeschreibungssprache" (VHDL, Verilog) vertraut machen. Wenn ich mir deine Beiträge hier so anschaue, scheinst du entweder mit den richtigen Waffen auf die falschen Ziele zu schießen oder umgekehrt. ;-) Ansonsten wäre noch ein Stichwort: SystemC. Das ist eine Art Bibliothek für C, die ebenfalls Hardware nachbilden kann, und wahrscheinlich dem am nächsten, was du meinst.
Hallo zusammen @Hallo Kest: Vielen Dank für Deinen Tipp. Du hast schon recht. Es ist auch immer gut, wenn man sich wieder mal mit einer neuen Technologie beschäftigt. Einen Teil der Theorie zur FPGA-Entwicklung bin ich schon durchgegangen und ich denke, ich habe das Prinzip verstanden. Ich habe auch bereits Floating point libraries für Verilog und VHDL im Internet gefunden. http://www.vhdl.org/vhdl-200x/vhdl-200x-ft/packages/files.html Ich habe aber noch nicht durchschaut wie ich sie nach Quartus einbinden muss. Deshalb wollte ich auch mal wissen ob dieser Lösungsweg sinnvoll ist. Im Prinzip käme ich auch ans Ziel, wenn ich weiss wie man diese Libraries verwenden kann. An ein paar Tausende habe ich nicht gedacht. Deshalb auch die Frage mit dem Compilieren des C-codes. Wenn ich es richtig verstanden habe, dann gibt es auch Synthese tools die c-Code synthetisieren. Bei diesem Algorithmus werden neben etwas Steuerlogik drei Gleichungen gelöst aus denen dann entsprechende Steuersignale erzeugt werden. @Jörg: Ich meine, dass der Ansatz Rechenoperationen in einem FPGA auszuführen nicht komplett der falsche Weg ist. Ich habe mir schon einige Lösungen angeschaut und dort werden weitaus komplexere mathematische Problemstellungen/Algorithmen wie z.B. eine FFT gelöst. Ausserdem gibt es auch einige kommerzielle Libraries für FPGAs, speziell für schnelle Rechenaufgaben. SystemC habe ich mir auch schon ein wenige angeschaut:) Momentan bleibe ich aber noch bei Verilog und VHDL. Lösbar ist es ja und mit Heausforderungen wächst man...:) Beste Grüsse und nochmals vielen Dank Geri
Floating-Point ist immer etwas "problematisch". Ich habe damit noch nie irgendwas gemacht, schätze aber, dass es nicht auf Anhieb synthetisierbar ist, wenn überhaupt. Ja, es gibt Tools, die con C nach HDL wandeln, die sind aber recht teuer. Es gibt auch Tools, wo Du die Gleichnung hinschreibst und daraus entsteht dann ein FPGA-Design - die sind aber noch teuerer. Es gibt auch welche, die von MatLAB/Simulnk nach HDL wandeln - die sind auch teuer. Einen kostenlosen Weg wird es also nicht geben. Du soltest Deine Gleichung soweit optimieren, dass Du in wenigen Schritten/Takten alles berechnen kannst. Ansonsten gibt es DSPs, die die Aufgabe viel eleganter und schneller lösen können. Mit einem FPGA wirst Du nicht über 100-150 MHz kommen. Da könntest Du auch schon über einen DSP mit 500 MHz nachdenken. Ich würde erst gar nicht mit Floating-Point anfangen (wollen). Mach lieber fixed point und es wird alles viel einfacher. Grüße, Kest
@gerhard also ich kann dir nur den tip geben : versuch das ganze mit fixed point zu lösen. mit floating point sollte man (gerade als anfänger) nicht sein erstes projekt bestreiten. ich bin zwar auch ein neuling (beschäftige mich erst seit 1 1/2 jahren hobbymässig mit fpgas) aber floating point ist mir persönlich ne nummer zu hoch und alles was ich mit floating point machen muß lager ich so gutes geht auf einen uC aus. da weiß man das es funktioniert. im fpga funktioniert es sicherlich auch, aber es ist halt was anderes einen algorithmus in hardware zu giessen.
Natürlich kannst du in einem FPGA komplexe Rechenoperationen lösen, das will ich nicht bezweifelt haben. Vielmehr wäre aber zu überdenken, wie man sich der Problematik nähert. Es ist eben nicht "C und Gleichung hinschreiben", sondern man sollte schon verstehen, was auf Hardwarebasis passiert und wie man eine möglichst optimale Implementierung erreicht. Sonst wäre ein uC oder DSP besser geeignet für die Aufgabe. Ähnlich der FFT gibt es auch "computergeeignete" Darstellungen anderer mathematischer Funktionen. Ich würde vorschlagen, du suchst dir ein eben solches Verfahren z.B. für die Wurzelfunktion raus und versuchst das dann zu implementieren.
Hallo @TheMason: Mit fixed point kann ich bestimmt auch versuchen. Wenn du meinst es sei um Ecken einfacher, dann schau ich mir das mal an. Falls du mit Quartus II arbeitest und mir bitte mit einem ganz einfachen Beispielprojekt aushilfstt, dann wäre ich dir sehr dankbar! @Jörg: Welche Konsequenzen eine Implemntierung von Floating-Pointfunktionen aus Hardware-Sicht hat und dass ein FPGA bzgl. "verbrauchte" Zellen ins Schnaufen kommt, das ist mir bewusst. Dieses Problem löst sich aber mit der Zeit von selbst:) DSP ist mir auch schon in den Sinn gekommen. Ich werde mir die Sache aber auch nochmals genauer ansehen. Die Umsetzung geht mit c bestimmt etwas schneller... Beste Grüsse Geri PS: ach ja, vielleicht ein FPGA mit DSP und ein uP am besten auch noch drin:)
Wenn es nicht zeitkritisch ist, sollte man zu einem DSP-core greifen und mit C hantieren. Wenn der Algo aber steht und man Tempo braucht, ist fixed point das Beste. Das bissl HDL hat man in kurzer Zeit drauf. Poste mal eine Struktur deines Algos, dann kann man entscheiden.
Hallo Jürgen Anbei mal die Struktur des Algorithmus. Die Routine CalcCase ist ein weiterer Teil des Algoritmus, den ich aber hin bringe, wenn der andere Teil funktioniert. Das Ganze ist als Statusmaschine aufgebaut. Ich denke, das kommt der FPGA-Entwicklung zu Gute. ProcessFPGA() wird oft:) wie möglich aufgerufen. Beste Grüsse Geri PS: Deine Rückmeldung baut mich wider auf:)
Das ist nichts sonderlich Anspruchsvolles und lässt sich direkt im FPGA machen. Allerdings braucht es in jedem der states eine Sub-fsm mit Zyklen, die die verschiedenen Rechenschritte einzeln abklappern. Im Prinzip könnte man zwar alles aufbauen und nur die jeweilig entstehende Latenz abwarten, bis das Ergebnis valid ist, doch bekäme man wohl Resourcenproblme mit den Wurzeln und den devidern. Daher ist es besser, alles sequenziell zu nutzen und die platzfressenden Devider und Wurzelbilder jeweils nur einmal aufzubauen. Die dafür benötigten Komponenten werden dann einfach gespeist und das Ergebnis abgeholt, so wie bei einem Coprozessor. Das einzige, was Du tun musst, ist eine geeignete fixed point Auflösung zu finden. Gfs für jede Rechnung einzeln einstellen.
Hallo Jürgen Vielen Dank die Durchsicht des Algorithmus. Schön zu hören, dass er sich mit halbwegs Aufwand realisieren lässt. Arbeitest du selbst eigentlich mit Verilog oder mit VHDL? Wenn ich richtig kombiniere, dann hast du schon einiges mit Fixed-point Arithmetik gemacht. Mit welchen Libraries arbeitetst du da eigentlich? Für beide Sprachen habe ich eine Fixed point library gefunden. http://www.vhdl.org/vhdl-200x/vhdl-200x-ft/packages/files.html Ich weiss allerdings nicht wie ich sie anwenden muss. Allgemein gefällt mir Verilog (noch) besser als VHDL, ich glaube aber VHDL vom Sprachumfang leistungsfähiger und bietet mehr Stukturierungsmöglichkeiten. Mit Verilog selbst komme ich schon recht gut zurechet. VHDl kann ich auch nachvollziehen. Bzgl. Algorithmus: So wie du das beschreibst finde ich es ganz schön. So habe ich es mir - wie ich es von c gewohnt bin - auch vorgestellt:) Mit den Sub-FSM habe ich kein Problem. Mir fehlt hier noch die "Startmechanik". Beste Grüsse und nochmals vielen Dank Geri
Eine spezielle math-Lib braucht man hinsichtlich fixed point nicht. Du benötigst nur z.B. numeric.std. Was die state machines angeht, so mache ich das meistens so, daß jede Sub resettet und gestartet werden kann, am Ende selber im Reset hängen bleibt und beim Übergang dorthin ein ready zurückmeldet. Deine fsm, so wie so dort oben steht, braucht dann nur noch module starten und warten, bis sie fertig sind. Arbeitet man dann eine der fsm um, so verschiebt sich der Rest im timing automatisch. Wie gesagt, besteht der Aufwand im Grunde nur darin, die algorithmischen Schritte in INT-Variablen zu übersetzen und einzeln aufzubauen. Die Zeilen " s = sqrt(A*A + B*B+ C*C); A = A/s;" sähen in etwa so aus: sig_a_square <= std_logic_vector(unsigned(A)*unsigned(A)); sig_b_square <= std_logic_vector(unsigned(B)*unsigned(B)); sig_c_square <= std_logic_vector(unsigned(C)*unsigned(C)); root_radical <= std_logic_vector(unsigned(sig_a_square) + unsigned(sig_b_square) + unsigned(sig_c_square)); (wait states) s <= root_result; Dabei wäre root_radical der Eingang der root-Komponente und root_result der Ausgang dieses Moduls. Die Quadrierungen können in einem state erfolgen, könnten aber auch auf 3 states aufgeteilt werden, da Quartus erkennt, daß diese nicht gleichzeit benutzt werden und dann die benötigten embedded Multiplier automatisch gemultiplexed werden, auch wenn man das nicht ausdrücklich formuliert ("auto resource sharing"). Wichtig: Prüfe mal, ob der Quartus Megawizzard für deinen Chip die benötigten Megafunctions lpm_devider und alt_square_root erzeugen kann. Nicht dass der Cyclone I da zu knapp ist. (Müsste aber passen).
Ach ja, und für die Division (zweite Zeile) benötigt man eben den schon angesprochenen Devider entsprechender Breite. Wenn A z.B. auf 32 Bit genau sein muss, braucht man in der Regel eine 66 Bit Division, die man auch 2-stufig ausführen kann (2x40). So eine 40 Bit Division braucht etwa eine viertel us. So lange muss die fsm warten / bzw takten, bis das Ergebnis ok ist. Wenn Du aber mehrere Division hast, kann man es pipelinen (-> Megawizzard). Dann kann man jeden clk eine neue Aufgabe reinwerfen. Die Dauer beträgt etwa 10-15 clks - je nach Routing und FPGA-Frequenz. Ich mache es bei einstufigen Teilungen so, daß ich den A-Wert um genügend viele Bits erweitere, sodaß das Ergebnis korrekt rauskommt. In Deinem Fall wirst Du 2-stufig (also mit Restbewertung) rechnen müssen. Dann wird es etwas tricky mit dem pipelining: Du müsstest z.B. die Hauptdivisionen durch s von oben nacheinander einwerfen, die Latenz abwarten, die drei Ergebnisse und die zugehörigen Reste zwischenspeichern und dann die Reste nochmal einwerfen. Gfs findest du aber auch ein Timing, das alle Divisionen im FPGA zeitlich korrekt als pipeline realisiert. In jedem Fall brauchst Du nur einen Wurzelbilder und einen Divider. Wenn das FPGA sonst nicht viel macht, kann man auch mehrere Divider einsetzen.
Hallo Jürgen Zuerst mal vielen Dank für deine sehr ausführliche Rückmeldung! Ich habe nachgeschaut, mein Chip unterstützt die Megafunktionen. Zum Vorgehen.. interessant:) Ich werde mir mal überlegen wie ich jeden State in ein Programmmodul aufteilen kann, das dann durch bestimmte Ereignisse getriggert und beendet wird. Dann wird jedenfalls alles auch etwas übersichtlicher. Deine Technik mit dem Reset interessiert mich. Wenn ich dich richtig verstehe, dann wartet das Programmodul auf "seinen" Reset (Trigger) und führt dann seine Arbeit solange aus, bis es fertig ist oder eine Bedingung für Abbruch eintritt, schaltet ein Ready-Signal (Weiterschaltbedingung) auf 1 und wartet dann wieder auf einen Reset. Falls du hier vielleicht einen guten Link zu einem kleinen Beispiel hast, dann wäre das super? Da ich ja Newbie inder Sprache bin, muss ich solche Dinge sowieso lernen. So wie es aussieht muss ich mich dann aber auch mal über die Integerarithmetik Gedanken machen:) Aber auch noch anschauen wie man Module bilden kann. Wenn ich alles richtig verstanden habe, dann wird bei der Übergabe der Parameter an die Programmodule einige 64-bit Werte übergeben. Ich hoffe, der FPGA kommt dabei nicht ins Schwitzen:) Beste Grüsse und vielen Dank für Deine kontruktive Hilfe Geri
Hallo zusammen Eher eine allgemeine Frage bzw. nochmals ich. In der Zwischenzeit habe ich mir mal Gedanken gemacht, wie eine Impelmentierung mit Modulen meiner Meinung nach allgemein aussehen könnte. Nun hätte ich gerne mal Eure Meinung ob der im Bild aufgezeigte Lösungsweg sinnvolle ist bzw. ob man bei der Modellierung von FPGA-Systemen allgemein komplett anderst vorgeht? (Grundidee: 1. vom Groben zum Detail, 2. Auteilung in Teilsysteme (in VHDL Module) und 3. Hierarchienbilung) Im dargestellten Algorithmus arbeitet eine State-Machine. Jeder State ist in einem Modul (Modul 1, 2 und 3 ) untergebracht. Modul 1, 2, 3 benötigt Modul 0 (das Modul liegt konzeptuel deshalb eine Ebene tiefer) zur Berechnung. Modul 4 ist auf gleicher Ebente wie Modul 1, 2, und 3 und wird von diesen - je nach State - gefüttert:) Vielen Dank für Euere kritische Würdigung:) und beste Grüsse Geri
Schlecht siehts nicht aus, allein fehlt die Beschreibung der Funktionen.
Hallo Module 1, Module 2 und Module 3 entsprechen Stati einer Statusmaschine. In jedem der Module werden ein paar logische Operationen durchgeführt und eine komplexe Formel: m=sqrt(x*x + y*y + z*z); Deltax = m / (x*y); Das Rechenergebnis mündet dann in Module 4 Modul 0 enthält einige logische Operationen (einfach) und ein paar Multiplikationen. Einen Vorgeschmack über die Komplexität des Algorithmus habe ich ja bereit weiter oben zum Download bereitgestellt. Fixed point-Arithmetik wäre auch OK. Beste Grüsse Geri
Das scheint mir eher trivial zu sein, es sei denn, es muss eine kuntinuierliche pipeline aufgebaut werden. Die obenstehens Operation macht ein FPGA in unter 10 clks.
Hallo Hans Ich kann mir gut vorstellen, dass ein FPGA damit kein Problem hat. Mein Problem liegt eher in der Umsetzung. Ich habe momentan ehrlich gesagt keine Vorstellung wie ich den weiter oben geposteten Algorithmus "Algo.c" strukturiert umsetzen kann. Über Vorschläge würde ich mich sehr freuen:) Beste Grüsse Geri
Das läasst sich direkt umsetzen. Die Rechnungen brauchen natürlich ein paar sub states. Wurde aber oben schon gesagt. VHDL muss mal halt lernen.
Hallo Hans Vielen Dank für Deine konstruktive Hilfe. Beste Grüsse Geri
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.