mikrocontroller.net

Forum: FPGA, VHDL & Co. Takt herunterteilen


Autor: Küchenhilfe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Küchenhilfe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Takt sollte schon symmetrisch sein.

Autor: Boris M. (borism)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Küchenhilfe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem enable habe ich verstanden, aber was meinst du mit dem 
Begriff Toggeln?

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-)

Autor: Martin Kohler (mkohler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Küchenhilfe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens soll das Signal an einen Drehschalter an dem die Taktsignale 
eingestellt werden.

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

Bewertung
0 lesenswert
nicht lesenswert
> Ü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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Taktteiler is
  port(CLK_10M     : in  std_logic;
       CLK_OUT     : out std_logic);
end Taktteiler;

architecture BEHAVE of Taktteiler is
constant div1MHZ    : integer := (10/2)-1; -- 10MHz/10 = 1MHz --> zählen von 0..4
signal cnt          : integer range 0 to div1MHZ  := 0;
signal clkout       : std_logic := '0';

begin
  process begin 
     wait until rising_edge(clk_10M);
     if (cnt < div1MHZ) then
        cnt    <= cnt+1;
     else 
        clkout <= not clkout;
        cnt    <= 0;
     end if;
  end process;
  CLK_OUT <= clkout;
end BEHAVE;

Autor: Küchenhilfe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Küchenhilfe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

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

Bewertung
0 lesenswert
nicht lesenswert
> 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...

Autor: Chef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der Takt sollte schon symmetrisch sein.
Einfach jeweils den doppelten Takt nehmen und auf ein JK-FF (toggle FF).

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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_FP... 
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 !

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

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

Bewertung
0 lesenswert
nicht lesenswert
> 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:
  process begin 
     wait until rising_edge(clk_10M); -- Alles hört auf den Takt
     if (counter=99) then
        counter <= 0;
     else
        counter <= counter+1;
     end if;
  end process;
  
  process begin 
     wait until rising_edge(clk_10M); -- Alles hört auf den Takt
     if (counter=0) then
        led <= '0';
     end if;
     if (counter=50) then
        led <= '1';
     end if;
  end process;

Das hier ist nicht synchron:
  process (counter, clk) begin 
     if (counter=100) then        -- asynchroner Reset
        counter <= 0;
     elsif rising_edge(clk) then
        counter <= counter+1;
     end if;
  end process;

  process (counter) begin         -- Kombinatorik und Latch
     if (counter=0) then            
        led <= '0';
     end if;
     if (counter=50) then
        led <= '1';
     end if;
 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.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Erläuterung!
Wenn ich das Beispiel aus dem Clock Enable Artikel nochmals hernehme:
process(clk)
begin
  if rising_edge(clk) then
    if ce='1' then
 
    -- Aktionen hier einfügen, welche mit langsamen Takt laufen
    -- ***1
 
    end if;
  end if;
end process;
process(clk)
begin
  if rising_edge(clk) then
 
    -- Aktionen hier einfügen, welche mit schnellem Takt laufen
    -- ***2
 
  end if;
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?

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

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, vielen Dank für die Nachhilfe ;)

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.