Forum: FPGA, VHDL & Co. VHDL - Bruch mit 2er Potenz im Nenner


von Stefan H. (Firma: dm2sh) (stefan_helmert)


Lesenswert?

Hallo,

wenn ich bspw. folgendes in VHDL machen will:
y <= x/1024 * 345;
dann sagt mir der Compiler, dass das Multiplikationsergebnis 
(std_logic_vector) länger ist als die Faktoren. Ich hatte allerdings 
gehofft, dass er die 2er-Potenz erkennt und zerlegt:

gekürzt wird daraus folgendes:

So implementiert ist keine Erweiterung des Bitvektors nach links nötig. 
Warum verlangt der Compiler es trotzdem?

Wenn ich die ursprüngliche Variante wähle und den Vektor erweitere, 
bringt das dann Nachteile?

von J. S. (engineer) Benutzerseite


Lesenswert?

Über solche Geschichten (fehlberechnete Vektorlängen) habe ich mich auch 
schon des öfteren gewundert. Ich benutze für sowas dann einen manuellen 
Konstrukt, den ich mir mit Excel zusammenbaue und validiere. Auch für 
das o.a. Problem habe ich mir mal ein Excel gebaut, dass allerlei 
Teilungen auf fortgesetzte Additionen zurückführt. Das stammt noch aus 
einer Zeit, wo man die Register einzeln programmieren musste -)

In Deinem Fall könnte es sein, dass er einen Multiplier instanziert und 
erst gar keine Anstalten macht, einen CCM zu bauen. Oder, Du hast signed 
Typen und bei der Division intepretiert er nach einer allgemeinen 
Vorschrift ohne die Werte zu checken und kommt dann auch ein Bit mehr 
(wegen der +1024).

Probiere mal eine 1023 oder eine -1024, dann siehst Du,ob es daran 
liegt.

Welche Vektoren benutzt Du?

Macht er das bei der Division durch 3 (1/4 + 1/16 + 1/64 + 1/256 + 
1/1024 + ...) auch?

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


Lesenswert?

Stefan Helmert schrieb:
> Wenn ich die ursprüngliche Variante wähle und den Vektor erweitere,
> bringt das dann Nachteile?
Ich würde das einfach mal an einem Dreizeiler ausprobieren...

> wenn ich bspw. folgendes in VHDL machen will:
> y <= x/1024 * 345;
> dann sagt mir der Compiler, dass das Multiplikationsergebnis
> (std_logic_vector) länger ist als die Faktoren.
Klar: 16 Bit mal 16 bit = 32 Bit.

> Ich hatte allerdings gehofft, dass er die 2er-Potenz erkennt und zerlegt
Basierend auf welcher Annahme?

> So implementiert ist keine Erweiterung des Bitvektors nach links nötig.
> Warum verlangt der Compiler es trotzdem?
Weil er es nicht so macht! Der Compiler nimmt einfach deinen Vektor, 
schneidet die untersten 10 Bit ab (/1024) und multipliziert das mit 345. 
So steht das da: y <= x/1024 * 345;

BTW: was für ein Typ ist dein Vektor x?
Nimmst du zum Rechnen die alten Synopsys Libs?

von Stefan H. (Firma: dm2sh) (stefan_helmert)


Lesenswert?

Ja, ich habe signed. Stimmt bei negativen Werten geht das so nicht ganz 
auf. Da ist dann immer -1 Offset...

von J. S. (engineer) Benutzerseite


Lesenswert?

Also eigentlich müsste er bei -1024 ein bit weniger erzeugen (wollen), 
als bei 1024, weil die -1024 ja noch in den 10 Bit Vektor passen.

Ungeachtet dessen scheint mir das das eigentliche Problem:
>Der Compiler nimmt einfach deinen Vektor,
> schneidet die untersten 10 Bit ab (/1024) und multipliziert das mit 345.

Mit (x * 345 + 512 ) / 1024 müsste er es wie gewünscht anlegen.

von Stefan H. (Firma: dm2sh) (stefan_helmert)


Lesenswert?

J. S. schrieb:
>>Der Compiler nimmt einfach deinen Vektor,
>> schneidet die untersten 10 Bit ab (/1024) und multipliziert das mit 345.
>
> Mit (x * 345 + 512 ) / 1024 müsste er es wie gewünscht anlegen.

Er schneidet ja nicht ab. Er will ja die Erweiterung nach links. Nun ist 
das allerdings ziemlich Fehleranfällig, wenn man mit signed arbeitet. 
Durch das hin- und hergeschiebe unterschiedlichen Vektorlängen etc, 
passiert es schnell. Dass das Vorzeichen plötzlich weg ist und statt -1 
eine sehr große Zahl rauskommt. Das nervt.

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.