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
> So richtig funktioniert es nicht...
Und das nicht mal in der Simulation...
So ein Bauteil existiert nicht:
1 | TIMING_SPEICHER: process (INIT_BUTTON) |
2 | begin
|
3 | if INIT_BUTTON = '0' then |
4 | ZUSTAND <= Y0; --INIT_BUTTON -> nicht gedrueckt |
5 | elsif falling_edge (INIT_BUTTON) then |
6 | ZUSTAND <= Y1; |
7 | if falling_edge (CLK_1_MHZ) then |
8 | :
|
9 | ZUSTAND <= FOLGE_Y; |
10 | end if; |
11 | 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.
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?
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
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:
1 | FSM_DATA_R_W : process (STATE, CLK, RW_ENABLE, FLAG_A, FLAG_B, FLAG_C, FLAG_D) |
2 | variable i, j, k, l : integer:= 0; |
3 | begin
|
4 | if falling_edge (CLK) then |
5 | :
|
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:
1 | RW_ENABLE <= '1'; |
2 | DATA_TX <= CONTROL_REG_A (i); |
3 | i := i + 1; |
4 | if i = 15 then |
5 | RW_ENABLE <= '0'; -- bin mir hier nicht sicher |
6 | i := 0; -- eigentlich unnötig. Nur nötig, wenn i auch in den anderen Zuständen als Laufvariable verwendet werden soll |
7 | FLAG_B <= '1'; |
8 | NEXT_STATE <= WRITE_MODE; |
9 | end if; |
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
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.