www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Verständnisfrage Prozess


Autor: Ralph H. (guru)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mal ne Verständnisfrage zum Prozess in VHDL. Ich lieg doch 
richtig, dass die Anweisung nach dem "rising_edge" erst ausgeführt wird, 
NACHDEM dieses Ereignis auch eingetreten ist !?
D.h. alle bis zum letzten "end if" stehenden Anweisungen werden ERST 
NACH eintreffen des Ereignisses, also im Prozess, ausgeführt !?
Nun meine Frage, an welcher Stelle lade ich den Zähler ? Das muss in 
jedem Fall auch ohne das ein Ereignis eintrifft gehen. Ich denk ich 
müsste das außerhalb des Prozesses tun, oder?
IC11_12: 
  process(CSRFLPraeMode)
  begin
  if rising_edge(CSRFLPraeMode) then QIC11_12 <= QIC11_12 + 1 -- zählen..
     end if ;
end process IC11_12

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph H. schrieb:
> Ich lieg doch richtig, dass die Anweisung nach dem "rising_edge"
> erst ausgeführt wird, NACHDEM dieses Ereignis auch eingetreten ist !?
Nicht nachdem, sondern WEGEN des Ereignisses wird der Prozess neu 
berechnet (nicht "ausgeführt").

Ralph H. schrieb:
> Nun meine Frage, an welcher Stelle lade ich den Zähler ? Das muss in
> jedem Fall auch ohne das ein Ereignis eintrifft gehen.
Tja, weil du da jetzt ein Ereignis verwendest, das schon das 
Zählereignis selber ist, kannst du den Zähler da natürlich nicht laden. 
Pech...

Deshalb mußt du das hier asynchron machen:
IC11_12: 
  process(CSRFLPraeMode,load,value)
  begin
  if load='1' then
     QIC11_12 <= value;
  elsif rising_edge(CSRFLPraeMode) then QIC11_12 <= QIC11_12 + 1 -- zählen..
     end if ;
end process IC11_12

ABER....
warum machst du solche Konstrukte? Wofür soll der Code sein?
Wieviele Takte hast du in deinem Design (ein Takt ist das bei 
rising_edge() oder falling_edge() oder bei 'event)?

Sieh dir den Beitrag "vhdl-richtlinien f. synthese?" mal an.

> Ich denk ich müsste das außerhalb des Prozesses tun, oder?
Das geht nicht. Probiers aus.
Grund: dann hast du 2 Treiber auf ein Signal.

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Sieh dir den Beitrag "vhdl-richtlinien f. synthese?" mal an.

oder ein paar Grundlagen VHDL

Autor: Ralph H. (guru)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zunächst mal Danke Euch ! Ich hab mir die Beiträge angesehen, aber um 
ehrlich zu sein keine ANTWORT auf meine Frage erhalten dabei. Entweder 
bin ich zu blöd die da rauszulesen (sicher :D) oder wer weiß was auch 
immer..
Werd aber dennoch versuchen das irgendwie zu kapieren.

Lothar Miller schrieb:
> ABER....
> warum machst du solche Konstrukte? Wofür soll der Code sein?
Ein einfacher 4Bit-Zähler, der geladen wird, um ihn später auszulesen :)

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann versuch ich mich mal.
1) rising_edge - kennzeichnet grundsätzlich einen Takt. Flankenwechsel 
können damit nicht abgefragt werden.

2)
>Ich lieg doch
>richtig, dass die Anweisung nach dem "rising_edge" erst ausgeführt wird,
>NACHDEM dieses Ereignis auch eingetreten ist !?
Im Prinzip ja, allerdings ist die Zeitspanne theoretisch = 0

Zu beachten ist hier noch, das Signalzuweisungen nicht sofort sondern 
erst am ende des Prozesses ausgeführt werden.

3)
>alle bis zum letzten "end if" stehenden Anweisungen werden ERST
>NACH eintreffen des Ereignisses, also im Prozess, ausgeführt !?
Ja das ist richtig, allerdings gilt auch hier Zeitspanne theoretisch = 0

4) an welcher Stelle lade ich den Zähler ?

Lothar schrieb:
>Tja, weil du da jetzt ein Ereignis verwendest, das schon das
>Zählereignis selber ist, kannst du den Zähler da natürlich nicht laden.
Wieso geht es deiner Meinung nach nicht Synchron ?

Das Laden des Zählers entspricht einem Reset, auch wenn ein anderer wert 
als 0 geladen wird.

im allgemeinen schreibt man das so:
process (clock) begin
  if rising_edge (clock) then
              -- den Zähler laden
    if reset = 1 then 
      zaehler <= 0;
    end if;
    zaehler <= zaehler + 1;
  end if;
end process;

5)
Das muss in jedem Fall auch ohne das ein Ereignis eintrifft gehen.
Dein "Ereignis" ist der Systemtakt, ohne den Takt geht gar nichts

Das hier sollte helfen:
http://www.mikrocontroller.net/articles/VHDL_Flank...

6)
>Ich denk ich müsste das außerhalb des Prozesses tun, oder?
Nein, der Reset gehört zum Prozess

Autor: D. I. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
reibt man das so:
>
>
> process (clock) begin
>   if rising_edge (clock) then
>               -- den Zähler laden
>     if reset = 1 then
>       zähler <= 0;
>     end if;
>     zähler <= zähler + 1;
>   end if;
> end process;
> 

Dann doch eher so:

>
> process (clock) begin
>   if rising_edge (clock) then
>               -- den Zähler laden
>     if reset = '1' then
>       zähler <= 0;
>     else
>       zähler <= zähler + 1;   
>     end if;
>   end if;
> end process;
> 

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist schon spät
process (clock) begin
  if rising_edge (clock) then
              -- den Zähler laden
    if reset = '1' then 
      zaehler <= (others => '0');
    end if;
             -- den Zähler erhöhen
    zaehler <= zaehler + 1;
  end if;
end process;


ich hoffe jetzt ist es richtig

Autor: Ralph H. (guru)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
> Ist schon spät
Na ist doch OK.. ich soll ja mein Köpppl anstrengen ;-)

Danke Euch erstmal... nur zu meinem Verständnis, der Zähler wird immer 
auf 0 gestellt wenn Reset 1 ist, oder ?? Ich denke nicht !!
Aus meiner Sicht wird der Zähler doch erst rückgesetzt werden, wenn die 
nächste steigende Flanke von clock kommt UND Reset dann noch 1 ist, oder 
irre ich mich ? D.h. wenn kein CLOCK mehr kommt, wird auch der Zähler 
durch Reset 1 NICHT rückgesetzt ?!

Autor: D. I. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn kein Clock mehr kommt schauts eh düster aus in der Schaltung.

Und nein Silvia das ist nicht ok, da dein Zähler nie zurückgesetzt 
werden wird sondern immer hochzählen wird

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
> ich hoffe jetzt ist es richtig

Nein, so wirkt der Reset nicht.
Es zählt nämlich die letzte Zuweisung, und die ist immer
zaehler <= zaehler + 1;
unabhängig davon, ob der Reset-Pfad ausgeführt wurde oder nicht.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph H. schrieb:
> Aus meiner Sicht wird der Zähler doch erst rückgesetzt werden, wenn die
> nächste steigende Flanke von clock kommt UND Reset dann noch 1 ist
So ist es.

> D.h. wenn kein CLOCK mehr kommt, wird auch der Zähler
> durch Reset 1 NICHT rückgesetzt ?!
Auch richtig.

ABER.... (Obacht, jetzt kommts)
...in einem idealen (und auf jeden Fall in einem Anfänger-)Design gibt 
es genau 1 Takt. Der kommt von einem Taktgenerator, der aussen an das 
FPGA angeschlossen ist. Und der Takt kommt garantiert 1 mal, solange 
dieses Signal Reset aktiv ist! Denn dieser Reset selber ist ja auch ein 
Signal, das synchron (das ist das Schlüselwort) zum Takt gesetzt und 
zurückgesetzt wird. Und daher muß der Reset mindestens für 1 Taktzyklus 
lang aktiv sein.

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aus meiner Sicht wird der Zähler doch erst rückgesetzt werden, wenn die
>nächste steigende Flanke von clock kommt UND Reset dann noch 1 ist

Genau,
ach jetzt versteh ich erst warum Lothar das asynchron lösen wollte, denn 
du schriebst ja:
> Das muss in jedem Fall auch ohne das ein Ereignis eintrifft gehen

na der reset ist ja schnell asynchron gemacht:
process (clock,reset) begin
              -- den Zähler laden
    if reset = '1' then 
      zaehler <= (others => '0');
    end if;
             -- den Zähler erhöhen
  if rising_edge (clock) then
    zaehler <= zaehler + 1;
  end if;
end process;

allerdings solltest du nach Möglichkeit bei der synchronen Methode 
bleiben

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
> warum Lothar das asynchron lösen wollte
Ich wollte das nicht! Ralph wollte das!  ;-)

Für mich gelten erst mal meine Postulate (wobei ich mich mit der 
Begründung von Ausnahmen etwas leichter tue...;-)

Wenn sich Signale nur wegen einer Taktflanke des selben Takts ändern 
können, dann nennt man das ein synchrones (=zeitgleiches) Design. Und 
nur so funktionieren FPGA Designs zuverlässig. Allerdings kämpft Ralph 
mit CPLDs rum, da fallen mir gleich ein paar Ausreden ein, warum man 
"lokale" Takte nehmen könnte.....

BTW:
So ein Bauteil gibt es (eigentlich) nicht:
process (clock,reset) begin
              -- den Zähler laden
    if reset = '1' then 
      zaehler <= (others => '0');
    end if;
             -- den Zähler erhöhen
  if rising_edge (clock) then
    zaehler <= zaehler + 1;
  end if;
end process;
Wenn hier der Reset aktiv ist, und keine Flanke kommt, dann wird der 
Zähler zurückgesetzt (klar soweit). Wenn jetzt aber eine Flanke kommt, 
dann hat die Vorrang vor dem Reset (weil die if rising_edge() Abfrage im 
Prozess nach der Reset-Abfrage kommt) und der Zähler müsste um 1 
hochzählen, um sofort danach wieder zurückgesetzt zu werden...

Autor: T. M. (xgcfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
> process (clock,reset) begin
>               -- den Zähler laden
>     if reset = '1' then
>       zaehler <= (others => '0');
>     end if;
>              -- den Zähler erhöhen
>   if rising_edge (clock) then
>     zaehler <= zaehler + 1;
>   end if;
> end process;

Ich will ja nix sagen, aber IMHO solltest du vielleicht auch erstmal 
schauen, was und wie ein Prozess funktioniert. Auch diese Lösung ist 
falsch, es sollte mit asynchronem Reset folgendermaßen lauten
process(clock, reset) is
begin
  if(reset = '1') then
    zaehler <= (others => '0');
  elsif(rising_edge(clock)) then
    zaehler <= zaehler + 1;
  end if;
end process;

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Und nein Silvia das ist nicht ok, da dein Zähler nie zurückgesetzt
>werden wird sondern immer hochzählen wird

grummel
process (clock) begin
  if rising_edge (clock) then
              -- den Zähler laden
    if reset = '1' then 
      zaehler <= (others => '0');

    else        -- den Zähler erhöhen
      zaehler <= zaehler + 1;
    end if;
  end if;
end process;


Um euch das denken abzunehmen, bin ich aber nicht hier

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich will ja nix sagen, aber IMHO solltest du vielleicht auch erstmal
>schauen, was und wie ein Prozess funktioniert. Auch diese Lösung ist
>falsch, es sollte mit asynchronem Reset folgendermaßen lauten

Da widerspreche ich dir jetzt einfach mal, denn deine Klammern bewirken 
gar nix

Autor: Ralph H. (guru)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
> Da widerspreche ich dir jetzt einfach mal, denn deine Klammern bewirken
> gar nix
Hey nicht zanken !! und daran denken, ich will den Zähler mit nem 
anderen Wert als 0 laden !! da geht := others nicht !

Wenn ich so seh was ihr scheit, bin ich froh gefragt zu haben, denn es 
scheint ja doch nicht leicht zu sein.

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
>>Ich will ja nix sagen, aber IMHO solltest du vielleicht auch erstmal
>>schauen, was und wie ein Prozess funktioniert. Auch diese Lösung ist
>>falsch, es sollte mit asynchronem Reset folgendermaßen lauten
>
> Da widerspreche ich dir jetzt einfach mal, denn deine Klammern bewirken
> gar nix

Es geht nicht um die Klammern.
process (clock,reset) begin
   -- den Zähler laden
   if reset = '1' then
       zaehler <= (others => '0');
   end if;
   -- den Zähler erhöhen
   if rising_edge (clock) then
     zaehler <= zaehler + 1;
   end if;
 end process;
Diese Beschreibung entspricht nicht den üblicherweise vorhanden FFs, bei 
denen der Reset Vorrang hat und bei dem der Reset wirkt unabhängig davon 
on der Takt kommt.
Bei deiner Beschreibung oben wird der Zähler erhöht, auch wenn der Reset 
aktiv ist.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Silvia A. schrieb:
> denn deine Klammern bewirken gar nix
Aber das fehlende erste end if und das stattdessen verwendete elsif 
alles...  :-o
Dadurch erhält der (asynchrone) Reset genau die Priorität, die er im FF 
tatsächlich auch hat.

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>So ein Bauteil gibt es (eigentlich) nicht
>Wenn hier der Reset aktiv ist, und keine Flanke kommt, dann wird der
>Zähler zurückgesetzt (klar soweit). Wenn jetzt aber eine Flanke kommt,
>dann hat die Vorrang vor dem Reset (weil die if rising_edge() Abfrage im
>Prozess nach der Reset-Abfrage kommt) und der Zähler müsste um 1
>hochzählen, um sofort danach wieder zurückgesetzt zu werden...


Komisch, Xilinx beschreibt einen Zähler mit asynchronen Reset genauso.
(Mal abgesehen vom Clock enable und der anderen schreibweise für 
"rising_edge")

-- Usage of Asynchronous resets may negatively impact FPGA resources 
-- and timing. In general faster and smaller FPGA designs will 
-- result from not using Asynchronous Resets. Please refer to 
-- the Synthesis and Simulation Design Guide for more information.
process (<clock>, <reset>) 
begin
   if <reset>='1' then 
      <count> <= (others => '0');
   elsif <clock>='1' and <clock>'event then
      if <clock_enable>='1' then
         <count> <= <count> + 1;
      end if;
   end if;
end process;


Autor: T. M. (xgcfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will nicht zanken ;-P Wir sind hier ja nicht auf Arbeit, oder? ;-)

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber das fehlende erste end if und das stattdessen verwendete elsif
>alles...  :-o
>Dadurch erhält der (asynchrone) Reset genau die Priorität, die er im FF
>tatsächlich auch hat.

Habt ihr denn meinen Post von 22:06 nicht gesehen ? Da hatte ich meinen 
Fehler schon korrigiert

>Hey nicht zanken !! und daran denken, ich will den Zähler mit nem
>anderen Wert als 0 laden !! da geht := others nicht !
Tja jetzt kommt zum vorschein, das std_logic nicht zum rechnen gedacht 
ist, denn eine zuweisung wie    zaehler <= 23  funktioniert nicht.


>Wenn ich so seh was ihr scheit, bin ich froh gefragt zu haben, denn es
>scheint ja doch nicht leicht zu sein.
Lach , ne vhdl ist nicht einfach

Autor: Silvia A. (silvia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich will nicht zanken ;-P Wir sind hier ja nicht auf Arbeit, oder? ;-)
Du verlierst eh, schon allein weil ich eine Frau bin

Autor: Anguel S. (anguel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDL ist keine Sprache wie C, in der man die Konstrukte nach Belieben 
optimieren oder umändern sollte. Man soll sich bei HDLs am besten strikt 
an die Templates halten, denn letztendlich sollen diese Templates 
richtig von der Software erkannt werden und in HW umgesetzt werden.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch mal zusammengefasst die verschiedenen Beschreibungen:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity AsyncReset is
    Port ( rst : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           a1 : in  STD_LOGIC;
           a2 : in  STD_LOGIC;
           a3 : in  STD_LOGIC;
           b1 : out  STD_LOGIC;
           b2 : out  STD_LOGIC;
           b3 : out  STD_LOGIC);
end AsyncReset;

architecture Behavioral of AsyncReset is

begin
   process (clk,rst) begin
      if (rst='1') then         -- rst hat Vorrang
         b1 <= '0';
      elsif rising_edge(clk) then
         b1 <= a1;
      end if;
   end process;

   process (clk,rst) begin
      if rising_edge(clk) then
         b2 <= a2;
      end if;
      if (rst='1') then         -- rst hat Vorrang
         b2 <= '0';
      end if;
   end process;

   process (clk,rst) begin
      if (rst='1') then
         b3 <= '0';
      end if;
      if rising_edge(clk) then  -- clk hat Vorrang
         b3 <= a3;
      end if;
   end process;

end Behavioral;
Das gibt die Meldung
Signal b3 cannot be synthesized, bad synchronous description. The 
description style you are using to describe a synchronous element 
(register, memory, etc.) is not supported in the current software release.

Wenn dieser Prozess dann auskommentiert wird, ergeben sich wie erwartet 
2 FFs mit asynchronem Reset.

Autor: Anguel S. (anguel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph H. schrieb:
> Ein einfacher 4Bit-Zähler, der geladen wird, um ihn später auszulesen :)

Man starte ISE Project Navigator und clicke auf die gelbe Glühlampe in 
der Toolbar.
Dann VHDL -> Synthesis Constructs -> Coding Examples -> Counters -> /w 
Load, CE and Synch Active High Reset wählen, weil der die meisten 
Features hat und weil synchrones Design (zumindest bei FPGAs immer 
vorzuziehen ist) und schon hat man den richtigen Template-Code:
process (<clock>) 
begin
   if <clock>='1' and <clock>'event then
      if <reset>='1' then 
         <count> <= (others => '0');
      elsif <clock_enable>='1' then
         if <load_enable>='1' then
            <count> <= <input>;
         else 
            <count> <= <count> + 1;
         end if;
      end if;
   end if;
end process;

Falls man möchte, kann man den jetzt etwas vereinfachen, falls man etwas 
nicht braucht. Oder man schaut sich mal die anderen Counter-Templates 
an.

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.