Forum: FPGA, VHDL & Co. Rechen-Framework für VHDL


von Batzi (Gast)


Lesenswert?

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.

von Strubi (Gast)


Lesenswert?

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...

von Andreas H. (ahz)


Lesenswert?

Batzi schrieb:
> Geht das mit MATLAB und oder Python?

https://de.mathworks.com/products/hdl-coder.html

Hth

Andreas

von Markus F. (mfro)


Lesenswert?

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).

von J. S. (engineer) Benutzerseite


Lesenswert?

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
von Batzi (Gast)


Lesenswert?

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?

von Strubi (Gast)


Lesenswert?

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.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

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.

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

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.

von hls-nap (Gast)


Lesenswert?

Ich würde an der Stelle einfach zum Q Format greifen...

von Strubi (Gast)


Lesenswert?

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.

von Purzel H. (hacky)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.