"Preprozessor" Berechnungen in VHDL möglich?

OP #6064146
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
Moderator (Firma: Titel) Persönliche Seite #6064176
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...
Gast #6064190
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);
OP #6064203
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.
#6064297
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;
#6064446
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;

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.