Forum: FPGA, VHDL & Co. Taktflankenauswertung auf Buttons


von guest (Gast)


Lesenswert?

Hallo,

ich würde gerne wissen ob man grundsätzlich nur Taktflankenauswertungen 
auf Clocks vornehmen sollte, oder ob dies auch theoretisch auf bspw. 
Buttons angewendet werden kann.
Ich hatte einen kleinen Zähler aufgesetzt der auf die steigende Flanke 
des Buttons das Ergebnis erhöht, jedoch bekomme ich, abhängig von den 
ausgewählten Buttons, warnings oder errors.
Stellt sich mir halt die Frage ob man dies prinzipiell sein lassen 
sollte oder ob dies andere Gründe hat.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity toplevel is
6
  port(    RST : in std_logic;
7
      BTN2 : in std_logic;
8
      LED1 : out std_logic;
9
      LED2 : out std_logic;
10
      LED3 : out std_logic;
11
      LED4 : out std_logic);
12
end toplevel;
13
14
architecture Behavioral of toplevel is
15
  signal LED_TMP : unsigned(3 downto 0);
16
17
begin
18
  
19
  BTN_CNT_UP : process(BTN2, RST)
20
  begin  
21
    if(RST = '1') then
22
      LED_TMP <= "0000";
23
    elsif(BTN2'event and BTN2 = '1') then
24
      LED_TMP <= LED_TMP + 1;
25
    end if;
26
  end process;
27
28
  
29
  LED1 <= LED_TMP(0);
30
  LED2 <= LED_TMP(1);
31
  LED3 <= LED_TMP(2);
32
  LED4 <= LED_TMP(3);
33
34
end Behavioral;

Bei Nutzung von BTN1:

Warning:Place:619 - This design is using a Side-BUFG site due to 
placement constraints on a BUFG, DCM, clock IOB or the
   loads of these components. It is recommended that Top and Bottom BUFG 
sites be used instead of Side-BUFG sites
   whenever possible because they can reach every clock region on the 
device. Side-BUFG sites can reach only clock
   regions on the same side of the device and also preclude the use of 
certain Top and Bottom BUFGs in the same clock
   region.

Bei Nutzung von BTN2:

(Zwar kann man den Error mit NET "BTN2" CLOCK_DEDICATED_ROUTE = FALSE; 
beseitigen, jedoch schränke ich mich dann anderweitig ein)

Error: Place:1018 - A clock IOB / clock component pair have been found 
that are not placed at an optimal clock IOB /
   clock site pair. The clock component <BTN2_BUFGP/BUFG> is placed at 
site <BUFGMUX_X1Y10>. The IO component <BTN2> is
   placed at site <PAD287>.  This will not allow the use of the fast 
path between the IO and the Clock buffer. If this
   sub optimal condition is acceptable for this design, you may use the 
CLOCK_DEDICATED_ROUTE constraint in the .ucf
   file to demote this message to a WARNING and allow your design to 
continue. However, the use of this override is
   highly discouraged as it may lead to very poor timing results. It is 
recommended that this error condition be
   corrected in the design. A list of all the COMP.PINs used in this 
clock placement rule is listed below. These
   examples can be used directly in the .ucf file to override this clock 
rule.
   < NET "BTN2" CLOCK_DEDICATED_ROUTE = FALSE; >

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


Lesenswert?

> Stellt sich mir halt die Frage ob man dies prinzipiell sein lassen
> sollte
JA. So werden Flanken von irgendwelchen asynchronen Eingängen niemals 
abgefragt!
Ein ideales Anfängerdesign (und sowas mchst du offenbar) sieht so aus:
Genau 1 Takt (der kommt von einem Oszillator und hat so um 50MHz)
und genau 0 Resets.
Flanken von externen Signalen werden so ausgewertet, dass die erst mal 
einsynchronisiert werden und dann ein vorher-nachher Vergleich die 
Flanke ermittelt:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
Sieh dir mal die Lauflichterorgie auf meiner HP an:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html

> oder ob dies andere Gründe hat.
Du kannst nicht mit jedem x-beliebigen Pin auf ein Taktnetz (abhängig 
vom FPGA geht das mit Einschränkungen). Mit dem Aufheben der Forderung 
nach einem Taktnetz (CLOCK_DEDICATED_ROUTE = FALSE) erlaubst du den 
Tools, einen Takt von irgendwoher auf beliebigen Umwegen zu einem 
Flipflop zu verdrahten. Das wirst du einsehen: das geht gern mal ins 
Auge.

von guest (Gast)


Lesenswert?

Besten Dank soweit,

also ich hab mir dein Code für das Einsynchronisieren mal angeschaut und 
ist eigentlich auch gut verständlich.
Nun erhalte ich ja durch den Vorher, Nachhervergleich in sr(3) und sr(2) 
einen 1-Takt langen Ausschlag von rise oder fall. Ist es nun möglich auf 
diese beiden Signale das Attribut event anzuwenden da sie ja synchron 
zur clock laufen? Oder liegt ich da jetzt wieder falsch? Ist für mich 
noch ein bisschen schwammig das Ganze, weil " x'event and x = '1' " für 
mich lediglich ein Mittel war, irgendeine Taktflanke zu bestimmen. 
Wahrscheinlich fehlt mir da noch der Bezug zur Hardware.
Und wieso hast du den Vector sr 4 Bit breit gemacht? 2 Bit würden doch 
auch langen?
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity edge_detect is
5
  port (async_sig : in std_logic;
6
        clk       : in std_logic;
7
        rise      : out std_logic;
8
        fall      : out std_logic);
9
end;
10
11
architecture RTL of edge_detect is
12
begin
13
  process
14
    variable sr : std_logic_vector (3 downto 0) := "0000";
15
  begin
16
    wait until rising_edge(clk);
17
    -- Flanken erkennen
18
    rise <= not sr(3) and sr(2);
19
    fall <= not sr(2) and sr(3);
20
    -- Eingang in Schieberegister einlesen
21
    sr := sr(2 downto 0) & async_sig;
22
  end process;
23
end architecture;

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


Lesenswert?

guest schrieb:
> Und wieso hast du den Vector sr 4 Bit breit gemacht? 2 Bit würden doch
> auch langen?
Okok. Ich lasse mich auf 3 Bits herunterhandeln: 2 zum 
Einsynchronisieren und das 3. zur Flankenunterscheidung.

> Ist es nun möglich auf diese beiden Signale das Attribut event
> anzuwenden da sie ja synchron zur clock laufen?
> Oder liegt ich da jetzt wieder falsch?
Halten wirs wie bei Terminators: es kann nur EINEN geben. Gemeint ist 
damit der Takt. Wenn irgendwo ein 'event oder ein rising_edge() oder ein 
falling_edge() auftaucht, dann steht das in Idealfall immer das selbe 
Signal dabei.

>    variable sr : std_logic_vector (3 downto 0) := "0000";
Vergiss diese Anwendung von Variablen:
Mach Variablen niemals speichernd, du wirst damit (füher oder später) 
dein blaues Wunder erleben.
Dazu mehr im Beitrag "Variable vs Signal"

> Wahrscheinlich fehlt mir da noch der Bezug zur Hardware.
Kauf (oder leih) dir das Buch "VHDL-Synthese" von Reichardt/Schwarz. Da 
werden dir ein paar Lichtlein aufgehen...

von guest (Gast)


Lesenswert?

> Okok. Ich lasse mich auf 3 Bits herunterhandeln: 2 zum
> Einsynchronisieren und das 3. zur Flankenunterscheidung.

Die Flankenunterscheidung wird doch in den Signalen rise und fall
abgelegt?

Aber gut, dann werd ich mich auf den EINEN beschränken. Stellt sich mir 
nur noch eine Frage. Die Flankenunterscheidung, z.B. rise bleibt ja 
einen ganzen Takt auf 1.
Letztendlich war es ja mein Ziel bei der Flanke aufwärts zu Zählen, so 
quasi in der Art:
(wobei BTN1_RISE die manuelle Flankenauswertung ist)
1
SET_OUTPUT : process(BTN1_RISE, CLK, RST)
2
  begin
3
    if(RST = '1') then
4
      LED_TMP <= "0000";
5
    elsif(BTN1_RISE = '1' and BTN1_RISE'event) then
6
      LED_TMP <= LED_TMP + 1;
7
    end if;
8
  end process;

Da es aber nur EINEN gibt, bleibt mir ja bestenfalls die folgende 
Möglichkeit, die aber auch nicht das gewünschte Ergebnis liefert
1
elsif(BTN1_RISE = '1') then

Mir fehlt also lediglich eine Möglichkeit nun, wie auch beim 'event, 
einmalig in den elsif Zweig bei einer Flanke einzusteigen.

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


Lesenswert?

Mal angenommen, du erzeugt dir einen Flankenimpuls von genau 1 Takt 
Dauer. Das Zählen der Flanken geht dann so:
1
SET_OUTPUT : process(CLK, RST)
2
   begin
3
     if(RST = '1') then           -- Achja, die lieben asynchronen Lehrbuchresets...
4
       LED_TMP <= "0000";
5
     elsif rising_edge(clk) then  -- es kann nur EINEN geben
6
        if(BTN1_RISE = '1') then  -- genau für 1 clk Zyklus aktiv
7
           LED_TMP <= LED_TMP + 1;
8
        end if;
9
     end if;
10
  end process;

Zum Thema "Reset" gabs hier im 
Beitrag "Xilinx und die Resets" schon mal ein paar 
tiefergehende Betrachtungen, die in der gesamten Länge incl. der 
weiterführenden Links einen Blick wert sind.

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.