+ Operator nicht auf reals definiert?

Gast #3231641
Lesenswert?

Hallo liebe VHDL Experten,

ich habe folgendes Problem:
Ich möchte gerne zur Compilezeit ein Array beschreiben, so ähnlich wie 
hier:
http://www.lothar-miller.de/s9y/archives/37-DDFS-mit-BROM.html

Der Inhalt der LUT soll das Ergebnis der Mitternachtsformel werden, also 
mit Division und Wurzel.

Nun wollte ich etwas Testcode schreiben, der folgendermaßen aussieht:

lutgeneration: for i in 0 to 65535 generate
  lookuptable(i) <= std_logic_vector(to_unsigned(3.25 + 5.43, 16));
end generate;

Damit bekomme ich aber die Fehlermeldung:
Error (10327): VHDL error at LUTBIG.vhd(40): can't determine definition 
of operator ""+"" -- found 0 possible definitions

Es scheint also so als sei der Plus Operator nicht auf zwei reele 
Operanden definiert, was ja bedeuten würde ich kann in vhdl keine 
kommzahlen addieren?

wenn ich folgendes mache:
  lookuptable(i) <= std_logic_vector(to_unsigned(integer(3.25) + 
integer(5.43), 16));

wird fehlerfrei compiliert.

Kann mir da jemand nen Tipp geben? Habe auch schon die Beschreibung der 
packages auf:
http://www.csee.umbc.edu/portal/help/VHDL/stdpkg.html
durchforstet, aber leider nix gefunden.

Folgende packages habe ich eingebunden:

library ieee;
use ieee.std_logic_1164.all;
--use ieee.std_logic_unsigned.all;
use IEEE.math_real.all;
use ieee.numeric_std.all;

Gruß

Johannes
Moderator (Firma: Titel) Persönliche Seite #3231821
Lesenswert?

Johannes Scherle schrieb:
> Es scheint also so als sei der Plus Operator nicht auf zwei reele
> Operanden definiert, was ja bedeuten würde ich kann in vhdl keine
> kommzahlen addieren?
Logisch kannst du real-Zahlen addieren. Aber to_unsigned kann keine 
real-Zahlen konvertieren. Deshalb muss (wie beschrieben) der Cast auf 
integer() mit rein...

Ich vermute, du hast schon mal C programmiert, und dich an die 
implizite Umwandlerei zwischen den Zahlenformaten gewöhnt. Sowas gibt 
es bei VHDL nicht, du musst jedesmal explizit sagen, was wie nach 
wohin gewandelt werden soll.

BTW:
Weil der (überladene) '+' Operator auch "nur" eine Funktion ist, 
könntest du deine Addition auch mal als Funktionsaufruf schreiben:
1
lookuptable(i) <= std_logic_vector(to_unsigned(integer("+"(3.25,5.43)),16));
Gast #3231877
Lesenswert?

hallo,

vielen dank für die schnelle Antwort. Wenn ich aber vor dem unsigned 
cast auf integer caste gehen wir aber ja die Nachkommastellen verloren 
oder?

Mal eine generelle Frage zur effizienten Realisierung einer Look Up 
Table. Ich möchte eine sehr große LUT realisieren: 2^16 - 1 Einträge mit 
einer Wortbreite von 16 Bit.

Ich habe das bisher mit einem when construct (Stack Overflow des 
Parsers), einem with Select construct (hat funktioniert aber sehr lange 
zum kompilieren gedauert) und eben einem Array zur Compilezeit versucht 
(hat auch funktioniert aber extrem viele Logikblöcke verbraucht). Gibt 
es noch eine elegantere Möglichkeit die schnell kompiliert und wenig 
Logikblöcke verbraucht?

Ich programmiere übrigens ein DE0-Nano. Weiß jemand ob das überhaupt 
diese BRAM Elemente zur Verfügung stellt? Finde dazu leider nix im 
Datenblatt :-(.

Viele Grüße

Johannes
Gast #3231903
Lesenswert?

Wie stellst Du Dir denn eine 16 Bit Darstellung Deiner Real Zahlen vor? 
Wie sähe beispielsweise der standard_logic_vector (SLV) aus Deinem 
Beispiel aus?

Durch das Speichern als SLV nimmst Du automatisch eine Konvertierung 
vor. Ob dies nun eine Fixpoint Zahl mit Nachkommastellen ist oder ein 
ganzzahliger Integer Wert, solltest Du Dir vorher überlegen.
Gast #3231915
Lesenswert?

Jürgen P. schrieb:
> Wie stellst Du Dir denn eine 16 Bit Darstellung Deiner Real Zahlen
> vor?
> Wie sähe beispielsweise der standard_logic_vector (SLV) aus Deinem
> Beispiel aus?
>
> Durch das Speichern als SLV nimmst Du automatisch eine Konvertierung
> vor. Ob dies nun eine Fixpoint Zahl mit Nachkommastellen ist oder ein
> ganzzahliger Integer Wert, solltest Du Dir vorher überlegen.

mhm ok verstehe das Problem. Ok, das da oben war vielleicht ein 
schlechtes Beispiel. Mich hatte nur diese Fehlermeldung irritiert.

Aber tatsächlich, wie werden denn reals in vhdl repräsentiert? Als 
single oder double precision?
Moderator (Firma: Titel) Persönliche Seite #3231948
Lesenswert?

Johannes Scherle schrieb:
> Aber tatsächlich, wie werden denn reals in vhdl repräsentiert? Als
> single oder double precision?
Im Standard ist lediglich der "Mindestbereich" von -1E38 bis +1E38 
festgelegt, aber nicht, mit welcher Genauigkeit die Darstellung 
erfolgen muss. Du musst also für dienen Simulator und deinen Synthesizer 
da nochmal genau nachlesen, wie hier der Datentyp real implementiert 
ist. Meist wird für float aber die auf dem Entwicklungsrechner 
tatsächlich vorhandene Zahlendarstellung einer Fließkommazahl 
verwendet...
Gast #3232546
Lesenswert?

Also ein FPGA hat von hause aus keine FPU. Genause wie es keine CPU hat.
Wenn du nur Fließkommazahle in eine LUT schreiben willst ist das OK. Da 
nimmst du dann halt 32Bit (SP) oderr mehr wie du willst. Um den aufbau 
mußt du dich aber selber kümmer Vorzeichen Mantisse und Exponent. Ob in 
der LUT nun nen 32Bit Integer oder 32 einzelen Bits oder zwei 9Bit und 
ein 14Bit stehen ist dem FPGA vollkommen egal.
Wenn du damit rechnen willst musßt du ihm schon erklären wie.
Zum rechnen mit Fließkommazahlen brauchst du ne primitive FPU im FPGA.
Fixed Point ist da schon einfacher. Aber auch Fließkomma ist nicht so 
schwer.
Ne multiplikation ist halt ne einfache Multiplikation und ne Adition für 
die Exponenten. Das geht aber nicht von alleine.

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