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


von Ralph H. (guru)


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?
1
IC11_12: 
2
  process(CSRFLPraeMode)
3
  begin
4
  if rising_edge(CSRFLPraeMode) then QIC11_12 <= QIC11_12 + 1 -- zählen..
5
     end if ;
6
end process IC11_12

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


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:
1
IC11_12: 
2
  process(CSRFLPraeMode,load,value)
3
  begin
4
  if load='1' then
5
     QIC11_12 <= value;
6
  elsif rising_edge(CSRFLPraeMode) then QIC11_12 <= QIC11_12 + 1 -- zählen..
7
     end if ;
8
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.

von Klaus F. (kfalser)


Lesenswert?

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

oder ein paar Grundlagen VHDL

von Ralph H. (guru)


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 :)

von Silvia A. (silvia)


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:
1
process (clock) begin
2
  if rising_edge (clock) then
3
              -- den Zähler laden
4
    if reset = 1 then 
5
      zaehler <= 0;
6
    end if;
7
    zaehler <= zaehler + 1;
8
  end if;
9
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_Flankenerkennung

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

von D. I. (Gast)


Lesenswert?

Silvia A. schrieb:
reibt man das so:
>
>
1
> process (clock) begin
2
>   if rising_edge (clock) then
3
>               -- den Zähler laden
4
>     if reset = 1 then
5
>       zähler <= 0;
6
>     end if;
7
>     zähler <= zähler + 1;
8
>   end if;
9
> end process;
10
>

Dann doch eher so:

>
1
> process (clock) begin
2
>   if rising_edge (clock) then
3
>               -- den Zähler laden
4
>     if reset = '1' then
5
>       zähler <= 0;
6
>     else
7
>       zähler <= zähler + 1;   
8
>     end if;
9
>   end if;
10
> end process;
11
>

von Silvia A. (silvia)


Lesenswert?

Ist schon spät
1
process (clock) begin
2
  if rising_edge (clock) then
3
              -- den Zähler laden
4
    if reset = '1' then 
5
      zaehler <= (others => '0');
6
    end if;
7
             -- den Zähler erhöhen
8
    zaehler <= zaehler + 1;
9
  end if;
10
end process;

ich hoffe jetzt ist es richtig

von Ralph H. (guru)


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 ?!

von D. I. (Gast)


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

von Klaus Falser (Gast)


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.

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


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.

von Silvia A. (silvia)


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:
1
process (clock,reset) begin
2
              -- den Zähler laden
3
    if reset = '1' then 
4
      zaehler <= (others => '0');
5
    end if;
6
             -- den Zähler erhöhen
7
  if rising_edge (clock) then
8
    zaehler <= zaehler + 1;
9
  end if;
10
end process;

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

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


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:
1
process (clock,reset) begin
2
              -- den Zähler laden
3
    if reset = '1' then 
4
      zaehler <= (others => '0');
5
    end if;
6
             -- den Zähler erhöhen
7
  if rising_edge (clock) then
8
    zaehler <= zaehler + 1;
9
  end if;
10
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...

von T. M. (xgcfx)


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
1
process(clock, reset) is
2
begin
3
  if(reset = '1') then
4
    zaehler <= (others => '0');
5
  elsif(rising_edge(clock)) then
6
    zaehler <= zaehler + 1;
7
  end if;
8
end process;

von Silvia A. (silvia)


Lesenswert?

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

grummel
1
process (clock) begin
2
  if rising_edge (clock) then
3
              -- den Zähler laden
4
    if reset = '1' then 
5
      zaehler <= (others => '0');
6
7
    else        -- den Zähler erhöhen
8
      zaehler <= zaehler + 1;
9
    end if;
10
  end if;
11
end process;

Um euch das denken abzunehmen, bin ich aber nicht hier

von Silvia A. (silvia)


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

von Ralph H. (guru)


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.

von Klaus Falser (Gast)


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.
1
process (clock,reset) begin
2
   -- den Zähler laden
3
   if reset = '1' then
4
       zaehler <= (others => '0');
5
   end if;
6
   -- den Zähler erhöhen
7
   if rising_edge (clock) then
8
     zaehler <= zaehler + 1;
9
   end if;
10
 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.

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


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.

von Silvia A. (silvia)


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")
1
-- Usage of Asynchronous resets may negatively impact FPGA resources 
2
-- and timing. In general faster and smaller FPGA designs will 
3
-- result from not using Asynchronous Resets. Please refer to 
4
-- the Synthesis and Simulation Design Guide for more information.
5
process (<clock>, <reset>) 
6
begin
7
   if <reset>='1' then 
8
      <count> <= (others => '0');
9
   elsif <clock>='1' and <clock>'event then
10
      if <clock_enable>='1' then
11
         <count> <= <count> + 1;
12
      end if;
13
   end if;
14
end process;

von T. M. (xgcfx)


Lesenswert?

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

von Silvia A. (silvia)


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

von Silvia A. (silvia)


Lesenswert?

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

von Anguel S. (anguel)


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.

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


Angehängte Dateien:

Lesenswert?

Hier noch mal zusammengefasst die verschiedenen Beschreibungen:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity AsyncReset is
5
    Port ( rst : in  STD_LOGIC;
6
           clk : in  STD_LOGIC;
7
           a1 : in  STD_LOGIC;
8
           a2 : in  STD_LOGIC;
9
           a3 : in  STD_LOGIC;
10
           b1 : out  STD_LOGIC;
11
           b2 : out  STD_LOGIC;
12
           b3 : out  STD_LOGIC);
13
end AsyncReset;
14
15
architecture Behavioral of AsyncReset is
16
17
begin
18
   process (clk,rst) begin
19
      if (rst='1') then         -- rst hat Vorrang
20
         b1 <= '0';
21
      elsif rising_edge(clk) then
22
         b1 <= a1;
23
      end if;
24
   end process;
25
26
   process (clk,rst) begin
27
      if rising_edge(clk) then
28
         b2 <= a2;
29
      end if;
30
      if (rst='1') then         -- rst hat Vorrang
31
         b2 <= '0';
32
      end if;
33
   end process;
34
35
   process (clk,rst) begin
36
      if (rst='1') then
37
         b3 <= '0';
38
      end if;
39
      if rising_edge(clk) then  -- clk hat Vorrang
40
         b3 <= a3;
41
      end if;
42
   end process;
43
44
end Behavioral;
Das gibt die Meldung
1
Signal b3 cannot be synthesized, bad synchronous description. The 
2
description style you are using to describe a synchronous element 
3
(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.

von Anguel S. (anguel)


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:
1
process (<clock>) 
2
begin
3
   if <clock>='1' and <clock>'event then
4
      if <reset>='1' then 
5
         <count> <= (others => '0');
6
      elsif <clock_enable>='1' then
7
         if <load_enable>='1' then
8
            <count> <= <input>;
9
         else 
10
            <count> <= <count> + 1;
11
         end if;
12
      end if;
13
   end if;
14
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.

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.