Forum: FPGA, VHDL & Co. Wait statement in a procedure is not accepted.


von Xilinxer (Gast)


Lesenswert?

Hallo,

ich versuche mich gerade an VHDL und möchte probeweise ein 
Shift-Register synthetisieren, z.B. wie man es von einem hc595 kennt. 
Bei folgendem Code kriege ich den Error, obwohl in meinem Lehrbuch z.B. 
auch ein wait until in einer Schleife eines Prozesses verwendet wird:

ERROR:Xst:825 - "C:/Users/xilinx/Desktop/Projects/Test/led.vhd" line 34: 
Wait statement in a procedure is not accepted.

Wo liegt mein Fehler? Ich verwende Xilinx ISE 14.7.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity test is
5
    Port (   I: in std_logic_vector (3 downto 0);
6
        CLK: in std_logic;
7
        D: in std_logic;
8
        CS: in std_logic;
9
        Q: out std_logic);
10
end test;
11
12
architecture Behavioral of test is
13
signal data : std_logic_vector (3 downto 0);
14
signal output: std_logic;
15
begin
16
  load: process(cs)
17
  begin
18
    if cs = '0' and cs'event then
19
      data <= I;
20
    end if;
21
  end process;
22
  
23
  shift: process
24
  variable data_l : std_logic_vector(3 downto 0);
25
  begin
26
    wait until rising_edge(clk);
27
    
28
    data_l := data;
29
    
30
    if CS = '0' then
31
      while (CS = '0') loop
32
        Q <= data_l(3);
33
        data_l := data_l(2 downto 0) & D;
34
        wait until rising_edge(clk);
35
      end loop;
36
    else
37
      Q <= '0';
38
    end if;
39
    
40
  end process;
41
end Behavioral;

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


Lesenswert?

Xilinxer schrieb:
> obwohl in meinem Lehrbuch z.B. auch ein wait until in einer Schleife
> eines Prozesses verwendet wird
Höchstens 5% des simulierbaren VHDL können synthetisiert werden.  Welche 
das sind, steht im Handbuch zum Synthesizer.

Das, was du da gepostet hast, kann nur simuliert, aber nicht 
synthetisiert werden.

von Dussel (Gast)


Lesenswert?

Xilinxer schrieb:
> Bei folgendem Code kriege ich den Error, obwohl in meinem Lehrbuch z.B.
> auch ein wait until in einer Schleife eines Prozesses verwendet wird:
Eins vielleicht. Aber dein Prozess enthält zwei Waits und das geht nicht 
mehr.

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


Lesenswert?

Dussel schrieb:
> Aber dein Prozess enthält zwei Waits und das geht nicht mehr.
Doch, sogar mehrere wait gehen, aber eben nur ohne Bedingungen:
http://www.lothar-miller.de/s9y/archives/47-wait-im-Prozess.html

Das eigentliche Problem hier ist das Übliche: es wird versucht  mit VHDL 
zu "programmieren". Also die sequentielle Denkweise aus der 
Mikrocontroller-Ecke anstelle von Hardwarebeschreibung anzuwenden. Und 
dann kommt eben eine for-Schleife dorthin, obwohl in VHDL eine Schleife 
prinzipiell parallele Hardware erzeugt.

: Bearbeitet durch Moderator
von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Lothar M. schrieb:
> Höchstens 5% des simulierbaren VHDL können synthetisiert werden.

Naja, so schlimm ist es nun auch nicht ;-)

Aber  es stimmt irgendwo.

Dass wait statements nicht synthesizierbar sind, sollte klar sein, denn 
warten "tut" ja nur der Simulator. Klar, könnte auch das Synthesetool 
etwas warten, aber das brächte wohl nicht viel.

von Vancouver (Gast)


Lesenswert?

Die Fehlermeldung ist etwas irreführend:

"Wait statement in a procedure is not accepted."

Aber es gibt hier keine procedure, sondern nur zwei Prozesse.

Der Kern des Problems ist das Wait-Statement in der while-Schleife. Es 
ist wichtig zu verstehen, dass alle Arten von Schleifen in VHDL zur 
Synthesezeit ausgewertet werden. Das Ergebnis einer loop muss damit 
schon feststehen, wenn die Struktur (also die Netzliste) erzeugt wird. 
Mit dem Wait-Statement innerhalb der While-Loop wird der Synthesizer 
angewiesen, die Schleifenauswertung zu unterbrechen bis eine Taktflanke 
kommt, was natürlich keinen Sinn ergibt.

von Xilinxer (Gast)


Lesenswert?

Ich glaube*, ich habe verstanden. Stimmt es, dass die Synthese eines 
Prozesses dafür sorgt, dass am Ende dieses alle zugewiesenen Signale ihr 
Ergebnis bekommen und dass alle Angaben, die ich im Prozess mache 
parallel ausgeführt/syntetisiert werden?

Wenn ich folgendes schreibe, dann wird dieses in vier parallele Zweige 
synthesisiert (als Beispiel) und mit der steigenden Flanke das Ergebnis 
übernommen? Das sollten hier dann doch nur vier einfache D-Flipflops 
sein oder?
1
process: (clk)
2
begin
3
  for i in 3 downto 0 loop
4
    if rising_edge(clk) then
5
      D(i) <= I(i);
6
    end if;
7
  end loop;
8
end process;

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Xilinxer schrieb:
> Ich glaube*, ich habe verstanden. Stimmt es, dass die Synthese
> eines
> Prozesses dafür sorgt, dass am Ende dieses alle zugewiesenen Signale ihr
> Ergebnis bekommen und dass alle Angaben, die ich im Prozess mache
> parallel ausgeführt/syntetisiert werden?
>
> Wenn ich folgendes schreibe, dann wird dieses in vier parallele Zweige
> synthesisiert (als Beispiel) und mit der steigenden Flanke das Ergebnis
> übernommen? Das sollten hier dann doch nur vier einfache D-Flipflops
> sein oder?
> process: (clk)
> begin
>   for i in 3 downto 0 loop
>     if rising_edge(clk) then
>       D(i) <= I(i);
>     end if;
>   end loop;
> end process;

Jein ...

Das würde man so schreiben:
1
process (clk)
2
begin
3
  if rising_edge(clk) then
4
    for i in 3 downto 0 loop
5
      D(i) <= I(i);
6
    end loop;
7
  end if;
8
end process;

Mal davon abgesehen, dass man für so ein Beispiel keine loop benötigt^^

Aber ansonsten ja ... Das ist äquivalent mit
1
process (clk)
2
begin
3
  if rising_edge(clk) then
4
    D(3) <= I(3);
5
    D(2) <= I(2);
6
    D(1) <= I(1);
7
    D(0) <= I(0);
8
  end if;
9
end process;

: Bearbeitet durch User
Beitrag #5422115 wurde vom Autor gelöscht.
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mampf F. schrieb:
> Das würde man so schreiben: ...
Oder ganz ohne Prozess so:
D <= I when rising_edge(clk);

Xilinxer schrieb:
> Das sollten hier dann doch nur vier einfache D-Flipflops sein oder?
Ja. So ist es. Du kannst das auch einfach mal synthetisieren und den 
erzeugen RTL-Schaltplan ansehen...

> Stimmt es, dass die Synthese eines Prozesses dafür sorgt, dass am Ende
> dieses alle zugewiesenen Signale ihr Ergebnis bekommen
Es ist in VHDL so definiert, dass Signale erst beim Ende des Prozesses 
oder beim nächsten wait den zuletzt zugewiesenen Wert übernehmen und bis 
dahin den "alten" Wert behalten. Dass diese Definition eingehalten wird, 
dafür sorgt der Synthesizer.

von Vancouver (Gast)


Lesenswert?

Ich würde das so schreiben:

1
for i in 0 to 3 generate
2
3
 process (clk) 
4
 begin
5
   if rising_edge(clk) then
6
       D(i) <= I(i);
7
   end if;
8
 end process;
9
10
end generate;


Der Prozess beschreibt ein einzelnes D-FF und die generate-Schleife 
drumherum sagt, wie oft das erzeugt werden soll. Ist etwas mehr 
Schreibarbeit aber damit hast Du eine klare Trennung zwischen dem 
funktionalen und dem strukturellen Teil. Die anderen Vorschläge sind 
aber genauso richtig.

von Da D. (dieter)


Lesenswert?

Vancouver schrieb:
> Ich würde das so schreiben:

Damit die Zählvariable I den größtmöglichen Gültigkeitsbereich hat?

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Da D. schrieb:
> Vancouver schrieb:
>> Ich würde das so schreiben:
>
> Damit die Zählvariable I den größtmöglichen Gültigkeitsbereich hat?

Hätte ich so auch nicht gemacht ... generate verwende ich nur, wenn ich 
mehrere Instancen eines Cores erzeugen möchte :)

von Vancounver (Gast)


Lesenswert?

Da D. schrieb:
> Damit die Zählvariable I den größtmöglichen Gültigkeitsbereich hat?

Der Gültigkeitsbereich ist innerhalb der Schleife... ist das ein 
Problem?

> ... generate verwende ich nur, wenn ich mehrere Instancen eines Cores erzeugen 
möchte :)

Naja, das ist ja nichts anderes, nur dass die Komponente direkt in der 
Schleife definiert wird (sozusagen eine Lambda-Komponente :-). 
Grundsätzlich kannst Du jeden indizierten Ausdruck in eine 
generate-Schleife packen, nicht nur Instanziierungen.

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.