Forum: FPGA, VHDL & Co. VHDL - For-Schleife


von Problemator (Gast)


Lesenswert?

Hallo Leute,

habe ein Problem:

Ich versuche Tasten zu entprellen indem ich bei fallender Flanke einfach 
eine Weile warte und dann nochmal überpüfe, ob der Zustand immernoch 0 
ist und dann zählt die Taste als gedrückt.

Das Warten läuft mit einer for Schleife.

Ich simuliere das ganze mit ISIM, aber stelle fest, dass die gesamte for 
Schleife einfach übersprungen wird? Warum?
1
  CButton: process(button, clk1)
2
    begin
3
      if button'event and button='0' then
4
          for i in 1 to 100 loop              
5
              if clk1'event and clk1='1' then
6
                tmp <= i;
7
              end if;
8
              if button='0' and i=100 and pushed='1' then
9
                  button_control <= not(button_control);
10
              end if;
11
          end loop;
12
      end if;
13
  end process;

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


Lesenswert?

Problemator schrieb:
> Das Warten läuft mit einer for Schleife.
Hast du vorher mal C programmiert?
Und willst jetzt mit der selben Denkweise Hardware beschreiben?
ROTFL... :-D

VHDL ist keine Programmiersprache sondern eine Beschreibungssprache. 
Du mußt dir also denken: wie würde ich so eine Verzögerung mit Logik und 
Flipflops aufbauen. Und das dann beschreiben...

> Ich simuliere das ganze mit ISIM, aber stelle fest, dass die gesamte for
> Schleife einfach übersprungen wird? Warum?
Weil eine for-Schleife in VHDL in der Zeit 0 durchlaufen wird.


Zu deiner Frage:
Eine for-Schleife in VHDL bedeutet nur, dass der Block innerhalb der
for-Schleife eine bestimmte Anzahl oft dupliziert wird.
Deinen Code könntest du also auch so schreiben:
1
  CButton: process(button, clk1)
2
    begin
3
      if button'event and button='0' then
4
5
              if clk1'event and clk1='1' then
6
                tmp <= i;
7
              end if;
8
              if button='0' and i=100 and pushed='1' then
9
                  button_control <= not(button_control);
10
              end if;
11
12
              if clk1'event and clk1='1' then
13
                tmp <= i;
14
              end if;
15
              if button='0' and i=100 and pushed='1' then
16
                  button_control <= not(button_control);
17
              end if;
18
19
              if clk1'event and clk1='1' then
20
                tmp <= i;
21
              end if;
22
              if button='0' and i=100 and pushed='1' then
23
                  button_control <= not(button_control);
24
              end if;
25
:
26
: und so fort, das Ganze insgesamt 101 mal...
27
:
28
              if clk1'event and clk1='1' then
29
                tmp <= i;
30
              end if;
31
              if button='0' and i=100 and pushed='1' then
32
                  button_control <= not(button_control);
33
              end if;
34
35
      end if;
36
  end process;



Davon abgesehen:
1
  CButton: process(button, clk1)
2
    begin
3
      if button'event and button='0' then
4
          for i in 1 to 100 loop              
5
              if clk1'event and clk1='1' then
6
                tmp <= i;                                 --- Signale werden erst am Prozessende zugewiesen
7
              end if;
8
              if button='0' and i=100 and pushed='1' then
9
                  button_control <= not(button_control);  --- Signale werden erst am Prozessende zugewiesen
10
              end if;
11
          end loop;
12
      end if;
13
  end process;
Hier steht also eigentlich das da:
1
  CButton: process(button, clk1)
2
    begin
3
      if button'event and button='0' then
4
          if clk1'event and clk1='1' then
5
             tmp <= 100;                      -- am Prozessende hat i den Wert 100
6
          end if;
7
          if button='0' and pushed='1' then   -- and i=100  unnötig, Grund s.o.
8
             button_control <= not(button_control);  
9
          end if;
10
      end if;
11
  end process;



Davon abgesehen:
1
  CButton: process(button, clk1)
2
    begin
3
      if button'event and button='0' then
4
         :
5
         if clk1'event and clk1='1' then  
6
            :
Ein Double-Clock-Flipflop? Sowas gibt es nicht.



Ein Tipp:
Du hast eigentlich alles falsch gemacht, was man in 10 Zeilen falsch 
machen kann. Sieh dir doch einfach mal an, wie Andere das machen. Lies 
dir ein Buch zu den Grundlagen programmierbarer Logik durch...
Z.B.  VHDL-Synthese von Reichardt&Schwarz

von Problemator (Gast)


Lesenswert?

Danke, du hast wohlmöglich Recht...

Kann mir jemand erklären, warum die wait-Anweisung nicht funktioniert?

Ich möchte doch einfach nur, dass das System nach der ersten fallenden 
Flanke wartet und dann nochmal überprüft ob ich low oder high bin. So 
möchte ich halt einfach die Taste entprellen.

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


Lesenswert?

Problemator schrieb:
> Kann mir jemand erklären, warum die wait-Anweisung nicht funktioniert?
Die funktioniert schon.
BTW: Welche wait-Anweisung?

> Ich möchte doch einfach nur, dass das System nach der ersten fallenden
> Flanke wartet und dann nochmal überprüft ob ich low oder high bin.
Deine Denkweise ist falsch.

> So möchte ich halt einfach die Taste entprellen.
So geht das "einfach":
http://www.lothar-miller.de/s9y/categories/5-Entprellung

von Sebastian G. (jaseg)


Lesenswert?

Nur "wait until" kann synthetisiert werden, "wait for" ist nur bei 
Simulationen hilfreich.

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


Lesenswert?

Sebastian G. schrieb:
> Nur "wait until" kann synthetisiert werden
Und nur wenig Bedingungen, die nach dem until kommen. Eigentlich kann 
die Synthese mit wait until nur Flanken auswerten...

Das hier könnte z.B. leicht Probleme machen:
1
   wait until a='0' and b='1' and cnt=1200;

von Problemator (Gast)


Lesenswert?

Irgendwie bin ich jetzt völlig durcheinander...

Kann mir denn keiner eine gute Einführung geben, wie ich das mit dem 
Entprellen machen kann?

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


Lesenswert?

Problemator schrieb:
> Kann mir denn keiner eine gute Einführung geben, wie ich das mit dem
> Entprellen machen kann?
Hast du was übersehen im 
Beitrag "Re: VHDL - For-Schleife"

Problemator schrieb:
> Ich versuche Tasten zu entprellen indem ich bei fallender Flanke einfach
> eine Weile warte und dann nochmal überpüfe, ob der Zustand immernoch 0
> ist und dann zählt die Taste als gedrückt.
Ok, hier eine Lösung speziell für dich ...
Vorab nochmal die Postulate:
1
Ein Design (insbesondere ein Anfängerdesign) hat genau 1 Takt, 
2
der immer auf dieselbe Flanke aktiv ist. 
3
Es gibt keinen (und schon gar keinen asynchronen) Reset.
4
Externe Signale werden über 2 Flipflops einsynchronisiert.
5
Jede Abweichung von diesen Regeln muß fundiert begründet werden können.
Alles klar soweit? Ich gehe davon aus, dass der clk1 nicht noch einen 
Bruder namens clk2 hat, oder so?
Des weiteren gehe ich (mangels genauerer Problem- und 
Aufgabenbeschreibung) davon aus, dass der clk1 von einem Taktgenerator 
kommt und ca. 50MHz hat.

So denn:
1
signal prescaler : integer range 0 to 499999 := 0; -- Vorteiler 10ms 
2
signal inputsr   : std_logic_vector(3 downto 0);
3
:
4
:
5
 process begin
6
   wait until rising_edge(clk); -- der Takt: es kann nur einen geben.
7
   if (prescaler=499999) then
8
      prescaler <= 0;
9
      if (inputsr = "0111") then -- steigende Flanke
10
         riseedge<='1'; 
11
      else
12
         riseedge <= '0';
13
      end if;
14
      -- von rechts Eintakten
15
      inputsr <= inputsr(2 downto 0) & input;
16
   else
17
      prescaler<=prescaler+1;
18
   end if;
19
 end process
20
21
 process (clk) begin
22
   if rising_edge(clk) then    -- der Takt: es kann nur einen geben.
23
      if (risedge='1') then
24
         -- Taste gedrückt, mach was
25
      end if;
26
   end if;
27
 end process;
28
:

von Problemator (Gast)


Lesenswert?

Kannst du das Design auch kurz mal erklären, oder zumindest das 
Grundprinzip. Ich komme nämlich nicht ganz dahinter :-(

von Problemator (Gast)


Lesenswert?

Lothar Miller schrieb:
> -- von rechts Eintakten
>       inputsr <= inputsr(2 downto 0) & input;

Was passiert hier?

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


Lesenswert?

Problemator schrieb:
> Was passiert hier?
Stichwort Concatenation Operator "&"
Hier wird der Eingang input rechts an die drei unteren Bits vom 
inputsr angehängt, und diese 4 Bits dann dem inputsr zugewiesen.

Schönes Wochenende noch... ;-)

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.