Forum: FPGA, VHDL & Co. VHDL: Zufallswerte für die Initialisierung erzeugen


von Florian (flori_n)


Lesenswert?

Moin,

ich sitze gerade an einem kleinen Problem.
In VHDL sollen für die Initialisierung, das heißt zur Synthesezeit, 
Zufallswerte erzeugt werden.
Es gibt die Standardprozedur uniform. Ist es möglich, die für die 
Initialisierung zu nutzen?
Unten steht ein kurzer Code dazu. Der funktioniert in der Simulation wie 
erwartet, aber bei der Synthese gibt es Probleme.
Quartus gibt den Fehler
"Error (10372): VHDL error at Top.vhdl(19): item cannot be assigned 
value
"
aus (Zeile 19 ist der Beginn der Funktionsdefinition).
Vivado ist bei einem ähnlichen Code (den ich jetzt nicht hier habe) 
etwas genauer und gibt an, dass irgendwo in math_real ein 
nicht-konstantes real-Signal benutzt wird, das nicht synthetisiert 
werden kann.
Ist es möglich, uniform oder eine andere Standardfunktion für 
Zufallszahlen in der Synthese zu nutzen?

Ich könnte ein LFSR benutzen oder die Zufallswerte extern erzeugen und 
im Code als Werte speichern. Darum geht es aber nicht.
Und noch ganz klar: Es geht nicht darum, einen Zufallszahlengenerator zu 
synthetisieren. Es sollen einfach nur bei der Synthese pseudozufällige 
Initialisierungswerte erzeugt werden.

[Bearbeitung: Es geht auch nicht darum, dass die Werte bei jedem 
Synthesedurchlauf unterschiedlich sind.]
1
library ieee;
2
3
use ieee.std_logic_1164.all;
4
use ieee.numeric_std.all;
5
use ieee.math_real.all;
6
7
entity Top is
8
  port(
9
    clk           : in  std_logic;
10
    data_select   : in  unsigned(2 downto 0);
11
    data_out      : out unsigned(7 downto 0) := (others => '0')
12
  );
13
end entity;
14
15
architecture rtl of Top is
16
  -- Seeds für Uniform, die Werte werden bei jedem 'Aufruf' geändert
17
  shared variable seed_1, seed_2  : natural := 1;
18
19
  impure function random return natural is
20
    variable rand_real  : real;
21
    variable result    : integer;
22
  begin
23
    -- rand_real ist ein Zufallswert zwischen 0 und 1
24
    uniform(seed_1, seed_2, rand_real);
25
    -- Auf den Bereich 0 bis 100 abbilden
26
    return integer(round(rand_real * 100.0));
27
  end function;
28
  
29
  -- Ein Arry, das mit Zufallswerten initialisiert werden soll.
30
  type array_t is array (0 to 2**data_select'length) of integer;
31
  constant const_array  : array_t := (others => random);
32
  
33
begin
34
35
  -- Damit nicht alles wegoptimiert wird
36
  data_out <= to_unsigned(const_array(to_integer(data_select)), data_out'length);
37
    
38
end architecture;

: Bearbeitet durch User
von Martin S. (strubi)


Lesenswert?

Die Synthese unterscheidet allgemein bei VHDL nicht zwischen 
'Ausfuehrung von VHDL' und 'Umsetzung in Hardware'. Leider.
Ob es in Verilog mit '$random' in der Initialisierung geht, weiss ich 
nicht.

Demnach ist dein Ansinnen in der Form vermutlich nicht umsetzbar, so 
dass es wohl das einfachere ist, die Initialwerte explizit mit einem 
Script zu generieren und dann die Synthese anzuwerfen. Oder du nutzt 
gemischt gut dokumentierte Mechanismen (je nach Vendor), um die 
Initialwerte nachtraeglich fuer entsprechende Location-Constraints ins 
BIT-File zu patchen.
Bei Xilinx gibt es sonst noch einige ICAP-Hacks zur 
in-system-Rekonfiguration, falls es um Serien-Produktion ginge.

Nachtrag: Was du noch probieren koenntest: Die Zufalls-Sequenz als 
Generic von der Synthese aus uebergeben.

: Bearbeitet durch User
von Florian (flori_n)


Lesenswert?

Martin S. schrieb:
> Die Synthese unterscheidet allgemein bei VHDL nicht zwischen
> 'Ausfuehrung von VHDL' und 'Umsetzung in Hardware'.
Grundsätzlich ist ja sowas wie
[vhdl]constant WIDTH : natural := 
integer(ceil(log2(real(DATA_RANGE))));[vhdl]
möglich, auch wenn die Formel nicht synthetisierbar ist. Deshalb habe 
ich mich gefragt, ob auch die Zufallsinitialisierung irgendwie geht.
Allerdings müsste ja für die Zufallswerte bei der Synthese tatsächlich 
eine Funktion mit Variablen ausgeführt werden. Daran scheitert es 
wahrscheinlich.

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.