Const Berechnung: ** out of integer bounds

OP #4352185
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
OP #4352242
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.
Gast #4352251
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?
Gast #4352263
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
Moderator (Firma: Titel) Persönliche Seite #4352290
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...
OP #4352321
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).
Gast #4352384
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.
Gast #4366784
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren