www.mikrocontroller.net

Forum: FPGA, VHDL & Co. "if signal'event and signal = '1' " im process, wie bzw. wie umgeht man das?


Autor: ChrisB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich benötige in meiner Hardware die Auswertung der Flanke eines 
Eingangssignal.

Dazu habe ich folgendes Versucht:

...
signal meinEingang : in std_logic;
signal meinAusgang : out std_logic;
...
P1 : process ( meinEingang ) is
begin
  if meinEingang'event and meinEingang = '1' then
    meinAusgang <= '0';
  end if;
end process P1;

Dies ist meine Anwendung in sehr vereinfachter Form, nur um zu Schildern 
wo mein Problem liegt.
So wie es dort oben steht bekomme ich es einfach nicht synthetisiert. 
Soll ja auch irgendwie nicht möglich, habe ich jetzt schon oft gelesen, 
da das ein asynchroner Process ist und man dort keine Flankenabfragen 
machen kann, ich benötige dies aber in irgend einer Form.
Wie kann man das Problem anders lösen, so dass es dann synthetisierbar 
ist?

Gruß,

Christoph

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie kann man das Problem lösen, so dass es dann synthetisierbar ist?
Das ist auch so synthetisierbar, wie du es beschrieben hast ;-)

Allerdings wirst du u.U. zur Laufzeit des Designs ab und an Probleme mit 
dem Design haben. Im Idealfall hast du in deinem Design einen Mastertakt 
zu dem alles synchron ist.
Weil jetzt aber deine Taster und die ganze Aussenwelt sicher nicht 
synchron zu deinem FPGA laufen, mußt du jedem Signal deinen Takt 
aufzwingen, das Signal also über mindestens 2 Flipflops 
Einsynchronisieren bzw. Eintakten. Tust du das nicht, kann es 
innerhalb deines Designs irgendwo zu Metastabilität kommen und dein 
Design verhält sich fehlerhaft.

1) Such mal hier im Forum nach diesen kursiven Begriffen, du bist nicht 
der erste, der dieses Problem hat.
2) Ich habe so eine Eintakterei mit Flankenerkennung dort festgehalten: 
http://www.lothar-miller.de/s9y/categories/18-Flan...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> signal meinEingang : in std_logic;
> signal meinAusgang : out std_logic;

Signale sind nur Signale und nicht in oder out ;-)
So vielleicht:
signal meinEingang : std_logic;
signal meinAusgang : std_logic;

Autor: ChrisB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja stimmt, eigentlich meinte ich auch in beiden Fällen nen Port. Das 
eine ist nen Ausgang, das andere nen Eingang.

Autor: ChrisB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich probiere gerade deine Flankenerkennung aus. An soetwas habe ich 
bisher noch nicht gedacht, aber ist gut möglich, dass ich damit mein 
Problem lösen kann.
Hast du dich schonmal mit einem Brushless Motor beschäftigt? Speziell 
die Implementierung der Steuerung in Hardware? Da bin ich gerade dran, 
mal sehen wie weit ich komme.

Gruß,

Christoph

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hast du dich schonmal mit einem Brushless Motor beschäftigt?
Nein, da müssen andere ran.
Ich habe leider (noch) keine Zeit dafür gefunden ;-)

Autor: Bernhard R. (barnyhh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Process P1 liefert doch eine konstante '0' an meinAusgang. Es fehlt 
die Bedingung, unter der meinAusgang innerhalb dieses Processes auf '1' 
gesetzt wird.

Bernhard

Autor: ChrisB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Bernhard: Ja du hast Recht. Da ist mir wohl ein Fehler unterlaufen als 
ich das Problem schnell beispielhaft Schildern wollte.

@Lothar:
Deine Flankenerkennung scheint ganz gut zu funktionieren, jedoch habe 
ich da eine Frage bzw. ein Verständnisproblem:
Ich mache also einen Process in dem deine Flankenerkennung läuft, 
sensibel auf das Clock Signal und in einem weiteren Process (sensibel 
auf Clock Signal und das Flankensignal) will ich das wie folgt 
auswerten:

if flanke = '1' and pegel = '1' then ...

jedoch kann das meiner Meinung nach so nicht ganz funktionieren, da 
sobald die Flanke auf 1 geht der Pegel erst beim nächsten Takt auf 1 ist 
und da ist die Flanke schon wieder auf 0 oder habe ich das falsch 
verstanden?
Ich würde das so lösen:

-- Entprellen
if (sregC="11111110") then pegelC <= '1'; end if; -- high
if (sregC="00000001") then pegelC <= '0'; end if; -- low

Also genauso wie die Flankenerkennung. So ist sicher gestellt, dass das 
Pegelsignal zu gleichen Zeit auf 1 geht wie das Flankensignal.

Was sagst du dazu?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also gut, Kopier ich das mal kurz her, und pass das an:
signal sr     : std_logic_vector(2 downto 0);
signal flanke_steigend : std_logic;
:
process (clk)
begin
   if rising_edge(clk) then
      -- Schieberegister
      sr <= sr(1 downto 0) & eingang;
      -- Flankenerkennung
      flanke_steigend <= '0';
      if (sr="011") then 
         flanke_steigend <= '1';
      end if;
   end if;
end process;

process (clk)
begin
   if rising_edge(clk) then
      if (flanke_steigend='1') then
         -- tu hier das, was getan werden muss
      end if;
   end if;
end process;

Alle deine Prozesse sind (im Idealfall) mit einem Mastertakt 
rising_edge(clk) getaktet. Und synchron zum Takt fragst du dann die 
Flanke ab.

Autor: ChrisB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, ich glaube da hebn wir aneinander vorbei geredet.
Mit ist schon klar, wie es dann weiter geht.
Ich bin nur davon ausgegangen, dass man dann in dem Process für die 
Auswertung auch auf den Pegel schaut.
Also mit if flanke = '1' and pegel = '1' weiss ich dass es eine 
steigende Flanke ist und mit if flanke = '1' and pegel = '0' weiss ich, 
dass es eine fallende flanke ist.
Wenn man dies so auswerten würde, würde es aber so wie ich das 
verstanden habe nicht gehen, weil das "richtige" Pegelsignal erst einen 
Takt später als das Flankensignal anliegt und so das Flankensignal schon 
wieder 0 ist, wenn der richtige Pegel anliegt.
Es muss also entweder wie du es oben gemacht hast ein Signal für eine 
fallende Flanke und zusätzlich ein Signal für die steigende Flanke geben 
(wenn man wie ich beide Fälle auswerten will).
Eine andere Möglichkeit wäre doch aber auch für die Erkennung des 
Pegels:
if (sregC="11111110" or sregC="11111111") then pegelC <= '1'; end if; -- 
high
if (sregC="00000001" or sregC="00000000") then pegelC <= '0'; end if; -- 
low
zu verwenden.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ... weil das "richtige" Pegelsignal erst einen Takt später als das
> Flankensignal anliegt und so das Flankensignal schon wieder 0 ist ...
Am einfachsten ist es, immer 1 Signal zu setzen, das dann für genau
1 Taktzyklus lang aktiv ist. Dieses Signal wird dann in anderen Stufen 
als Clock-Enable verwendet.
Dann kann es genau diese von dir beobachteten Latency-Probleme nicht 
geben, denn du hast nur 1 Stelle, an der das Signal berechnet wird.


BTW:
> if (sregC="11111110" or sregC="11111111") then pegelC <= '1'; end if; --
Das ist das selbe wie:
if (sregC(7 downto 1)="1111111") then pegelC <= '1'; end if;

Autor: Patrick Sulimma (abaddon1979)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine typische Auswertung eines Einganssignal ist auch dies:
Es liefert bei steigender Flanke einen Puls mit der Periodendauer des 
Clocks:
--Positive Taktflankenabfrage der Triggersignale, minimierung der Pulsdauer--

a_1:  
process (GCK)
begin
if rising_edge(GCK) then
Last_TRG <= TRG;
end if;
end process a_1;

a_2:
process (GCK)
begin
if rising_edge(GCK) then
if TRG ='1' and Last_TRG = '0' then 
Q2 <= '1';
else Q2 <= '0';
end if;
end if;
end process a_2;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann immer noch ins Auge gehen, hier ist am Einsynchronisieren nur 1 
FF beteiligt, im Prozess a_2 wird der asynchrone Eingang TRG verwendet. 
Sicher wird es erst mit 2FFs:
if rising_edge(GCK) then
   Sync_TRG <= TRG;
   Last_TRG <= Sync_TRG;
   if (Sync_TRG ='1' and Last_TRG = '0') 
   then Q2 <= '1';
   else Q2 <= '0';
   end if;
end if;

Autor: Patrick Sulimma (abaddon1979)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jep da gebe ich dir Recht, eine Synchronisierung fehlt da noch. Bin auch 
nicht mehr der Jungste und manchmal leidet man da an Hirnschwund ... ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.