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


von ChrisB (Gast)


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

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


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-Flankenerkennung

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


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;

von ChrisB (Gast)


Lesenswert?

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

von ChrisB (Gast)


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

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


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 ;-)

von Bernhard R. (barnyhh)


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

von ChrisB (Gast)


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?

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


Lesenswert?

Also gut, Kopier ich das mal kurz her, und pass das an:
1
signal sr     : std_logic_vector(2 downto 0);
2
signal flanke_steigend : std_logic;
3
:
4
process (clk)
5
begin
6
   if rising_edge(clk) then
7
      -- Schieberegister
8
      sr <= sr(1 downto 0) & eingang;
9
      -- Flankenerkennung
10
      flanke_steigend <= '0';
11
      if (sr="011") then 
12
         flanke_steigend <= '1';
13
      end if;
14
   end if;
15
end process;
16
17
process (clk)
18
begin
19
   if rising_edge(clk) then
20
      if (flanke_steigend='1') then
21
         -- tu hier das, was getan werden muss
22
      end if;
23
   end if;
24
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.

von ChrisB (Gast)


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.

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


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;

von Patrick S. (abaddon1979)


Lesenswert?

Eine typische Auswertung eines Einganssignal ist auch dies:
Es liefert bei steigender Flanke einen Puls mit der Periodendauer des 
Clocks:
1
--Positive Taktflankenabfrage der Triggersignale, minimierung der Pulsdauer--
2
3
a_1:  
4
process (GCK)
5
begin
6
if rising_edge(GCK) then
7
Last_TRG <= TRG;
8
end if;
9
end process a_1;
10
11
a_2:
12
process (GCK)
13
begin
14
if rising_edge(GCK) then
15
if TRG ='1' and Last_TRG = '0' then 
16
Q2 <= '1';
17
else Q2 <= '0';
18
end if;
19
end if;
20
end process a_2;

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


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:
1
if rising_edge(GCK) then
2
   Sync_TRG <= TRG;
3
   Last_TRG <= Sync_TRG;
4
   if (Sync_TRG ='1' and Last_TRG = '0') 
5
   then Q2 <= '1';
6
   else Q2 <= '0';
7
   end if;
8
end if;

von Patrick S. (abaddon1979)


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 ... ;)

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.