Ich habe zunehmende Anforderungen Berechnungen in VHDL, also in einem FPGA darzustellen. Es geht um in der Hauptsache CO-Berechnungen und Variationen von Reglern. Die Algorithmen sind eher einfacher Natur, als vom Konzept simpel und verständlich. Es gibt aber eine Reihe von Formeln umzusetzen und ich frage mich, ob man das nicht automatisieren kann. Besonders die Breiten der unsigneds und signeds und die z.T. abartigen Bitschiebereien und Abschneidereien sind meine Sache nicht. Geht das mit MATLAB und oder Python? Es geht z.B. um sowas wie hier: Y(t+1)= k*X(t)) + (1-k)*Y(t)/2 + (1-k*k)*Y(t-2)/2 ... und oft auch die Quadrate und Kubike von X und Y. X und Y sind jeweils im Bereich von -100% und +100%, k = 0 .. 1.999 Ich würde gerne den range festlegen für k, x und den Rest rechnet das Programm aus. Also, was rauskommen kann, welche Bitbreite benötigt wird und wie man das zusammenstreichen muss, dass es stimmt.
Moin, guck dir mal MyHDL und die diversen third-party Erweiterungen wie fixbv an. Das macht das Leben etwas leichter, aber nicht alles automatisch. Wenn du solche Formeln effizient umsetzen willst, musst du immer noch etwas Grips in das Design der Pipeline stecken. Auch die hochgehypte 'HLS' kriegt das nicht so hin, wie man eigentlich will...
Batzi schrieb: > Geht das mit MATLAB und oder Python? https://de.mathworks.com/products/hdl-coder.html Hth Andreas
Batzi schrieb: > Ich würde gerne den range festlegen für k, x und den Rest rechnet das > Programm aus. Also, was rauskommen kann, welche Bitbreite benötigt wird > und wie man das zusammenstreichen muss, dass es stimmt. Na dann mach' das doch. Das einzige Problem das Du hast, sind die Konstanten, soweit ich sehe. Die sind (weil eben signed oder unsigned) einfach mal 32 bit breit. VHDL 2008 erlaubt die Definition von Konstanten mit Angabe der Vektorbreite. Wenn die 2 nicht 32 (sondern eben nur 2) bit breit sein soll, dann schreibst Du nicht "2", sondern 2d"2" (oder 2u"2"). Entsprechend wird dein Ergebnisvektor bei der Multiplikation mit dieser Konstante eben nicht 32 + 32 Bit breit, sondern eben nur 32 + 2. Wenn Du weiter gehen willst, kannst Du auch die arithmetischen Operationen von unsigned (oder signed) für eigene Datentypen überschreiben:
1 | subtype u16 is unsigned(15 downto 0); |
2 | function "+" (f : u16; s : u16) return u16 is |
3 | variable res : u16; |
4 | begin
|
5 | res := resize(unsigned'(f) + unsigned'(s), res'length); |
6 | return res; |
7 | end function "+"; |
Ab jetzt kannst Du mit u16 addieren und bekommst wieder ein u16 Ergebnis, mußt aber eben selber aufpassen, ob dein Ergebnis noch in den Vektor paßt (aber das ist anderswo auch so).
Andreas H. schrieb: > https://de.mathworks.com/products/hdl-coder.html Der HDL-Coder löst genau dieses Problem auch nicht. Das kann er auch nicht, ohne Hinweise auf die Art der Verwendung des Ergebnisses. Das gleiche gilt hierfür: Strubi schrieb: > Auch die hochgehypte 'HLS' > kriegt das nicht so hin, wie man eigentlich will... Wie auch soll ein Mathematiksyntheseprogramm (mehr sind die beide ja nicht) auch wissen, was man mit der Rechnung bezweckt? Es kann ja sein, dass der Überlauf gewollt ist, wie z.B. bei einer DDS, einer digitalen PLL oder ähnlichen Anwendungen. Es gibt also hinsichtlich des Überlaufverhaltens (passiert / passiert nicht) und der Intention (gewollt, ungewollt) eine Kombination von 4 Fällen. Hinzu kommt dass der Überlauf nur scheinbar ist, infolge der Wertefüllung oder eben der funktionellen Abläufe wegen gar nicht auftritt. Diese Fälle müsste man typisieren. Da ist es besser, das von Hand hinzuschreiben und ausdrücklich vorzugeben und zu benennen, was man möchte, also eben auch das Abschneiden der Werte und Vergessen eventueller Bits. Hinsichtlich der Möglichkeit, Werte zu begrenzen und auszurechnen, wie breit die benötigten Vektoren dann sein müssen, mache ich das mit Excel. Solche Elementarfunktionen wie Addieren, Subtrahieren und Multiplizieren kopiert man dann als Blöckchen einfach rein und kriegt die VHDL als fertigen Block heraus. Besonders wirksam ist das immer bei Operationen, die den Ergebnisvektor nicht vollständig füllen, wie z.B. das Quadrieren eines singned: Limitiert man den z.B. nicht, kommen 2n-2 Bits heraus, bei händischer Berücksichtigung des Vorzeichens wie bei DDS 2n-1. Unterlässt man den Extremwert "-n" am Eingang, kommen immer maximal nur 2n-2 heraus und im Fall der Füllung des Wertes von nur z.B. 70% kommt 2n-3 heraus. Beispiel: die 5 Bit Zahlen zwischen maximal -11 und +11 ergeben 7 bit statt scheinbaren 10. Nimmt man -16 x -16 ergibt sich 256 also 9 Bit. Damit ist die Rechnung durchsichtig, vorgeplant, dokumentiert und man hat direkt Werte, die mit denen aus Modelsim zu vergleichen sind. Das kann MATLAB nicht besser. Im Gegenteil: Wenn ich bei der Nutzung vom Systemgenerator im Simulink einen Vergleich setze, muss ich händisch Vektorbreiten mitgeben, weil dieser sonst trotz richtigen Werten verneint wird. Da gibt es eine Reihe von Dingen, die MATLAB übrigens durchaus können könnte und IMO auch können sollte. Z.B. die Berechnung der Vektorbreite nach einer Division zweier Binärzahlen mit Vor- und Nachkommastellen: Die Position des Kommas ist eigentlich fest definiert und kann von mir im Kopf ja auch berechnet werden, Simulink kennt die aber nicht.
:
Bearbeitet durch User
Markus F. schrieb: > VHDL 2008 erlaubt die Definition von Konstanten mit Angabe der > Vektorbreite. Danke für den Hinweis und deine Ausführungen. Das ist schon richtig, löst aber nicht die Aufgabe, die Formeln richtig anzuwenden und zu übersetzen. Mit dem HDL-Coder von MATHWORK's konnte ich mich in der Zwischenzeit auseinandersetzen, aber nicht anfreunden, weil er das was ich möchte, nicht kann. Eigentlich kann ich es nicht so recht glauben, dass es nichts geben soll. Codieren denn alle FPGA-Entwickler ihre Formeln per Hand?
Batzi schrieb: > Eigentlich kann ich es nicht so recht glauben, dass es nichts geben > soll. Codieren denn alle FPGA-Entwickler ihre Formeln per Hand? Nö. Aber einfach so die Formel hinschreiben is nich. Du musst Dir deine Pipeline/gewünschte Arithmetik definieren. Dann kannst du, wenn du zumindest bei Python tiefer in die Tricks mit Generatoren eingestiegen bist, an den Punkt gelangen, dass du die Formeln zumindest aufgebrochen relativ gut lesbar hinschreiben kannst und MyHDL dir daraus auch simulier/synthetisierbare HDL generiert. Also sowas wie:
1 | def pipeline(...): |
2 | |
3 | @dsp_element |
4 | def dmac1(a, b, k): |
5 | y0 = k*a + (1-k) * b |
6 | return y0 |
7 | |
8 | @dsp_element |
9 | def dmac2(a, b, k): |
10 | y1 = ... |
11 | return y1 |
12 | |
13 | ... |
Es gibt sowas auch für C++, aber das ist wesentlich uneleganter und schwerfälliger zu benutzen. Ich kann schlussendlich nur raten, das für seine spezifische Anwendung selber zu machen - wie man's dreht und wendet, muss man sich schliesslich damit beschäftigen, ob das Ding richtig rechnet. Aber der Aufwand muss sich auch amortisieren, sonst schreibt man's doch besser in HDL hin.
Batzi schrieb: > Eigentlich kann ich es nicht so recht glauben, dass es nichts geben > soll. Codieren denn alle FPGA-Entwickler ihre Formeln per Hand? Nein. Viele schauen erstmal, ob das Tool das alleine zufriedenstellend hinbekommt und wenden sich dann dem nächsten Problem zu. Man muss der Synthese natürlich die Möglichkeit geben, Randbedingungen wie z.B. Wertebereiche zu erkennen. Wird die Arithmetik zu komplex, kann man es mit automatischem Pipelining bzw Registerbalancing versuchen. Das ist zumindest bei der ASIC Synthese eigentlich seit langem Stand der Technik.
Strubi schrieb: > und MyHDL dir daraus auch > simulier/synthetisierbare HDL generiert. Bleibt die Frage, wie effektiv das HDL ist, das daraus erzeugt wrd. Solange das einfache lineare Rechenketten sind, mag das gehen. Allerdings kann man das auch gleich direkt hinschreiben.
Weltbester FPGA-Pongo schrieb im Beitrag #5670402: > Bleibt die Frage, wie effektiv das HDL ist, das daraus erzeugt wrd. > Solange das einfache lineare Rechenketten sind, mag das gehen. > Allerdings kann man das auch gleich direkt hinschreiben. Was du pro "Stage" hinschreibst, wird auch so instanziert, d.h. wenn die Pipeline nicht voll ausgelastet ist (im Sinne der linearen Ketten), verschwendet man allenfalls Logik. Ansonsten wird das Framework sehr viel kniffliger, z.B. wenn man eine fixe Anzahl MAC-Units vorgibt, und z.B. eine (hochdimensionale) Matrizen-Multiplikationn draufwirft, macht's keinen Sinn, das zu automatisieren. Den Gewinn den man in jedem Fall gegenüber dem Hinschreiben in V* hat, ist, dass man die Beschreibung der Arithmetik von der Formel getrennt hält und die Wiederverwertbarkeit recht gut ist.
> Besonders die Breiten der unsigneds und signeds und die z.T. abartigen
Bitschiebereien und Abschneidereien sind meine Sache nicht.
Das ist das absolute Minimum. Zusaetzlich sollte man eine gute Ahnung
von Mathematik haben..
Sonst wird das nichts.
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.