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
> 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
> 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;
Ja stimmt, eigentlich meinte ich auch in beiden Fällen nen Port. Das eine ist nen Ausgang, das andere nen Eingang.
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
> 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 ;-)
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
@ 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?
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.
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.
> ... 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;
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; |
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; |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.