vhtl schrieb:
> if rising_edge(BUTTON) then
Das ist die komplett falsche Strategie, vermutlich, weil du noch die
falsche Denkweise hast.
Um es kurz zu machen: man macht nicht unnötig viele Taktdomänen auf.
Alles, was mit wait oder 'event oder rising_egde() oder falling_edge()
zu tun hat, ist eine eigene Taktdomäne. Und weil man dann immer Probleme
mit dem Taktdomänenübergang hat, sollte man versuchen, so einfache Dinge
wie einen Taster direkt in der Zieldomäne zu erledigen.
Die Zieldomäne ist "der Takt", üblicherweise der eine Takt, der von
einem Quarz im Bereich um 50..100MHz an einem FPGA-Pin vorgegeben wird.
vhtl schrieb:
> Mit geht's jetzt aber um das asynchrone Erkennen von Signaländerungen
> (ob der Zähler hier eine besondere Rolle spielt weiß ich nicht).
>
> Der Button ist jetzt auch nur ein Beispiel für ein Signal, also Prellen
> bitte ignorieren.
Wenn du ein Signal erkennen willst/musst/sollst, das so kurz ist, dass
es mit dem einen einzigen FPGA-Takt nicht einsynchronisiert und darauf
ein Pegelwechsel erkannt werden kann, dann bleibt dir als Notnagel(!!)
nur, eine Flanke darauf zu erkennen, diesen Flankenwechsel zu speichern,
einzusynchronisieren und mit dem einen FPGA-Takt darauf zu reagieren.
So etwa:
http://www.lothar-miller.de/s9y/archives/19-Kurzer-Spike-in-Puls-umgewandelt.html
vhtl schrieb:
> Also: Wie wartet man richtig auf einen Signalwechsel pro Prozeß, um
> danach z.B. einen Zähler zu erhöhen?
Man "wartet" eigentlich nicht, sondern man erkennt nur, dass nichts
relevantes passiert ist und deshalb nichts getant werden muss. Relevant
bei einem Signalwechsel ist eine Änderung eines Pegels z.B. von 0 auf 1.
Also muss 1. der Pegelverlauf gespeichert und dann 2. in diesem Speicher
ein Pegelwechsel erkannt und dann 3. darauf reagiert werden:
1 | architecture Behavioral of counter is
|
2 | signal value : integer := 0;
|
3 | signal sr_button : STD_LOGIC_VECTOR(1 downto 0) := "00"; -- Schieberegister für asynchrones Eingangssignal
|
4 | begin
|
5 |
|
6 | sr_button <= sr_button(0) & BUTTON when rising_edge(clk); -- Signal einspeichern und einsynchronisieren
|
7 |
|
8 | count: process(clk) begin
|
9 | if rising_edge(clk) then
|
10 | if sr_button = "01" then -- gewünschter Pegelwechsel am BUTTON erkannt
|
11 | value <= value + 1; -- Reaktion auf die den Pegelwechsel
|
12 | end if;
|
13 | end if;
|
14 | end process;
|
15 |
|
16 |
|
17 | end Behavioral;
|
Letztlich ist es einfach: das gesamte FPGA-Design besteht aus
Zustandsautomaten. Das hört sich jetzt aufwändig an, aber letztlich ist
ja jeder schäbige Zähler schon so ein Automat. Und der Automat im Fall
hier ist einfach so gestrickt, dass er bei jedem FPGA-Takt prüft, ob das
Schieberegister einen Flankenwechsel von 0 nach 1 beinhaltet. Wenn
nicht, dann tut der Automat nichts. Wenn so ein Wechsel erkannt ist,
dann zählt er den Zähler hoch.