www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Zwei Taktflanken synchronisieren


Autor: chris (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

kurze Frage an die VHDL Profis. Wie kann ich in meinem Programm s.o. die 
fallenden Taktflanken CLK_1_MHZ und INIT_BUTTON synchronisieren und dann 
beim Zutreffen der Bedingung RW_INIT auf gleich 1 setzten?
Also wenn INIT_BUTTON gleich 1 ist soll dessen fallende Flanke den 
Zustand Y1 bereitsstellen. Im Zustand Y1 sollte dann in der If Abfrage 
durch einen Zwischenwert ZW_ZUSTAND solange gewartet werden bis dieser 
Aufgrund von falling_edge (CLK_1_MHZ) wahr ist. Anschließend wird der 
Zustand Y2 zugewiesen und RW_INIT wird auf gleich 1 gesetzt. So richtig 
funktioniert es nicht und es ist auch sehr umständlich geschrieben, so 
denke ich zumindest.
Ggf. kann mir jemand Tipps geben wie man dies sauberer Lösen, sowie die 
gewünschte Funktion realisieren kann.

Vielen Dank

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

Bewertung
0 lesenswert
nicht lesenswert
> So richtig funktioniert es nicht...
Und das nicht mal in der Simulation...
So ein Bauteil existiert nicht:
TIMING_SPEICHER: process (INIT_BUTTON)
  begin
       if INIT_BUTTON = '0' then 
          ZUSTAND <= Y0;   --INIT_BUTTON -> nicht gedrueckt
       elsif falling_edge (INIT_BUTTON) then 
          ZUSTAND <= Y1;
          if falling_edge (CLK_1_MHZ)  then 
             :
             ZUSTAND <= FOLGE_Y;    
          end if;
       end if;       
Das wäre ja ein Flipflop mit zwei Takteingängen...

Ich werde aus deiner Beschreibung nicht schlau. Zeichne einfach mal ein 
Timingdiagramm.

Zu den Grundlagen:
In einem FPGA-Design hast du im Idealfall (und insbesondere als 
Anfänger) genau 1 Takt, der auf eine Flankenrichtung sensitiv ist. Das 
nennt man dann ein synchrones Design. Alles andere erfolgt z.B. wie in 
VHDL Flankenerkennung beschrieben.

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du musst dir darüber im Klaren sein, dass du in VHDL eine Hardware 
beschreibst.
Was du hier machst, ist mehr oder weniger an die "Denke" von 
µC-Programmierung angelehnt. Sowas ist aber nicht synthetisierbar.

Dein Problem ist nicht nur die Flankenerkennung, sondern generell dein 
Design. z.B. würden für ZUSTAND keine Register angelegt, sondern 
Latches.


Auch ist mir die Funktionalität nicht ganz klar, was du erreichen 
willst.
Ich hab es so verstanden:

Dein Taster ist auf High und wenn er auf Low geht, dann springst du in 
einen Wartezustand, den du aber sofort mit der nächsten negativen Flanke 
des Taktes wieder verlässt.. Das Resultat wäre ein kurzer Impuls der 
unabhängig davon ist, wie lange du deinen Finger auf dem Taster lässt. 
Ist das so richtig?

Autor: chris (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für eure Antworten. Danke für den Link, ist eine sehr gute 
VHDL Codesammlung.
Schrotty du hast es richtig verstanden.

Ich habe es nun so wie im Bsp "VHDL Flankenerkennung" gemacht.
Danke für den Tipp.

Es haben sich jedoch schon wieder andere Fragen aufgetan. Vielleicht 
könnt ihr mir da als Anfänger und Lernwilligen auch weiterhelfen.
Ich will einen IC initialisieren (TEA 5880 TS FM-Empfänger). Dieser hat 
3 Datenleitungen die für die Beschreibung notwendig sind (RW_ENABLE, 
DATA_TX und CLK). Ebenso hat dieser 4 Register um ihn zu initialisieren. 
So, ich habe nun ein Programm geschrieben das genau das tun soll. Es 
funktioniert auch soweit, ich habe eine Testbench geschrieben und es in 
ModelSim simuliert. Jedoch habe ich wohl irgendwo ein Latch!

Die Daten zur Initialisierung habe ich als "constant std_logic_vector" 
definiert s. Anhang. Mit dem Tastendruck SET_BUTTON in der VHDL 
Flankenerkennung (Prozess: EDGE_DETECT) und CLK_ENABLE initialisiere ich 
nun meine State Maschine STATE_INIT.
Mit der eigentlichen State Maschine FSM_DATA_R_W, laufe ich nun meine 
Zustände durch. Ich setzte den RW_ENABLE = 1 und starte die 
Datenübertragung (15 Bit). Ich zähle die Bits durch 0..14, wenn Bit 14 
erreicht ist, dann setze ich ein Flag (Zustandsauswahl) und springe 
zurück in den Zustand WRITE_MODE. In diesem setze ich RW_ENABLE = 0, da 
RW_ENABLE nur während der  Übertragung der 15 Bit aktiv sein darf. Mit 
RW_ENABLE = 0 übernimmt der IC den jeweiligen 15 Bit String in das 
Register. Das mache ich nun 4 mal. Das funktioniert auch soweit, jedoch 
habe ich im Zustand   "CTL_REG_B" das Problem, das statt den letzten 
beiden Bits "01" in dem Vector "CONTROL_REG_A" eine "111" Folge 
erscheint (rot eingekreist im Anhang ModelSim). Ich weiß nicht mehr 
weiter warum das so ist...Latch?
Für Hilfe wäre ich sehr dankbar, vielleicht könnte ich noch ein paar 
Tipps bekommen den Code robuster bzw. einfacher zu gestalten.

Vielen Dank

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

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir das jetzt noch nicht sooo genau angeschaut, aber:
1) üblicherweise ist die Testbench ausserhalb des Designs, bindet das zu 
testende Modul als Komponente ein und hat keine Ports in der Entity.
2) dieser Prozess hier:
FSM_DATA_R_W : process (STATE, CLK, RW_ENABLE, FLAG_A, FLAG_B, FLAG_C, FLAG_D)  
variable i, j, k, l     : integer:= 0;
begin
   if falling_edge (CLK) then
   :
ist nur auf CLK sensitiv. Alle anderen Signale sind in der Liste 
überflüssig.

> Ich weiß nicht mehr weiter warum das so ist...Latch?
Nicht so richtig ein Latch, aber du bist dort bereits im Zustand 
WRITE_MODE. Wegen der Bitmuster ist schlecht zu sehen, dass das letzte 
Bit in keinem der Zustände CTL_REG_A...D korrekt ausgegeben wird   :-o
Und das wird klar, wenn du dir ansiehst, dass deine Variable nach dem 
indizieren incerementiert wird, und danach (wenn sie =14 ist) sofort der 
Zustand gewechselt wird. Das Bit 13 bleibt also jeweils in DATA_TX 
gespeichert.
Probiers mal so:
     RW_ENABLE <= '1';
     DATA_TX <= CONTROL_REG_A (i);
     i := i + 1;  
     if i = 15 then  
        RW_ENABLE <= '0';  -- bin mir hier nicht sicher
        i := 0;  -- eigentlich unnötig. Nur nötig, wenn i auch in den anderen Zuständen als Laufvariable verwendet werden soll
        FLAG_B <= '1';
        NEXT_STATE <= WRITE_MODE;
     end if;

Autor: chris (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

erstmal vielen Dank für die schnelle Antwort und die super Tipps.
So, ich habe nun meine Bedingung in der if Abfrage auf i = 15 geändert, 
d.h gleichzeitig, dass ich auch meine Bitstrings auf 15 ändern muss. Ich 
habe dann jeweils den Bitstrings noch eine '0' angehängt. Aber leider 
bleibt das Verhalten das gleiche und mein Timing verändert sich um die 
Bitstelle '0'. Allerdings wird dann das Bit in CTL_REG_B sichtbar, nur 
eben mit falschem Timing :-) Hab dir nochmals das neue Timing Diagramm 
angehängt, vielleicht hast du noch eine Idee die mir weiterhelfen 
könnte, bzw. eine andere Möglichkeit dies zu unterbinden. Schon mal 
vielen Dank für die Hilfe.

Grüße

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.