VHDL Entprellung-Fehler

Gast #4166831
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;
Moderator (Firma: Titel) Persönliche Seite #4167036
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"
Gast #4167045
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.
Gast #4167103
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.
Gast #4167106
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").
Gast #4167114
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.
Gast #4167121
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?
Moderator (Firma: Titel) Persönliche Seite #4167142
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.
Gast #4167155
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.
Moderator (Firma: Titel) Persönliche Seite #4167175
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;
Moderator (Firma: Titel) Persönliche Seite #4167363
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
Gast #4167418
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren