Wait statement in a procedure is not accepted.

Gast #5421361
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;
Moderator (Firma: Titel) Persönliche Seite #5421620
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.
Gast #5421707
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.
Gast #5421923
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.
Gast #5422100
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;
Persönliche Seite #5422106
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;
Beitrag #5422115 wurde von einem Moderator gelöscht.
Moderator (Firma: Titel) Persönliche Seite #5422117
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.
Gast #5422215
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.
Gast #5422522
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.

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