Ich bin noch recht unerfahren mit VHDL und brauche eure Hilfe. Ich soll mit Hilfe von VHDL einen 1Mhz-Takt herunterteilen auf verschiedene Werte: 1Hz, 10 Hz, 100 Hz, 1kHz, 10 kHz, 100 kHz und 1 Mhz. Mir fehlt der richtige Ansatz. Wie fange ich dabei richtig an?
Das macht man mit Clock Enable. Nicht den Takkt teilen, sondern nur alle x Takte das Clock Enable auf 1 setzen, damit die Schaltung was macht. Oder musst du einen symetrischen Takt ausgeben?
Na das sollte doch kein Problem sein... Ich geb dir mal einen Gedankenanstoß, kannst es ja versuchen zu programmieren. Wenn du fragen zu deinem Code hast kannst du die ja gerne hier stellen! Du hast deine CLK (Grundtakt = 1 MHz) aus dieser erzeugst du dir ein Enable-Signal, welches doppelt so schnell ist wie dein gewünschter Takt (z. B. mit einem Zähler). Mit deiner Clock und dem Ansteigen deines Enable-Signal hast du dann den Zeitpunkt für eine Flanken deiner gewünschte Clock (hiere musst du nur zwischen 0 und 1 toggeln wenn die CLK von 0 auf 1 geht und wenn Enable-Signal 1 ist). (Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt... Wenn nicht frag einfach...
Das mit dem enable habe ich verstanden, aber was meinst du mit dem Begriff Toggeln?
Mit toggeln meint er den Wechsel zwischen 0 und 1. Also du nutzt einen Zähler der mit dem Ursprungstakt läuft. Wenn Zählerstand erreicht -- Zähler rücksetzen und neues Taktsignal toggeln... schlecht erklärt ;-)
Küchenhilfe schrieb: > Das mit dem enable habe ich verstanden, aber was meinst du mit dem > Begriff Toggeln? Mit Toggeln wird gesagt, dass das Signal zum Schaltzeitpunkt (wenn Clock Enable gesetzt ist) einfach invertiert wird, 0->1 resp. 1->0, unabhängig davon, was für einen Zustand es vorher hatte.
Als Beispiel: Du hast 10MHz Grundtakt und willst 1MHz erzeugen. Dann beschreibst du einen synchronen Zähler, und einen Komparator, der beim Zählerstand 4 ein FlipFlop umschaltet (toggle) und außerdem synchron den Zähler zurücksetzt. Somit zählt der immer von 0 bis 4 und dein Signal wechselt alle 5 Takte die Polarität und du hast einen schönen symetrischen Takt am Ausgang des Toggle-FlipFlops mit 1Mhz. Durch Variation der Zählerwerte kannst du dann bei entsprechend langem Zähler alle möglichen Frequenzen einstellen. Der Zählerwert ist immer der halbe Teilerwert minus 1.
Übrigens soll das Signal an einen Drehschalter an dem die Taktsignale eingestellt werden.
> Übrigens soll das Signal an einen Drehschalter an dem die Taktsignale > eingestellt werden. Ich würde mit einem Drehschalter den Teiler am CPLD/FPGA einstellen und das fertige Signal ausgeben. Also nicht alle diese Frequenzen ausgeben >>> 1Hz, 10 Hz, 100 Hz, 1kHz, 10 kHz, 100 kHz und 1 Mhz und daraus auswählen. Sondern nur eine Frequenz erzeugen, und zwar die, die vom Schalter ausgewählt ist. Das ist eine einfache Aufgabe, aber mach erst mal 1 Frequenz:
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity Taktteiler is |
6 | port(CLK_10M : in std_logic; |
7 | CLK_OUT : out std_logic); |
8 | end Taktteiler; |
9 | |
10 | architecture BEHAVE of Taktteiler is |
11 | constant div1MHZ : integer := (10/2)-1; -- 10MHz/10 = 1MHz --> zählen von 0..4 |
12 | signal cnt : integer range 0 to div1MHZ := 0; |
13 | signal clkout : std_logic := '0'; |
14 | |
15 | begin
|
16 | process begin |
17 | wait until rising_edge(clk_10M); |
18 | if (cnt < div1MHZ) then |
19 | cnt <= cnt+1; |
20 | else
|
21 | clkout <= not clkout; |
22 | cnt <= 0; |
23 | end if; |
24 | end process; |
25 | CLK_OUT <= clkout; |
26 | end BEHAVE; |
>Ich würde mit einem Drehschalter den Teiler am CPLD/FPGA einstellen und >das fertige Signal ausgeben. Das würde ich nur im Notfall machen, weil ich zu wenig Anschlüsse am CPLD (XC9572 PC44) habe. Hier würden denke ich 3 Pins belegt werden. (GCK, In und OUT) ODER wenn natürlich zu viele Makrozellen ausgelastet sind, würde ich auf den nächst größeren CPLD setzen, dann könnte ich diese Methode durchführen.
Ich habe noch mal nachgedacht: Die Idee mit dem Drehschalter finde ich doch nicht so schlecht. Dann müsste aber der Drehschalter einen Code erzeugen. ODER?
> Hier würden denke ich 3 Pins belegt werden. (GCK, In und OUT) Was ist "hier"? Wie kommst du auf 3 Pins? Zum Ausgeben der o.a. Frequenzen bräuchtest du 7 Ausgangspins. Beim Anschluss eines BCD-Schalters bräuchtest du 3 für den Schalter und 1 für den Ausgang. > Dann müsste aber der Drehschalter einen Code erzeugen. ODER? Das wäre wohl das beste. BTW: die ganzen Teiler brauchen recht viel Platz im CPLD...
>Der Takt sollte schon symmetrisch sein.
Einfach jeweils den doppelten Takt nehmen und auf ein JK-FF (toggle FF).
Hallo, bin neu in VHDL und FPGA und komme eigentlich ziemlich flott voran. Zum Thema synchroner Takt habe ich aber noch einige Unklarheiten, die mir an dieser Stelle evtl genommen werden können. Unter synchronem Takt verstehe ich, dass die heruntergeteilten Taktsignale die Flanken exakt zum gleichen Zeitpunkt haben wie der Haupttakt, von welchem die heruntergeteilten abgeleitet sind (die Flanken natürlich seltener, da kleinere Frequenz). Es soll also nicht ein Zählerstand mit Kombinatorik mit einen bestimmten Zählerwert verglichen werden, da durch die Kombinatorik wieder eine Verzögerung hinzukommt. Wenn nun der Vergleichswert jedoch in ein FF gespeichert wird (das das Ergebnis des Vergleichs übernimmt), dann müsste dies doch wieder synchron mit dem Haupttakt laufen oder? Stellt das Beispiel von: Autor: Lothar Miller (lkmiller) Datum: 13.11.2009 09:35 mit CLK_OUT einen synchronen Takt zur Verfügung? der ohne weiteres in weiterverwendet werden kann? Die im Artikel http://www.mikrocontroller.net/articles/Taktung_FPGA/CPLD#Clock_Enable verwendete Methode läuft ja eigentlich auf das gleiche heraus (wobei das CLK_OUT aus dem Beispiel von Lothar dem ce aus dem Artikel entspricht). Daraus schliesse ich, dass es auch mit dem Beispiel von Lothar nötig ist, nochmals mit dem Haupttakt zu synchronisieren? Oder liege ich da falsch? Das ganze ist mir noch ein bisschen schleierhaft... Wer hilft, bekommt 42 Jungfrauen im Paradies, versprochen !
> Wenn nun der Vergleichswert jedoch in ein FF gespeichert > wird (das das Ergebnis des Vergleichs übernimmt), dann müsste dies doch > wieder synchron mit dem Haupttakt laufen oder? Nein, weil der Ausgang des FFs erst mit einer bestimmten Verzögerung erscheint. Der Ausgang kommt also später als der Takt. Die Flanken des "Derived Clock" sind also phasenverschoben zum schnellen Takt. Man kann so einen abgeleiteten Takt verwenden, es kann aber Probleme geben: - Wenn man z.B. Ausgänge von FFs, die mit dem schnellen Takt arbeiten, an FFs führt, die mit dem abgeleiteten arbeiten, dann schalten deren Eingänge während der Taktflanke um. Es kommt zu Setup-Zeit Verletzungen. - Im FPGA gibt es eigene schnelle Leitungen für den Takt, welche garantieren, dass alle angeschlossenen FFs den Takt mehr oder weniger gleichzeitig sehen. Diese werden aber für angeleitete Takte nicht unbedingt verwendet, sodass die FFs am abgeleiteten Takt eventuell nicht 100% synchron schalten. In jedem Fall sollte man sicherstellen, dass der abgeleitete Takt wieder auf eine schnelle Leitung geführt wird (BUFG Komponente). Bei der (besten) Lösung mit CE Signal muss nichts nochmals synchronisert werden, weil alle FFs mit nur einem Takt laufen.
OK, vielen Dank. Das mit der Verzögerung leuchtet mir ein. D.h. aber auch, dass die Lösung von Lothar ein paar Beiträge weiter oben nicht absolut synchron ist und die einzige absolut Synchrone Variante ist, dass man das Haupttaktsignal und das CE-Signal in einen Block gibt (welcher mit langsamem Takt laufen soll) und dort die steigende Flanke des Haupttaktes auswertet und wenn das CE = 1 ist, dann eine Aktion ausführt? Ich hoffe, dass das so ungefähr hinkommt...
> D.h. aber auch, dass die Lösung von Lothar ein paar Beiträge weiter oben > nicht absolut synchron ist Die Aufgabe war, ein Ausgangssignal mit einem Tastverhältnis von 50% zu erzeugen. Dass dieses Ausgangssignal CLK_OUT heißt, ist ein Teil der Aufgabenstellung. Niemals (sag niemals Nie) würde ich diesen CLK_OUT innerhalb eines FPGA-Designs weiterverwenden. Allerdings hat dieser CLK_OUT wenigstens keine Glitches, Spikes und ähnliche unschöne Effekte, weil das Signal registriert ist. > D.h. aber auch, dass die Lösung von Lothar ein paar Beiträge weiter oben > nicht absolut synchron ist Ein synchrones Design ist so definiert, dass sich Signale nur aufgrund eines (in Zahlen 1) Taktes ändern können. Sowas z.B. ist garantiert synchron:
1 | process begin |
2 | wait until rising_edge(clk_10M); -- Alles hört auf den Takt |
3 | if (counter=99) then |
4 | counter <= 0; |
5 | else
|
6 | counter <= counter+1; |
7 | end if; |
8 | end process; |
9 | |
10 | process begin |
11 | wait until rising_edge(clk_10M); -- Alles hört auf den Takt |
12 | if (counter=0) then |
13 | led <= '0'; |
14 | end if; |
15 | if (counter=50) then |
16 | led <= '1'; |
17 | end if; |
18 | end process; |
Das hier ist nicht synchron:
1 | process (counter, clk) begin |
2 | if (counter=100) then -- asynchroner Reset |
3 | counter <= 0; |
4 | elsif rising_edge(clk) then |
5 | counter <= counter+1; |
6 | end if; |
7 | end process; |
8 | |
9 | process (counter) begin -- Kombinatorik und Latch |
10 | if (counter=0) then |
11 | led <= '0'; |
12 | end if; |
13 | if (counter=50) then |
14 | led <= '1'; |
15 | end if; |
16 | end process; |
Simulieren tut beides (in etwa) gleich: Es wird ein Zähler von 0 bis 99 erzeugt. Bei Zählerstand 0 wird eine LED aus- und bei 50 eingeschaltet. Allerdings ist die zweite Variante in der Realität extrem empfindlich auf Glitches und Spikes bei Zählerübergängen von counter. In der ersten Variante wird der counter quasi als Enable für das Setzen und Zurücksetzen der LED verwendet.
Vielen Dank für die Erläuterung! Wenn ich das Beispiel aus dem Clock Enable Artikel nochmals hernehme:
1 | process(clk) |
2 | begin
|
3 | if rising_edge(clk) then |
4 | if ce='1' then |
5 | |
6 | -- Aktionen hier einfügen, welche mit langsamen Takt laufen
|
7 | -- ***1
|
8 | |
9 | end if; |
10 | end if; |
11 | end process; |
1 | process(clk) |
2 | begin
|
3 | if rising_edge(clk) then |
4 | |
5 | -- Aktionen hier einfügen, welche mit schnellem Takt laufen
|
6 | -- ***2
|
7 | |
8 | end if; |
9 | end process; |
Die Aktionen, welche an den Stellen -- ***1 und -- ***2 stehen laufen also absolut synchron (also ohne Taktversetzung und ohne die Gefahr von Spikes/Glitches) und das if ce='1' then bildet ebenfalls keine Verzögerung?
Ja. Sie laufen absolut synchron zum clk. > das if ce='1' then bildet ebenfalls keine Verzögerung? Nein, denn das ist ja nur eine weitere Bedingung, die in die Weiterschaltlogik dort eingefügt werden: >> -- Aktionen hier einfügen, welche mit langsamen Takt laufen >> -- ***1
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.