mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Xilinxer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity test is
    Port (   I: in std_logic_vector (3 downto 0);
        CLK: in std_logic;
        D: in std_logic;
        CS: in std_logic;
        Q: out std_logic);
end test;

architecture Behavioral of test is
signal data : std_logic_vector (3 downto 0);
signal output: std_logic;
begin
  load: process(cs)
  begin
    if cs = '0' and cs'event then
      data <= I;
    end if;
  end process;
  
  shift: process
  variable data_l : std_logic_vector(3 downto 0);
  begin
    wait until rising_edge(clk);
    
    data_l := data;
    
    if CS = '0' then
      while (CS = '0') loop
        Q <= data_l(3);
        data_l := data_l(2 downto 0) & D;
        wait until rising_edge(clk);
      end loop;
    else
      Q <= '0';
    end if;
    
  end process;
end Behavioral;

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Weltbester FPGA-Pongo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Vancouver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Xilinxer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
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;

Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
process (clk)
begin
  if rising_edge(clk) then
    for i in 3 downto 0 loop
      D(i) <= I(i);
    end loop;
  end if;
end process;

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

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

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

Bewertung
0 lesenswert
nicht 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.

Autor: Vancouver (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Ich würde das so schreiben:

for i in 0 to 3 generate

 process (clk) 
 begin
   if rising_edge(clk) then
       D(i) <= I(i);
   end if;
 end process;

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.

Autor: Da D. (dieter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vancouver schrieb:
> Ich würde das so schreiben:

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

Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Vancounver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.