Forum: FPGA, VHDL & Co. Guard Bits Optimierung


von Jens W. (jensw)


Lesenswert?

Hallo zusammen,

eine Frage zum Verständnis:
In Umsetzungen von digitalen Filtern (VHDL) sehe ich immer wieder, dass 
für das Datenformat Gaurd Bits eingefügt werden. Der Vektor für das 
Ergebnis ist also länger, als man eigentlich bräuchte. Damit kann man 
sicher Überläufe verhindern.
Wenn ich das aber entsprechend umsetze, dann merkt der Synthesizer das 
und optimiert die "überflüssigen" Bits weg.

Daher meine Frage:
Wie kann man verhindern, dass diese Optimierung vorgenommen wird?
Gibt es da vielleicht ein constraint, das ich verwenden kann?

Grüße, Jens

von Rick D. (rickdangerus)


Lesenswert?

Jens W. schrieb:
> In Umsetzungen von digitalen Filtern (VHDL) sehe ich immer wieder, dass
> für das Datenformat Gaurd Bits eingefügt werden.
Wo genau hast Du das gesehen?

> Wenn ich das aber entsprechend umsetze, dann merkt der Synthesizer das
> und optimiert die "überflüssigen" Bits weg.
Ist doch prima.

> Wie kann man verhindern, dass diese Optimierung vorgenommen wird?
Warum will man das verhindern?
Wenn Logikausgänge oder Speicherstellen dauerhaft konstante Werte 
annehmen, dann können die auch konstant an die jeweilige Rail (GND oder 
Vcc) gebunden werden.

> Gibt es da vielleicht ein constraint, das ich verwenden kann?
Natürlich. Die konkrete Realisierung hängt von Deiner Toolchain bzw. vom 
Hersteller ab.

von Jens W. (jensw)



Lesenswert?

Hi Rick,

das habe ich in einem Buch "Grundlagen VHDL" gesehen, aber auch in 
Datenblättern zu speziellen Chips von TI. Da sind die Filter recht gut 
erklärt und die machen das in ihren Chips auch so.

Problematisch wird es, wenn man später erweitern will und nicht mehr 
alles anpacken will.

Ansonsten hast du natürlich recht, Vektoren werden nicht spontan 
breiter.

Gibt es einen anderen Grund, den ich noch nicht verstanden habe?

Grüße, Jens

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Angehängte Dateien:

Lesenswert?

> In Umsetzungen von digitalen Filtern (VHDL) sehe ich immer wieder, dass
> für das Datenformat Gaurd Bits eingefügt werden. Der Vektor für das
> Ergebnis ist also länger, als man eigentlich bräuchte. Damit kann man
> sicher Überläufe verhindern.

Also, ob "guard bits" wirklich der (in .de) geläufige Begriff dafür 
sind, das man die Bitbreite am Ausgang des MAC resp. für 
Zwischenergebnisse so auslegt, das nicht bei Überlauf böse 
Falschergebnisse entstehen, bezweifle ich.

Da geht es eher um den passenden Wertebereich für Integer und 
Saturation, Stichwort sollte "bit growth" sein.

Und Probleme damit tauchen eher bei µC und Co. auf, als bei FPGA, wo 
selbst bei den embedded MAC's extra bits wegen dem Bit growth vorgesehen 
sind.

https://zipcpu.com/dsp/2017/07/21/bit-growth.html

>> Gibt es da vielleicht ein constraint, das ich verwenden kann?
>Natürlich. Die konkrete Realisierung hängt von Deiner Toolchain bzw. vom
>Hersteller ab.

Eben, aber wenn beim Einsatz eine MUL18-"Macros" oder eines DSP-Slices 
was "wegoptimiert" wird, dann liegt das weniger am fehlenden constraint, 
als an "Fehlerhaften" Code in der Verhaltenbeschreibung. Da muß man 
schon den templates im style guide folgen. Insbesonders HLS zwingt dem 
Coder "ihren Willen auf".

Ich vermute aber ohnehin, es geht hier nicht um VHDL-Programmierung 
sondern um das Grundverständniss für Digitaltechnik. Fehlt es an dem, 
helfen auch Programmierkünste nicht. Auch wenn sich manche vehement 
gegen diese Einsicht stellen:

". Ich bin auch Webentwickler, daher suche ich keine Ratschläge, wo 
ich die Grundlagen der Programmierung lernen kann. Ich brauche nur 
Ratschläge, welche Literatur/Kurse/Videos ich mir ansehen kann, um in 
die Programmierung von DSP einzutauchen."  OMG

: Bearbeitet durch User
von Martin S. (strubi)


Lesenswert?

Jens W. schrieb:
> Daher meine Frage:
> Wie kann man verhindern, dass diese Optimierung vorgenommen wird?

Indem du die Bits auswertest. Aber: Was willst du genau machen? In den 
seltensten Anwendungen musst du dich um Overflow auf Bit-Ebene kuemmern. 
Besser ist eine Arithmetik a la `fixbv` aus der Python-HLS-Ecke um die 
Wertebereiche einzuhalten bzw. genug Headroom vorzuhalten.

> Gibt es da vielleicht ein constraint, das ich verwenden kann?

Viel komplizierter als das oben, aber je nach Toolchain kaemst du mit 
Stichwort 'keep' weiter.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Wuerde mich doch arg wundern, wenn da irgendein tool meint, optimieren 
zu koennen und eigenmaechtig wirklich wichtige Bits weglaesst.
Ich glaube, das ist eher so ein Fehler, den Menschen machen, wenn sie 
z.b. Ueber/unterschwingen von FIR Filtern nicht beruecksichtigen und 
dann von Hand irgendwelche Register ein bisschen zu klein 
dimensionieren.

Gruss
WK

von Jens W. (jensw)


Lesenswert?

Hallo zusammen,

vielen Dank schonmal für die Hinweise.

Um was es bei mir geht.
Ich baue einen eigenen Mikrocontroller Core. Der hat auch ein eigenes 
ROM (eigentlich ein RAM von außen zugänglich für den Opcode) und da sind 
für die Operationen auch die Konstanten drin.
Ich will das Design nur einmal synthetisieren und dann nichts mehr 
ändern, egal welches "Programm" laufen soll.
Zum Zeitpunkt der Synthese kann das ROM auch nur mit Nullen befüllt 
sein, und dann wird wegoptimiert, weil wird ja nicht gebraucht.
Wenn die Konstanten klein sind, dann werden die Vektoren auch kleiner. 
Und genau das kann ich nicht gebrauchen, wenn ich später einfach durch 
den Zugriff von außen den Opcode ändere. Dann sind die Vektoren zu kurz. 
Das ist das Problem.

Bradward B. schrieb:
> Ich vermute aber ohnehin, es geht hier nicht um VHDL-Programmierung
> sondern um das Grundverständniss für Digitaltechnik. Fehlt es an dem,
> helfen auch Programmierkünste nicht. Auch wenn sich manche vehement
> gegen diese Einsicht stellen:

Nein es geht ganz konkret um die Implementierung. Und das auch in 
ausschließlich VHDL.

Bradward B. schrieb:
> ". Ich bin auch Webentwickler, daher suche ich keine Ratschläge, wo
> ich die Grundlagen der Programmierung lernen kann. Ich brauche nur
> Ratschläge, welche Literatur/Kurse/Videos ich mir ansehen kann, um in
> die Programmierung von DSP einzutauchen."  OMG
Damit meinst du hoffentlich nicht mich! Meine Einarbeitung ist durchaus 
tief und langwierig!

Bradward B. schrieb:
> Also, ob "guard bits" wirklich der (in .de) geläufige Begriff dafür
> sind, das man die Bitbreite am Ausgang des MAC resp. für
> Zwischenergebnisse so auslegt, das nicht bei Überlauf böse
> Falschergebnisse entstehen, bezweifle ich.
Wie nennst du das dann? In der Literatur finde ich genau diesen Begriff 
für genau dieses Problem. Es gibt keine anderen Wörter im deutschen. Das 
ist doch eh alles aus dem Englischen 1:1 übernommen.

Grüße, Jens

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Jens W. schrieb:
> Der hat auch ein eigenes
> ROM (eigentlich ein RAM von außen zugänglich für den Opcode) und da sind
> für die Operationen auch die Konstanten drin.

Dann sag deinen tools: Dieses ROM ist eigentlich ein RAM und da kann 
auch mal alles moegliche drinnenstehen.

Gruss
WK

von Bruno V. (bruno_v)


Lesenswert?

Wenn Du die Bits im Design vorsiehst und sie wegoptimiert werden, dann 
werden sie in genau dieser Implementierung nicht gebraucht weil auch im 
Worst Case so ein befürchteter Überlauf nicht stattfindet.

von Andreas H. (signore_rossi)


Lesenswert?

Jens W. schrieb:
> Und genau das kann ich nicht gebrauchen, wenn ich später einfach durch
> den Zugriff von außen den Opcode ändere. Dann sind die Vektoren zu kurz.
> Das ist das Problem.

Wie sieht denn Dein Zugriff von außen aus? Wenn das ein Dual-Ported RAM 
wäre, würde da nichts wegoptimiert werden, weil die Toolchain sieht, 
dass der Inhalt extern geändert werden kann.

von Jens W. (jensw)


Lesenswert?

Bruno V. schrieb:
> Wenn Du die Bits im Design vorsiehst und sie wegoptimiert werden, dann
> werden sie in genau dieser Implementierung nicht gebraucht weil auch im
> Worst Case so ein befürchteter Überlauf nicht stattfindet.

Das stimmt. Und genau das ist das Problem. Ich will, nur weil ich den 
Opcode ändere, nicht jedes Mal neu bauen.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Jens W. schrieb:
> Ich will, nur weil ich den
> Opcode ändere, nicht jedes Mal neu bauen.

Dann! sag! deinen! tools!: Dieses! ROM! ist! eigentlich! ein! RAM!

scnr,
WK

von Andreas H. (signore_rossi)


Lesenswert?

Du hast immer noch nicht verraten, wie du den Opcode und/oder die 
Konstanten im ROM änderst ohne das das im Design als Datenpfad 
auftaucht. Dann gäbe es Dein Problem vermutlich überhaupt nicht.

von Jens W. (jensw)


Lesenswert?

Hallo Andreas,

im Moment ist es so, dass ich den Opcode noch in einem ROM liegen habe. 
Ich könnte später entweder mit dem µC den Opcode rüber kopieren. Dann 
muss ich das ROM als RAM implementieren. Da bin ich noch flexibel, das 
ist noch nicht final.
Wenn ich es aber so machen möchte, wie beispielsweise bei der ZPU, dann 
wird der Opcode als bit-File mit eingebunden. Dabei müsste ich den 
Arithmetik Core nicht mehr neu bauen, der bliebe dann gleich (und damit 
auch die Timings).
Der Core selbst soll flexibel bleiben (von der Aufgabe her). Bei kleinen 
Aufgaben sind Teile eben nicht benutzt, aber ich möchte nicht, dass die 
rausoptimiert werden.

Mit einem Bit-File macht der dann eine feldorientierte Regelung und mit 
einem anderen Bit-File rechnet er FIR Filter oder Apfelmännchen.

Grüße, Jens

von Bruno V. (bruno_v)


Lesenswert?

Jens W. schrieb:
> Mit einem Bit-File macht der dann eine feldorientierte Regelung und mit
> einem anderen Bit-File rechnet er FIR Filter oder Apfelmännchen.

Vielleicht machst Du Dir einfach zu viele Sorgen. Das Ergebnis wird 
immer so sein, wie Du es brauchst.

Ein Beispiel klassischer Programmierung wäre a=b*c.

Wenn b und c zur Compilezeit konstant sind, z.B. 3 und 4, dann macht der 
Compiler daraus a=12 (oder lässt die Zuweisung sogar weg, wenn sie nicht 
gebraucht wird). Wenn b und c variabel sind, dann ruft er Code zur 
Multiplikation auf.

Bei Dir sind sie noch konstant und Du machst Dir Sorgen um eine späteren 
Anwendungsfall, den Dein Compiler noch nicht kennt und deshalb nicht 
berücksichtigt.

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

Also bei dem prozessor den ich mal vor jahren für einen Spartan-3 gebaut 
hab, gabs die Probleme nicht, einfach BRAM als ROM instanziieren und gut 
ist, die Bits für den ROM sind irgendwo im Config-Bitstream, das wissen 
eigentlich die tools, muss man sich halt in die Doku einlesen.

https://shrek.unideb.hu/~janos.vegh/fpga/xilinx_books/docs/d2m/d2m.pdf

Das Wegoptimieren klingt hier nach "dead logic/code removal", diesen 
Optimierungsschritt kann man generell abstellen. Aber das wird an dem 
nicht besonders scharf beschrieben Szenario nix ändern.

von Martin S. (strubi)


Lesenswert?

Ok, ganz andere Baustelle. Oben wurde schon fast alles gesagt, du 
musst als erstes ein paar andere Aufgaben abfruehstuecken. In der 
Annahme, dass du das mit einer Xilinx-Architektur machst:

- Die Mapping-Summary der Synthese unter die Lupe nehmen. Da steht, zu 
welcher Komponente welche Primitiven alloziert werden.
- VHDL-Coderichtlinien UG901 anschauen
- data2mem und Details zu *.bmm -Files reinziehen (nicht trivial und 
Xilinx-spezifisch)

Mit letzterem updatest du dein 'ROM' (welches in der HW immer noch ein 
BRAM ist) mit deinem Programmfile (.elf).
Damit bist du gezwungen, ein BRAM fuer dein 'ROM' zu instanzieren. Fuer 
ein echtes ROM musst du auf jeden Fall neu synthetisieren oder das .bit 
direkt manipulieren, was auch eine Kenntnis der Interna und gezielte 
Allozierung im Placement erfordert. NOT RECOMMENDED :-).

Um die ROM-Funktion zu emulieren, verbietest du schlicht den 
Schreibzugriff auf geschuetzte Adressen, wie z.B. Boot-Code. Da wird 
dann auch nix mehr wegooptimiert.

Es gibt noch eine elegante Loesung, bei der du deine 'ROM'-Daten an das 
.bit-File haengst, und ins SPI-Flash braetst. Dann musst du nur noch mit 
dem geeigneten Code die Daten umkopieren.
Fuer die ZPU gibt es einen quasi fertigen Setup hier: 
https://github.com/hackfin/MaSoCist

von Andreas H. (signore_rossi)


Lesenswert?

Wenn Du Dein Programm- und Konstantenspeicher als durch deinen 
Mikrokontroller beschreibbaren Speicher implementierst, wird da nix 
wegoptimiert, auch wenn erstmal nur Nullen in der initialen 
Konfiguration stehen. Da existiert Dein Problem überhaupt nicht.

Zu data2mem hat Martin schon was gesagt.

Je nach Zielarchitektur kannst du dein ROM auch per partielle 
Rekonfiguration aktualisieren. AMD nennt das "Dynamic Function eXchange" 
(DFX). Auch wenn es vielleicht anders klingt, darf in dem 
auszutauschenden Bereich auch einfach nur ein ROM aus BRAMs mit 
Interface-Logik drin sein.

Wenn du DFX benutzt, hast du genau, was Du willst. Dein Mikrocontroller 
und weitere Logik im statischen Bereich wird einmal synthetisiert und 
implementiert; dein ROM liegt im rekonfigurierbaren Bereich, sodass Du 
für jedes Programm nur noch diesen Teil synthetisieren und 
implementieren musst.

Siehe https://docs.amd.com/r/en-US/ug909-vivado-partial-reconfiguration

Mit passendem FPGA ist das gut nutzbar aber schon auch aufwendig. Ich 
bin mir nicht sicher, dass sich da der Aufwand lohnt.

Per DFX austauschbares ROM würde ich eher als Ausprobier-Szenario für 
DFX sehen, als als sinnvolle Option das eigentliche Problem zu lösen.

Dauert die Synthese/Implementierung des Gesamtsystems überhaupt so 
lange, dass das ein Problem ist?

von Jens W. (jensw)


Lesenswert?

Vielen Dank,

mit den Tipps muss ich mich beschäftigen.
Aber das hört sich so an, wie das was ich gesucht habe.

Grüße, Jens

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.