Forum: FPGA, VHDL & Co. "Preprozessor" Berechnungen in VHDL möglich?


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich möchte ein Array mit Konstanten füllen.
Diese Konstanten sollen möglichst automatisch berechnet und befüllt 
werden.

Dazu habe ich momentan sowas:
1
  type t_boundaries_x is array (0 to led_count_x) of integer range 0 to display_width + 10;
2
  type t_boundaries_y is array (0 to led_count_y) of integer range 0 to display_heigth + 10;
3
4
5
  signal boundaries_x : t_boundaries_x;
6
  signal boundaries_y : t_boundaries_y;
7
....
8
  genboundsX :
9
  for I in 1 to led_count_x generate
10
    boundaries_x(I-1) <= ((display_width) / led_count_x + 1) * I;
11
  end generate;
12
13
  genboundsY :
14
  for I in 1 to led_count_y generate
15
    boundaries_y(I-1) <= ((display_heigth) / led_count_y + 1) * I;
16
  end generate;

Funktioniert grundsätzlich ganz gut. Aber...
Ich hätte gerne die Berechnung mit Komma.

Daher: die Berechnung: ((display_width) / led_count_x + 1) * I

Sollte mit hoher Genauigkeit durchgeführt werden.
Jedoch nur vor der Syntheze und nicht im FPGA selbst.

Gibt es dazu eine entsprechende Möglichkeit?

Danke

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


Lesenswert?

Holger K. schrieb:
> Gibt es dazu eine entsprechende Möglichkeit?
Nimm das math_real Package und die darin enthaltene Konvertierung zum 
integer. Etwa so wie dort zum Schluss die Tabelle berechnet wird:
http://www.lothar-miller.de/s9y/categories/31-DDFS

> Sollte mit hoher Genauigkeit durchgeführt werden.
Generell ist ein 32-Bit Float wegen der Mantisse, die nur 24 Bits hat, 
ungenauer als ein 32 Bit Integer. Allerdings hat der Float dank des 
Exponenten mehr Dynamik...

: Bearbeitet durch Moderator
von VHDL hotline (Gast)


Lesenswert?

Ich verstehe die Frage in Richtung der Syntax die man braucht, um das 
Array per Präprozessor zu initialisieren.

Schreibe die Berechnung in einer VHDL function und weise die dann bei 
der Signaldefinition zu.
1
function meine_berechnung (display_width: integer, led_count: integer) return t_boundaries_x;
2
3
...
4
5
constant boundaries_x : t_boundaries_x := meine_berechnung(display_width, led_count);

von Holger K. (holgerkraehe)


Lesenswert?

Vielen Dank für eure Antworten.

Wird das dann ins FPGA synthetisiert?
Ich möchte eigentlich die Berechnung quasi auf dem PC durchführen und 
das Array mittels aggregat funktion (generate section) vorfüllen so, 
dass das synthesetool nur noch konstanten vorfindet, ohne kommas.

Die Kommas sollen nur der Berechnung auf dem PC dienen.

von Christoph Z. (christophz)


Lesenswert?

VHDL hotline schrieb im Beitrag #6064190:
> Schreibe die Berechnung in einer VHDL function und weise die dann bei
> der Signaldefinition zu.
> function meine_berechnung (display_width: integer, led_count: integer)
> return t_boundaries_x;
>
> ...
>
> constant boundaries_x : t_boundaries_x :=
> meine_berechnung(display_width, led_count);

Die Berechnung dieser Konstanten wird vom Synthesetool bzw. dem 
Simulator gemacht. Es gibt keinen Präprozessor.

Das Place & Route Tool bekommt vom Synthesetool eine Netzliste wo nur 
noch der Wert der Konstante drinsteht.

Um zu kontrollieren, was da so berechnet wurde, kannst du diesen Wert in 
deiner Function auch ausgeben lassen (landet dann in der Konsole bzw. 
dem Logfile) ohne das FPGA Ressourcen dazu nötig werden:
1
report "The display boundry in X direction is:" & LF & integer'image(boundaries_x) severity note;

von Holger K. (holgerkraehe)


Lesenswert?

Perfekt! Vielen Dank :)

von Markus F. (mfro)


Lesenswert?

In VHDL gibt es den Begriff der "static expression".

Das klingt zwar so ähnlich wie das C-Schlüsselwort, ist aber etwas 
anderes (eher vergleichbar zu constexpr in C++).

Letzendlich heisst es nichts anderes, als daß ein VHDL-Konstrukt 
(eigentlich) nicht synthesitierbare Elemente enthalten darf, solange es 
so geschrieben wird, daß diese zur Synthesezeit vollständig (in 
synthesitierbare Elemente) evaluiert werden können:
1
architecture rtl of sintab is
2
    type sinus_table_type is array(natural range <>) of signed(31 downto 0);
3
    function sinus_table(start_value, end_value, step : real) return  sinus_table_type is
4
        constant table_size     : natural := 
5
                                  integer(ieee.math_real.ceil(
6
                                          end_value - start_value) / step);
7
        variable sintab : sinus_table_type(0 to table_size - 1);
8
    begin
9
        for i in sintab'low to sintab'high loop
10
            sintab(i) := to_signed(integer(
11
                              ieee.math_real.sin(start_value + real(i) * step) *
12
                              32767.0), sintab(i)'length);
13
        end loop;
14
        return sintab;
15
    end function sinus_table;
16
17
    function isin(sintab : sinus_table_type; us : signed) return signed is
18
        variable ret : signed(us'range);
19
    begin
20
        ret := sintab(to_integer(us mod sintab'length));
21
        return ret;
22
    end function isin;
23
24
    constant PI             : real := 3.1415926;
25
    constant stab           : sinus_table_type := sinus_table(0.0, 2.0 * PI, 0.01);
26
begin
27
    calc : process
28
    begin
29
        wait until rising_edge(clk);
30
        res <= isin(stab, arg);
31
    end process calc;
32
end architecture rtl;

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

was hab' ich denn da geschrieben?

synthetisierbar heisst das Wort ;)

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.