Forum: FPGA, VHDL & Co. Prozesskommunikation / Flankenerkennung


von Johannes Scherle (Gast)


Lesenswert?

Hallo alle,

ich habe eine Frage zur Flankenerkennung bzw. der Kommunikation zwischen 
Prozessen.
Folgendes Szenario:
Ein Prozess, sensitiv auf ein Sensor Eingangssignal, das einen high / 
low Pegel liefert. Dieser soll die Anzahl der Kanten auf diesem Signal 
liefern, also mit jeder Flanke um eins erhöhen und bei vier wieder auf 
Null zurücksetzen. Das Signal edgeCounter wird nur in diesem Prozess 
beschrieben.
1
process (oneorzero)
2
  --constant maxEdges : natural := 4;
3
  begin
4
     if (blockOccured = true) then
5
      if (edgeCounter = 4) then
6
       --edgeCounter <= 0;
7
    edgeCounter <= (others => '0');
8
       else
9
       edgeCounter <= edgeCounter + 1;
10
     end if;
11
    elsif (blockOccured = false) then
12
      --edgeCounter <= 0;
13
     edgeCounter <= (others => '0');
14
   end if;
15
  end process;

In einem anderen, synchronen Prozess möchte ich das Signal edgeCounter 
lesen und das Signal blockOccured, vom typ boolean schreiben.

Quartus synthetisiert mir das ohne zu meckern. Wenn ich das jedoch das 
Signal Tap Tool benutze und mir das ganze damit anschaue, sieht man, 
dass der edgeCounter scheinbar willkürlich mit jeder Taktflanke der 
Clock des synchronen Prozesses auf irgendwelche Werte gesetzt wird.

Jemand ne Idee?

Viele Grüße

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


Lesenswert?

Johannes Scherle schrieb:
> Quartus synthetisiert mir das ohne zu meckern.
Echt? Such mal im Synthesereport nach "combinational loop" oder 
"combinatorial loop". Das hast du mit dem edgeCounter nämlich gebaut:
http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife

Und die Simulation wird sicher nicht stimmen, weil das ein 
kombinatorischer Prozess ist, bei dem blockOccured und der edgeCounter 
in der Sensitivliste fehlen...

> Dieser soll die Anzahl der Kanten auf diesem Signal liefern,
> also mit jeder Flanke um eins erhöhen
Also einfach zählen.
Zähler werden immmer mit Flipflops aufgebaut.
Flipflops brauchen immer einen Takt.
Und Takte solltest du im Idealfall genau einen (in Zahlen 1) haben.
Erst dann wird das Design so richtig schön einfach...

von Schlumpf (Gast)


Lesenswert?

Hallo Johannes,

Lothar hat es ja schon gesagt:
Das, was du da beschreibst, geht eigentlich gar nicht und es ist ein 
Wunder, dass die Synthese es "gefressen" hat.
WAS sie allerdings daraus gebaut hat, wird nicht das sein, was du dir 
vorgestellt hast.
Stichwort Combinatorial Loop wurde ja schon genannt.

Prozesse sind sensitiv auf einen Zustandswechsel eines Signals in deren 
Sensitivity-Liste. ABER das sollte man niemals dazu verwenden, um eine 
Flankenerkennung zu bauen.

Überlege dir, wie eine Flankenerkennung und ein Zähler in "echter" 
Hardware aussehen würde (mit FlipFlops und Gattern).
Und genau das beschreibst du dann in VHDL.

eine Flankenerkennung macht man, indem man das zu analsysierende Signal 
durch zwei Register schiebt und die beiden Register auf "Ungleichheit" 
überprüft. Dann entsteht an diesem Vergleicher für einen Systemtakt lang 
eine "1", wenn eine Flanke vorliegt. Dieses Signal kann dann als 
Steuereingang (Enable) für einen synchronen Zähler dienen.

von Uwe (Gast)


Lesenswert?

> also mit jeder Flanke um eins erhöhen
Mit jeder ? Also mit jeder positiven Flanke und jeder negativen ?
Man muß sich im klearen sein was das für Bauelemte im FPGA drinne sind 
und einfach mal kurz überschlagen ob man aus diesen das gewünschte 
selber bauen könnte (wenn man der Synthetisierer wär).
Brauchst du das wirklich, reicht es nicht nur eine Art Flanken zu zählen 
und an das Ergebnis hinten noch ein weiteres 0 Bit drazupacken (also mal 
2 zu nehmen)?
Wenn du es wirklich brauchst dann mußt du einen Zähler machen der die 
positiven Flaken Zählht un einen der die negativen zählt und beide 
addieren.

von Schlumpf (Gast)


Lesenswert?

Uwe schrieb:
> Wenn du es wirklich brauchst dann mußt du einen Zähler machen der die
> positiven Flaken Zählht un einen der die negativen zählt und beide
> addieren.

Wieso das denn? Er will doch nur die Flanken des Eingangssignals 
erkennen und zählen.
Zählerfrequenz hoch genug wählen und dann mit bei steigendenden Flanke 
des Systemtakts den Zähler inkrementieren, wenn die Flankenerkennung des 
Eingangssignals Meldung macht ;-)

Also Eingangssignal steuert über eine Flankenerkennungslogik das EN des 
Counters, dessen Register mit dem Systemtakt versorgt werden.

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


Lesenswert?

Uwe schrieb:
> Brauchst du das wirklich, reicht es nicht nur eine Art Flanken zu zählen
> und an das Ergebnis hinten noch ein weiteres 0 Bit drazupacken (also mal
> 2 zu nehmen)?
> Wenn du es wirklich brauchst dann mußt du einen Zähler machen der die
> positiven Flaken Zählht un einen der die negativen zählt und beide
> addieren.
Zweimal Murks.

Dabei ist es so einfach:
Johannes Scherle schrieb:
> Dieser soll die Anzahl der Kanten auf diesem Signal liefern
Also was schnarchlangsames im Vergleich mit den 50MHz, die üblicherweise 
als Takt für ein FPGA herhalten müssen. Das heißt frei nach Kochrezept:
1. Einsynchronisieren
2. Flanke erkennen
3. Zählen
4. Auswerten
Frei nach 
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren würde 
ich also etwa so anfangen:
1
signal insr  : std_logic_vector(2 downto 0);
2
:
3
process begin    -- keine Sensitivliste bedeutet: keine FALSCHE Sensitivliste
4
   wait until rising_edge(clk); -- alles hört auf den 50MHz Takt
5
6
   -- Schieberegister zum Einsynchronisieren
7
   insr <= insr(1 downto 0) & input;
8
9
   if (insr(2)/= insr(1)) then   -- irgendeine Flanke von input
10
     if (blockOccured = true) then
11
       if (edgeCounter = 4) then -- wenn der Zähler auf 4 zählt, dann hat er eins zuviel gezählt: 0,1,2,3,4 sind 5 Schritte
12
        --edgeCounter <= 0;  -- jaja, wenn der Zähler ein Integer wäre, dann ginge das
13
         edgeCounter <= (others => '0');
14
       else
15
         edgeCounter <= edgeCounter + 1;
16
       end if;
17
     elsif (blockOccured = false) then
18
      -- edgeCounter <= 0;   -- siehe oben
19
       edgeCounter <= (others => '0');
20
     end if;
21
      
22
   end if;
23
end process;

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.