Forum: FPGA, VHDL & Co. Regler-Entwurf: Fixpoint oder integer?


von Patrick B. (p51d)


Lesenswert?

Hallo allerseits

Ich habe mal eine Frage wie auf einem FPGA richtig gerechnet wird. Ich 
möchte einen kleinen PI-Regler mit anti Windup (Back calculation) 
entwerfen. Die Regelparameter sind 32Bit Eingangsregister, das 
Error-Signal ist maximal 16Bit signed und die Stellgrösse soll 32Bit 
signed sein.

Wenn ich jetzt nur den proportionalen Pfad durgehe, dann ergibt sich 
nach dem Kp-Gleid ein 48Bit Register. Soll ich jetzt im Regler überall 
unterschiedliche Registergrössen verwenden oder gleich auf 64Bit 
vergössern? wWie wird das in VHDL normalerweise gemacht?

Auf einem Microcontroller kann man float oder double verwenden, aber auf 
dem FPGA?!

Bei einem Simulink-Model hatte ich in der Schule Fix-Point eingesetzt. 
Kann durch Fixpoint Registerbreite eingespart werden oder ist dies nur 
für einfachere Rechnungen?

Besten Dank,
MFG
Patrick

von J. S. (engineer) Benutzerseite


Lesenswert?

Es gibt verschiedene Methoden, das umzusetzen- vor allem, wie man die 
Genauigkeit (im letzten Bit) aufrechterhält. Bei den Bitbreiten ist es 
so, dass letztlich die am Ausgang verwendete Breite dafür verantwortlich 
ist, was in den Pfaden davor jeweils verwendet wird. Nicht benötigtes 
wird weggeworfen. Praktisch läuft es darauf hinaus, wie Du an welchen 
Stellen rundest.

Ob Du Integer verwendest, ist mehr eine Frage der Einfachheit der 
Beschreibung. Wenn viel gerechnet wird, würde ich das tun.

Bei Fix-Point-Formaten musst Du gfs etwas mehr nachdenken, hast aber die 
lokalen Auflösungen besser im Griff und stösst nicht an Grenzen. 
Ausserdem kann man in der Tat bits sparen, wenn man die 
Definitionsbereiche einschränkt und optimiert. Wenn man z.B. den Wert 
-32768 weglässt, spart man bei der ersten Multiplikation direkt ein bit 
ein. Bei einem Limit auf 0,7% der Aussteuerung sind es sogar 2. Das 
macht aber heute kaum noch einer, weil FPGA-Fläche billig geworden ist, 
es sei denn, es geht genau um eine RAM-Grenze beim Speichern etc.

In Deinem Fall ist die Rechung derart mickrig, dass die FPGA-Grösse 
durch andere Dinge bestimmt wird.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Patrick B. schrieb:
> Kann durch Fixpoint Registerbreite eingespart werden
Nein.
Denn für ein Festpunktformat wird lediglich das Komma an eine andere 
Stelle verschoben.
Es ist also, wie wenn du Strecken nicht in Metern, sondern in Millimeter 
oder Kilometer angibst.

Du könntest also z.B. für ein Kabellängenmessgerät ein Festpunktformat 
mit 3 Nachkommastellen nehmen und in Metern rechnen, oder du nimmst 
einen Integer und rechnest in Millimetern...

von Strubi (Gast)


Lesenswert?

Moin,

auf dem FPGA kannst du auch mit float draufschlagen (gibts auch 
typischerweise Code-Generatoren für), aber da geht die alte Diskussion 
Float vs. Fixpoint wieder los. Da die Daten bei einfachen Reglern aber 
doch meist recht begrenzt in den Werten sind, gibt es eigentlich keinen 
Grund, float zu nehmen, bzw. Nachteile:
- Mehr Logik- und Stromverbrauch
- Rundungsfehler bei grösseren Werten
- Keine Kontrolle über Fehlerfortpflanzung

Letzteres war für mich oft ein Killerkriterium, da das Maschinen-Epsilon 
(die vom LSB definierte Genauigkeit, z.B. 1/32768) dann vom Exponenten 
abhängt. Das wird dann beliebig hässlich, wenn man eine Genauigkeit für 
die gesamte Verarbeitungskette angeben muss. Lieber implementiert man 
dann Logik, die den Fehler immer mitführt, und nutzt Dithering-Techniken 
oder implementiert gleich eine Art Bresenham für die Approximation. Zum 
Thema Fixpoint/Rundung/Sättigung kann auch ein Blick in ein 
DSP-Referenzmanual wie z.B. des Blackfin nicht schaden.

Ich würde also gleich mal mit 64 bit anfangen (zumindest auf 
Akkumulatorseite). Später kannste immer noch runterskalieren, oder die 
Toolchain die nicht benötigten Bits rausschmeissen lassen.
Solange das nicht zu komplex wird, kann man das in VHDL ganz gut machen.
Ab einer gewissen Komplexität amortisieren sich dann eher Ansätze via 
MyHDL.

Grüsse,

- Strubi

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Und vor allem darf man nicht vergessen, dass eine Fließkommazahl zwar 
eine "gigantische" Dynamik, aber nur eine recht geringe Genauigkeit 
hat. Eine 32 Bit Fließkommazahl nach IEEE-754 hat nur 7 signifikante 
Stellen (weil die Mantisse da nur 23 Bit breit ist: 0...8388607).
Ein 32 Bit Integer hat immerhin fast 10 signifikante Stellen: 
0..4294967296

: Bearbeitet durch Moderator
von Patrick B. (p51d)


Lesenswert?

Verstehe ich das richtig, dass es eigentlich keinen grossen Vorteil 
bringt, wenn man Fix-Punkt verwendet?

Also werde ich im Regler intern wohl mit 64Bit-Registern arbeiten und am 
Ausgang wieder auf 32 Bit signed herunterskallieren.

von Strubi (Gast)


Lesenswert?

Patrick B. schrieb:
> Verstehe ich das richtig, dass es eigentlich keinen grossen
> Vorteil
> bringt, wenn man Fix-Punkt verwendet?
>
> Also werde ich im Regler intern wohl mit 64Bit-Registern arbeiten und am
> Ausgang wieder auf 32 Bit signed herunterskallieren.

Fixpoint ist ja faktisch Integer, nur schiebst du jeweils die Bits 
entsprechend der Nachkommastellen (binär, und von der Software-Seite her 
gedacht) nach rechts. In VHDL schneidest Du dir einfach aus dem Vektor 
die dir relevanten MSBs raus (unter Vernachlässigung der 
Rundungsaspekte).
Schlussendlich ist es eine Frage der Normierung. Wenn Du Werte zwischen 
0 und 1 elegant verarbeiten willst und die Genauigkeit 
(Nachkommastellen) feststeht, dann landest du halt immer bei 
Fixpunkt-Arithmetik. Wann du schlussendlich normierst, musst Du eben 
anhand des Wertebereichs und der gewünschten Genauigkeit festlegen. 
Solche generischen Aspekte kann man sich bei div. DSP-Architekturen gut 
abgucken.

von J. S. (engineer) Benutzerseite


Lesenswert?

Patrick B. schrieb:
> Verstehe ich das richtig, dass es eigentlich keinen grossen Vorteil
> bringt, wenn man Fix-Punkt verwendet?
Ich würde es mal so formulieren: Bei einem FPGA gibt es - was Register 
an geht - keine präferierten Bitbreiten. Von daher muss man auch (nur 
deswegen!) nicht die Kommastellen anpassen.

> Also werde ich im Regler intern wohl mit 64Bit-Registern arbeiten und am
> Ausgang wieder auf 32 Bit signed herunterskallieren.

Du solltest lokal mit der jeweils benötigten Breite arbeiten, die 
optimal ist. Die elegante Methode ist, sich die benötigte Auflösung an 
jeder Stelle im Design bewusst zu machen und zu optimieren. Die einfache 
Methode ist, dass einfach genügend viel Auflösung mitgeschleppt wird. 
Minimum ist aus naheliegenden Gründen ein Faktor 2 - gängig und 
schlüssig ist Faktor 10 -> 4 Bit mehr und gut ist. Auf die unteren Bits 
gibt man dann statistisches Rauschen, bevor man sie rundet.

Was Du brauchst, hängt letzlich immer von den Ansprüchen ab, konkret dem 
S/N des Eingangssignals und damit dem relativen Fehler dazu, den die 
Digitalwelt zusätzlich produziert. Für Hi-Q-Audio muss man da mehr tun, 
als bei normaler Messtechnik und da wieder mehr, als z.B. beim Video. Am 
Besten baust Du Dir deinen Rechenpfad mal in Excel auf und simulierst 
den Rundungsfehler. Dann siehst Du auch, ob Du was tun musst.

Wie andere schon geschrieben haben, würde ich von Float die Finger 
lassen, weil das wieder Restriktionen in der Auflösungen bringt und 
unverhältnismässig Resourcen braucht. Sowas baut man in FPGAs nur auf, 
wenn man C-Code 1:1 ins FPGA bringen will/muss und die validierte 
Rechenkette abbilden soll.

... oder in dem obskuren Fall, wenn die SPEC es zanghaft vorschreibt, 
dass man mit aller Gewalt einen float32 auf den Bus legen muss, weil der 
Controller das so übernehmen soll, ohne zu wandeln. (ja, solche SPECs 
gibt es :D)

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Patrick B. schrieb:
> Die Regelparameter sind 32Bit Eingangsregister, das
> Error-Signal ist maximal 16Bit signed und die Stellgrösse soll 32Bit
> signed sein.
>
> Wenn ich jetzt nur den proportionalen Pfad durgehe, dann ergibt sich
> nach dem Kp-Gleid ein 48Bit Register. Soll ich jetzt im Regler überall
> unterschiedliche Registergrössen verwenden oder gleich auf 64Bit
> vergössern? wWie wird das in VHDL normalerweise gemacht?

Bei deiner Wahl ob fixed-Point (sfixed oder ufixed) bzw. integer (signed 
oder unsigned) musst du prüfen, was dein Simulator bzw. Logicanalyser 
(Chipscope/Signaltap/Reveal) kann. Nichts ist schlimmer als mit 
unterschiedlichen Darstellungen zu kämpfen.

Welche Auflösung hat dein DAC? Es fällt mir schwer die 32 Bit 
anzunehmen. Es wird auch in der Nähe des Error-Signals liegen.

Du musst dir die Multiplizierer in DSP-Slices der FPGAs ansehen, 18 Bit 
sind dort verbreitet. Diese 18 Bit sind ein guter Ansatz für die interne 
Verarbeitungsbreite. Die Accumulatoren der DSP-Slices liegen bei 45..48 
Bit. Die rundest und schneidest du hinterher wieder auf 18 Bit.

Tom

von J. S. (engineer) Benutzerseite


Lesenswert?

Die Spartan6er MULs haben sogar 18x25Bit. Aus der Kombi lässt sich 
einiges effektiv herstellen, z.B. 36x50Bit. Das sollte wohl reichen.

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.