Forum: FPGA, VHDL & Co. Const Berechnung: ** out of integer bounds


von Patrick B. (p51d)


Lesenswert?

Hallo allerseits

Ich habe mal wieder ein VHDL Problem: Ich möchte für einen DDS das 
Phasenincrement als Konstante berechnen.
1
constant PhaseInc0 : unsigned(31 downto 0) := to_unsigned((RTC_Frequency * 2**32) / fclk, 32);

Nun bekomme ich die Fehlermeldung
1
Result of operator ** is out of integer bounds.

Wie kann ich das Problem umgehen, so dass die Berechung VOR der 
Compilierung geschieht? Die Resultierende Zahl ist 838042399, was in 
einen 32Bit Vektor passt.

Hat jemand einen Tipp?

MFG
Patrick

von Programmierer (Gast)


Lesenswert?

Patrick B. schrieb:
> Die Resultierende Zahl ist 838042399, was in
> einen 32Bit Vektor passt.

Aber 2**32 ist 100000000 in Hex, was 33 Bits sind.

von Patrick B. (p51d)


Lesenswert?

Klar, aber wird in VHDL nicht zuerst der Ausdruck berechnet? Muss das 
Zielregister (hier PhaseInc0) so gross sein, dass die Zwischenresultate 
der Berechnung platz haben?

Die Berechnung geht so:
1
PhaseInc0 = 16MHz * 2^32 / 82MHz = 838042399 = 0x31F3831F
also Deutlich kleiner als der Maximale Bereich von 2^32.

: Bearbeitet durch User
von Duke Scarring (Gast)


Lesenswert?

Patrick B. schrieb:
> 16MHz * 2^32
> also Deutlich kleiner als der Maximale Bereich von 2^32.
Das sieht der Simulator/Synthesizer offenbar anders.

von Programmierer (Gast)


Lesenswert?

Patrick B. schrieb:
> Nun bekomme ich die Fehlermeldung
> Result of operator ** is out of integer bounds.

Die Fehlermeldung sagt doch aber, dass das Ergebnis des ** Operators 
außerhalb der Grenzen ist, und 2**32 ist nun mal größer als 32 Bits.

Und was soll mit einem Zwischenergebnis passieren, wenn es nicht in ein 
Register passt?

von alt_s (Gast)


Lesenswert?

is
1
RTC_Frequency
 kleiner als 1?
dann gehts natürlich nicht.
Wenn du dir sicher bist das
1
(RTC_Frequency * 2**32) / fclk
dann musst halt resizen, die funktion "schneidet" dir die vorderen Bits 
ab.
Am besten gleich noch über einen report überprüfen ob das wirklich so 
ist und nen Error beim synthetisieren schmeißen

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


Lesenswert?

alt_s schrieb:
> is RTC_Frequency kleiner als 1?
> dann gehts natürlich nicht.
Eher andersrum: nur wenn das kleiner als 0,5 wäre, würde die Zahl noch 
in den Integer passen.

Die Lösung wurde doch schon erwähnt: es geht vorher bereits schief, denn 
das 2**32 passt schon nicht mehr in einen 32-Bit-Integer. Und damit ist 
für den Synthesizer die Rechnung zu Ende. Das sagt er mit der 
Fehlermeldung.

Ich würde einfach mal mit einem 64-Bit unsigned Vektor rechnen und die 
unteren 32 Bit abschneiden...

von Patrick B. (p51d)


Lesenswert?

Aber es geht ja um Konstanten, nicht um Berechnungen zur laufzeit. Wird 
bei Konstanten das Resultat nicht zuerst berechnet und dann dem Register 
zugewiesen (ähnlich wie bei C und Defines)?

1
constant PhaseInc0_temp : unsigned(63 downto 0) := to_unsigned((RTC_Frequency * 2**32) / fclk, 64);
2
constant PhaseInc0 : unsigned(31 downto 0) := PhaseInc0_temp(31 downto 0);

Ergibt die gleiche Fehlermeldung. Selbst die Klammern anders platzieren 
hilft nicht (um die Rechnung mit einer anderen Reihenfolge 
durchzuführen).

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


Lesenswert?

Patrick B. schrieb:
> Ergibt die gleiche Fehlermeldung
Klar: 2 ist ein Integer...

von Patrick B. (p51d)


Lesenswert?

Ich steh glaube ich auf dem Schlauch: Wie kann ich dann das Probelm 
lösen? Jede Konstante einem 64Bit Vektor (std_logic oder unsigned) 
zuweisen, dann diese zum Rechnen verwenden, und am Schluss wieder 
zurückkürzen?

Geht das wirklich nicht einfacher?

von Nase (Gast)


Lesenswert?

Patrick B. schrieb:
> Aber es geht ja um Konstanten, nicht um Berechnungen zur laufzeit. Wird
> bei Konstanten das Resultat nicht zuerst berechnet und dann dem Register
> zugewiesen (ähnlich wie bei C und Defines)?

Jaa-haa.
Aber auch die Berechnung der Konstanten, bevor das Resultat dem Register 
zugewiesen wird, hat nur endlich viele Bits. Hier nämlich 32.

Vielleicht könntest du das in Gleitkomma berechnen, dann runden und dann 
dem Register zuweisen.

von Markus F. (mfro)


Lesenswert?

Schreib' das Rechenergebnis selber hin und einen Kommentar, was Du 
eigentlich machen wolltest.

Das Leben ist zu kurz, um sich mit so was länger aufzuhalten;).

von Thomas W. (donka)


Lesenswert?

Versuch es mal mit dem Umweg über real!
1
constant PhaseInc0 : unsigned(31 downto 0) := to_unsigned(integer( real(RTC_Frequency) * 2.0**32 / real(fclk)), 32);

von ope (Gast)


Lesenswert?

ich denke mal eher, das der Simulator bzw. das Synthesetool intern nur 
einen 32bit Wertebereich hat und daher die Meldung kommt und auch nicht 
umgangen werden kann. Zumindest Modelsim hatte früher diese (lästige) 
Begrenzung.

Olaf

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.