Forum: FPGA, VHDL & Co. VHDL Entprellung-Fehler


von Uwe_24 (Gast)


Lesenswert?

Hallo zusammen,

ich versuche mich gerade in das FPGA und VHDL Thema einzuarbeiten und 
bin noch am Anfang.
Die Aufgabe lautet im Moment, eine Entprellung so zu entwerfen, dass bei 
einem Tastendruck ein Zähler hochzählt (10ms) und dann erst den 
Tastendruck "freigibt".
Es gibt in meinem vhdl-code 2 Zähler.. der eine wird ohne Entprellung 
angesteuert und der zweite mit. Beide Werte der Zähler möchte ich auf 
den Siebensegmentanzeigen ausgeben.
Nur leider funktioniert dieser Code nicht da immer wahllos dieselben 
Werte angezeigt werden (Wert für beide Zähler gleich). IUch hoffe ihr 
könnt mir ein paar Tipps/Vorschläge geben was ich falsch mache.

Hier, das was ich bis jetzt habe.
Gruß Uwe

OutSec,OutMin, OutSecD, OutSecMin sind jeweils meine Einer- & 
Zehnerstellen der beiden Zähler
1
library ieee;
2
use ieee.std_logic_1164.all; -- wg. des Datentyps std_logic_vector
3
use ieee.numeric_std.all;
4
5
entity fpga is
6
  port (
7
    clock_50        :in std_logic;
8
    key : in std_logic_vector  (3 downto 0); -- Drucktaster 
9
    hex7, hex6, hex5, hex4, hex3, hex2, hex1, hex0:
10
     out std_logic_vector (6 downto 0)     -- 7S-Anzeigen
11
  );
12
end fpga;
13
14
architecture Verhalten of fpga is
15
  signal outSec          : std_logic_vector(3 downto 0);
16
  signal outMin          : std_logic_vector(3 downto 0);
17
  signal outSecD        : std_logic_vector(3 downto 0);
18
  signal outMinD         : std_logic_vector(3 downto 0);
19
  signal key_debounce    : std_logic;
20
  
21
  begin
22
    
23
    v  : entity work.Debounce    port map (key(1), clock_50, key_debounce);
24
    z0 : entity work.Zaehler    port map (key(1), clock_50, outSec, outMin);
25
    z1 : entity work.Zaehler2    port map (key_debounce, clock_50, outSecD, outMinD);
26
    d0 : entity work.Dec       port map (outSec,  hex0);
27
    d1 : entity work.Dec       port map (outMin,  hex1);
28
    d2 : entity work.Dec       port map (outSecD, hex2);
29
    d3:  entity work.Dec          port map (outMinD, hex3);
30
    
31
end Verhalten;

Entprellung:
1
library ieee;
2
  use ieee.std_logic_1164.all;
3
  use ieee.numeric_std.all;
4
  use ieee.std_logic_unsigned.all;
5
6
entity Debounce is
7
  port (    
8
    key_in     :in std_logic;
9
    clk        :in std_logic;
10
    key_deb    :out std_logic
11
    );
12
end Debounce;
13
14
architecture Verhalten of Debounce is
15
16
  signal key_old     : std_logic;
17
  signal key_now     : std_logic;
18
  signal result     : std_logic;
19
  signal counter     : std_logic_vector (19 downto 0) :=(others => '0');
20
  
21
begin
22
  
23
  result <= key_now xor key_old;
24
25
  process (all) begin
26
    if rising_edge(clk) then 
27
    
28
      key_now <= key_in;
29
      key_old <= key_now;
30
31
      if (result = '1') then
32
        counter <= (others => '0');  
33
      elsif(counter(19) = '0') then 
34
        counter <= counter + 1;
35
      else 
36
        key_deb <= key_old;
37
      end if;
38
      
39
     end if;
40
    
41
   end process;
42
end architecture;

Zähler (Beide identisch)
1
library ieee;
2
  use ieee.std_logic_1164.all;
3
  use ieee.numeric_std.all;
4
  use ieee.std_logic_unsigned.all;
5
6
entity Zaehler is
7
  port (    
8
    k          :in std_logic;
9
    clk        :in std_logic;
10
    outSec     :out std_logic_vector (3 downto 0);
11
    outMin     :out std_logic_vector (3 downto 0)
12
    );
13
end Zaehler;
14
15
architecture Verhalten of Zaehler is
16
17
  signal einerStelle  : natural range 0 to 9;
18
  signal zehnerStelle : natural range 0 to 9;
19
  
20
begin
21
22
  process (all) begin
23
    if rising_edge(clk) then 
24
      if (k = '0') then
25
        
26
        if (einerStelle = 9) then
27
          einerStelle <= 0;
28
          if (zehnerStelle = 9) then
29
            zehnerStelle <= 0;
30
          else
31
            zehnerStelle <= zehnerStelle + 1;
32
          end if;
33
        else 
34
          einerStelle <= einerStelle + 1;
35
        end if;
36
      
37
      else
38
          einerStelle  <= 0;
39
          zehnerStelle <= 0;
40
      end if;
41
   end if;  
42
   end process;
43
 
44
   outSec <= std_logic_vector(to_unsigned(einerStelle,4));
45
   outMin <= std_logic_vector(to_unsigned(zehnerStelle,4));
46
   
47
end architecture;

Decoder zum ausgeben von Dezimalzahlen
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity Dec is
5
  port (c:    in  std_logic_vector(3 downto 0);
6
      hex:  out std_logic_vector(6 downto 0)
7
  );
8
end Dec;
9
10
architecture Verhalten of Dec is
11
begin  
12
  process (all) begin
13
    
14
    --Hier steuert der Decoder bei bestimmten Eingangswertem die LED-Anzeigen an
15
    case c is
16
      when "0000" => hex <= "1000000";
17
      when "0001" => hex <= "1111001";
18
      when "0010" => hex <= "0100100";
19
      when "0011" => hex <= "0110000";
20
      when "0100" => hex <= "0011001";
21
      when "0101" => hex <= "0010010";
22
      when "0110" => hex <= "0000010";
23
      when "0111" => hex <= "1111000";
24
      when "1000" => hex <= "0000000";
25
      when "1001" => hex <= "0010000";
26
      when others => hex <= "1111111";
27
    end case;
28
29
    ----------------------------------------------------------------------------   
30
  end process;
31
end Verhalten;

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


Lesenswert?

Uwe_24 schrieb:
> Nur leider funktioniert dieser Code nicht da immer wahllos dieselben
> Werte angezeigt werden
Gerade so ein Design ist geradezu prädestiniert für eine Simulation. Was 
zeigt deine an?

>  use ieee.numeric_std.all;
>  use ieee.std_logic_unsigned.all;
Das ist kein gute Idee. Da sind dann ein paar Typdefinitionen doppelt 
vorhanden, das kann ins Auge gehen wie im 
Beitrag "Re: std_logic_vector auf integer umwandeln" erklärt.
Siehe dazu auch den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

: Bearbeitet durch Moderator
von Lattice User (Gast)


Lesenswert?

Der Taster taugt halt etwas, oder ist wie auf manchen Entwicklungsboard 
bereits entprellt. Dann hat du als potentielle Abweichung nur noch den 
Zufall wenn du exakt eine Clockflanke erwischt, so dass der eine Zähler 
es schon sieht und er andere nicht mehr.

Übrigens sollte auch für den nicht entprellten Zähler der Taster 
einsynchronisiert werden, sonst spinnt der Zähler gelegentlich total.

von Uwe_24 (Gast)


Lesenswert?

Lothar Miller schrieb:
> Uwe_24 schrieb:
>> Nur leider funktioniert dieser Code nicht da immer wahllos dieselben
>> Werte angezeigt werden
> Gerade so ein Design ist geradezu prädestiniert für eine Simulation. Was
> zeigt deine an?
>
-Bis jetzt habe ich das noch nicht simuliert..da das bis jetzt in der 
Uni auch noch nie gemacht wurde, muss ich mich da ersteinmal 
einarbeiten. Werde ich aber bald machen müssen! Danke

>>  use ieee.numeric_std.all;
>>  use ieee.std_logic_unsigned.all;
> Das ist kein gute Idee. Da sind dann ein paar Typdefinitionen doppelt
> vorhanden, das kann ins Auge gehen wie im
> Beitrag "Re: std_logic_vector auf integer umwandeln" erklärt.
> Siehe dazu auch den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

Danke für den Tipp - habe das auch schon in meinen Files angeglichen!
Ändert leider nichts daran dass mein vhdl Code noch nicht will.

von Uwe_24 (Gast)


Lesenswert?

Lattice User schrieb:
> Der Taster taugt halt etwas, oder ist wie auf manchen
> Entwicklungsboard
> bereits entprellt. Dann hat du als potentielle Abweichung nur noch den
> Zufall wenn du exakt eine Clockflanke erwischt, so dass der eine Zähler
> es schon sieht und er andere nicht mehr.
>
> Übrigens sollte auch für den nicht entprellten Zähler der Taster
> einsynchronisiert werden, sonst spinnt der Zähler gelegentlich total.

Sollte dann bei einem Entprellten Taster nicht auf dem LCD "1" angezeigt 
werden. Mit meinem Zähler zähle ich ja sozusagen das "Bouncing" des 
Tasters, also wie oft die Taktflanke zu viel erkannt wurde. Bei einem 
Entprellten Taster müsste dies doch 1 sein? Liege ich da richtig?
Im Moment zeigen aber beide Zähler eine hohe Zahl an (Beide "85-90").

von Lattice User (Gast)


Lesenswert?

Uwe_24 schrieb:

>
> Sollte dann bei einem Entprellten Taster nicht auf dem LCD "1" angezeigt
> werden. Mit meinem Zähler zähle ich ja sozusagen das "Bouncing" des
> Tasters, also wie oft die Taktflanke zu viel erkannt wurde.

Nein, du mißt die Zeit in Einheite vom 20 ns wie lange der Taster 
gedrückt ist. In deinem Zähler ist keine Flankenerkennung.

von Lattice User (Gast)


Lesenswert?

Lattice User schrieb:

>
> Nein, du mißt die Zeit in Einheite vom 20 ns wie lange der Taster
> gedrückt ist. In deinem Zähler ist keine Flankenerkennung.

In einer Simulation waäre die das sofort ins Gesicht gesprungen!

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


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> eine Simulation. Was zeigt deine an?
Ich sehe da nur Nonsens...

: Bearbeitet durch Moderator
von Uwe_24 (Gast)


Lesenswert?

Lattice User schrieb:
> Uwe_24 schrieb:
>
>>
>> Sollte dann bei einem Entprellten Taster nicht auf dem LCD "1" angezeigt
>> werden. Mit meinem Zähler zähle ich ja sozusagen das "Bouncing" des
>> Tasters, also wie oft die Taktflanke zu viel erkannt wurde.
>
> Nein, du mißt die Zeit in Einheite vom 20 ns wie lange der Taster
> gedrückt ist. In deinem Zähler ist keine Flankenerkennung.

Lattice User schrieb:
> Lattice User schrieb:
>
>>
>> Nein, du mißt die Zeit in Einheite vom 20 ns wie lange der Taster
>> gedrückt ist. In deinem Zähler ist keine Flankenerkennung.
>
> In einer Simulation waäre die das sofort ins Gesicht gesprungen!


Oh dann bin ich auf dem gaanz falschen Fuß unterwegs! Die 
Flankenerkennung ist dass was ich brauche. Ich muss einen Zähler per 
Tastendruck inkrementieren, eInen mit Entprellung und einen ohne.. und 
dabei sollen die Flanken gezählt werden. Dankeschön .. ich tu mich da 
einfach noch sehr schwer :/ Hat jemand zufällig einen Link wo das gut 
erklärt ist?

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


Lesenswert?

Uwe_24 schrieb:
> Hat jemand zufällig einen Link wo das gut erklärt ist?
Erst Entprellen:
http://www.lothar-miller.de/s9y/categories/5-Entprellung
Dann die Flanke finden:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung

von Der L. (vhdl-neuling)


Lesenswert?

Ich würde Dir das Thema "Einsynchronisieren von externen Signalen" 
empfehlen, ebenso das Thema "was macht 'rising_edge(x)'" und schon wirst 
Du damit zwei große Schritte weiter sein. :)

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


Lesenswert?

Der Lars schrieb:
> ebenso das Thema "was macht 'rising_edge(x)'"
Und ebenso das Thema:
Es gibt in einem Anfängerdesign nur 1 Takt. Der kommt vom Quarz.

Oder andersrum:
Niemals(!) wird auf einen Taster oder sonst ein Signal ein 
'rising_edge() angesetzt.

Und das ist eigentlich auch nur Faulheit:
1
  process (all) begin
2
    if rising_edge(clk) then 
3
    ...
Wenn schon nur der Takt im Prozess verwendet wird, dann schreibe auch 
nur den Takt in die Sensitivliste. Dieses (all) ist ziemlich die 
blödsinnigste Erweiterung, die es gibt.

von Olga (Gast)


Lesenswert?

Lothar Miller schrieb:
> Wenn schon nur der Takt im Prozess verwendet wird, dann schreibe auch
> nur den Takt in die Sensitivliste. Dieses (all) ist ziemlich die
> blödsinnigste Erweiterung, die es gibt.

Bei allem Respekt, aber das ist eine äußerst sinnvolle Erweiterung. 
Warum soll sich der Entwickler mit etwas auseinandersetzen, was der 
Compiler (und Synthesizer) viel besser kann? Außerdem ist die 
Sensisivitylist eine ständige Fehlerquelle, die man mit (all) einfach 
nicht hat. Es bring absolut 0,0 Vorteil statt (all) dort irgendwelche 
Signale einzutragen.

von Der L. (vhdl-neuling)


Lesenswert?

Olga schrieb:
> Warum soll sich der Entwickler mit etwas auseinandersetzen, was der
> Compiler (und Synthesizer) viel besser kann?

Vielleicht weil der Compiler es nicht besser können sollte :-o

Ich finde der Entwickler sollte sich jede mögliche Überprüfbarkeit 
seines Codes erhalten. Aber das ist natürlich Geschmackssache :-)

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


Lesenswert?

Olga schrieb:
> Warum soll sich der Entwickler mit etwas auseinandersetzen, was der
> Compiler (und Synthesizer) viel besser kann?
Weil er dann auch mal mitdenken muss?

Oder siehst du den Fehler hier sofort?
1
  process (all) begin
2
    if rising_edge(clk) then 
3
      if (k = '0') then
4
        if (einerStelle = 9) then
5
          einerStelle <= 0;
6
          if (zehnerStelle = 9) then
7
            zehnerStelle <= 0;
8
          else
9
            zehnerStelle <= zehnerStelle + 1;
10
          end if;
11
        end if;
12
      else 
13
        einerStelle <= einerStelle + 1;
14
      end if;
15
      else
16
        einerStelle  <= reloadEiner;
17
        zehnerStelle <= reloadZehner;
18
    end if;  
19
  end process;

: Bearbeitet durch Moderator
von Olga (Gast)


Lesenswert?

Der Lars schrieb:
> Vielleicht weil der Compiler es nicht besser können sollte :-o

Ok, dann sind wir ganz schnell wieder beim Assembler. Ein ziemlich 
sinnloses Argument.

Lothar Miller schrieb:
> Weil er dann auch mal mitdenken muss?

Noch sinnloser. Der Compiler ist dazu da, mir stupide denkarbeit, die 
mich vom eigentlichen Entwickeln abhält, abzunehmen.

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


Lesenswert?

Sagen wir mal so: einem Anfänger schadet es nicht, über die 
Sensitivliste nachzudenken. Im einem synchronen Prozess, in dem nur der 
CLK eine Rolle spielen darf, ist nicht mal Tipparbeit gespart...

Aber das Pro-contra "all" ist hier im Thread eh nicht primär das Thema. 
Und einen synchronen Prozess schreibe ich sowieso ohne Sensitivliste: 
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html

: Bearbeitet durch Moderator
von Sigi (Gast)


Lesenswert?

Lothar Miller schrieb:
> Oder siehst du den Fehler hier sofort?  process (all) begin
>     if rising_edge(clk) then
>       if (k = '0') then
>         if (einerStelle = 9) then
>           einerStelle <= 0;
>           if (zehnerStelle = 9) then
>             zehnerStelle <= 0;
>           else
>             zehnerStelle <= zehnerStelle + 1;
>           end if;
>         end if;
>       else
>         einerStelle <= einerStelle + 1;
>       end if;
>       else
>         einerStelle  <= reloadEiner;
>         zehnerStelle <= reloadZehner;
>     end if;
>   end process;

Abgesehen von dem "..(all).." und scheinbarer semantischer
Fehler, hast du da noch etwas anderes übersehen? Meine
erste Einschätzung ist, dass das der Synthesizer nicht
übersetzen kann, zumindestens nicht der aller Hersteller.

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


Lesenswert?

Sigi schrieb:
> Meine erste Einschätzung ist, dass das der Synthesizer nicht übersetzen
> kann, zumindestens nicht der aller Hersteller.
Du liegst richtig. Oder andersrum: wenn er es könnte, dann würden nur 
die letzten beiden Zuweisungen übrig bleiben, und es wäre weit&breit 
kein Takt im Design...

: Bearbeitet durch Moderator
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.