Grundsätzlich gibt es zwei Möglichkeiten, dies zu tun. Der erste ist die Verwendung des nativen Xilinx-Clock-Synthesizer-Kerns. Dies hat unter anderem den Vorteil, dass die Xlinx-Tools die Uhr als solche erkennen und über die erforderlichen Pfade leiten. Die Tools werden auch alle zeitlichen Einschränkungen bewältigen (in diesem Fall nicht wirklich zutreffend, da es sich um einen 2-Hz-Takt handelt)
Die zweite Möglichkeit besteht darin, einen Zähler zu verwenden, um die Anzahl der schnelleren Taktimpulse zu zählen, bis die Hälfte Ihrer langsameren Taktperiode verstrichen ist. In Ihrem Fall beträgt die Anzahl der schnellen Taktimpulse, die eine Taktperiode eines langsamen Taktzyklus ausmachen, beispielsweise 50000000/2 = 25000000. Da wir eine halbe Taktperiode wünschen, sind dies 25000000/2 = 12500000 für jeden Halbzyklus . (die Dauer jedes Hochs oder Tiefs).
So sieht es in VHDL aus:
library IEEE;use IEEE.STD_LOGIC_1164.all;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned valuesuse IEEE.NUMERIC_STD.all;entity scale_clock isport(
clk_50Mhz :instd_logic;
rst :instd_logic;
clk_2Hz :outstd_logic);end scale_clock;architecture Behavioral of scale_clock issignal prescaler :unsigned(23downto0);signal clk_2Hz_i :std_logic;begin
gen_clk :process(clk_50Mhz, rst)begin-- process gen_clkif rst ='1'then
clk_2Hz_i <='0';
prescaler <=(others=>'0');elsif rising_edge(clk_50Mhz)then-- rising clock edgeif prescaler =X"BEBC20"then-- 12 500 000 in hex
prescaler <=(others=>'0');
clk_2Hz_i <=not clk_2Hz_i;else
prescaler <= prescaler +"1";endif;endif;endprocess gen_clk;
clk_2Hz <= clk_2Hz_i;end Behavioral;
Dinge zu beachten:
Der erzeugte Takt ist beim Reset Null. Dies ist für einige Anwendungen in Ordnung und für andere nicht. Es kommt nur darauf an, wofür Sie die Uhr benötigen.
Der erzeugte Takt wird von den Xilinx-Synthesewerkzeugen als normales Signal weitergeleitet.
2Hz ist sehr langsam. Das Simulieren für eine Sekunde wird eine Weile dauern. Da es sich um eine kleine Codemenge handelt, sollte die Simulation auch für 1 Sekunde relativ schnell erfolgen. Wenn Sie jedoch mit dem Hinzufügen von Code beginnen, kann die Zeit für die Simulation eines Taktzyklus von 2 Hz erheblich lang sein.
EDIT: clk_2Hz_i dient zum Puffern des Ausgangssignals. VHDL verwendet kein Signal rechts von einer Zuweisung, wenn es auch ein Ausgang ist.
Nicht schlecht, aber Sie können unsigned mit integer hinzufügen / vergleichen, also: if prescaler = 50_000_000/4 then ...und prescaler <= prescaler + 1;wäre ein bisschen einfacher.
Brian Drummond
@StaceyAnne Wenn ich das versuche, erhalte ich die Meldung "Aus Objekt clk_o kann nicht gelesen werden; 'buffer' oder 'inout' verwenden". Habe ich etwas verpasst?
Ausweichen
@evading, ein Puffer am Ausgang wird benötigt. VHDL mag die Tatsache nicht, dass clk_2Hzes sich um eine Ausgabe handelt, aber ihr Wert wird in dieser Zeile gelesen clk_2Hz <= not clk_2Hz;. Ich habe im Update bearbeitet.
Stanri
+1 Tolles Beispiel. Aber hier zeigt sich meine Unwissenheit (neu bei VHDL). Was ist der Unterschied zwischen prescaler <= (others => '0');und prescaler <= '0';?
Cbmeeks
NVM! Ich habe total vermisst, wofür othersich ein VHDL-Buch gelesen habe. Es ist nur eine Abkürzung, um alle "anderen" Bits auf einen gemeinsamen Wert zu deklarieren, anstatt so etwas wie "0000000000000000 ..." zu verwenden.
cbmeeks
9
Verwenden Sie einen Clock Prescaler.
Ihr Vorteilswert ist Ihre (clock_speed / desired_clock_speed) / 2, also (50Mhz (50,000,000) / 2hz (2)) / 2 = 12,500,000, was in binär 101111101011110000100000 wäre.
Es scheint, als würden Sie zwei Takte erzeugen, einen mit 0,5 Hz und einen mit 1 Hz? (seit deiner uhrzeit ist dein prescaler * 2?). Außerdem gibt das "+" einen Fehler aus, da Sie slvs hinzufügen, und ich bin mir nicht sicher, ob ich die Überlaufeigenschaft von add auf diese Weise verwenden soll. warum nicht einfach gehen newClock : std_logic := '0', bis zu prescaler / 2 zählen und zuweisen newClk <= not newClk?
Stanri
Danke, meine Logik war ein bisschen abwegig. Ich habe meinen ersten Beitrag jetzt mit getestetem Code und ein paar Ihrer Vorschläge aktualisiert :)
MLM
Ugh - all diese Einsen und Nullen und ein Kommentar, um zu sagen, was es wirklich ist! Warum nicht den Compiler benutzen, um das für dich zu tun ??? Und warum nicht einfach ganze Zahlen verwenden?
Martin Thompson
Ich kann mich irren, aber ich denke, dass die Verwendung von Standardwerten bei der Definition von Signalen in einer Architektur wie ": = (others => '0')" nicht synthetisierbar ist.
Arturs Vancans
Es ist synthetisierbar, funktioniert aber grundsätzlich nur auf SRAM-basierten FPGAs, wie die meisten von Xilinx, Altera oder Lattice.
Yann Vernier
8
Normalerweise möchten Sie eigentlich nichts Langsames takten, erstellen Sie einfach eine Freigabe mit der richtigen Rate und verwenden Sie diese in der Logik:
Erstellen Sie ein paar Konstanten mit Ihrer Taktfrequenz und der gewünschten Aktivierungsfrequenz, und schon können Sie mit selbstdokumentierendem Code starten.
Es verfügt über eine grafische Einstellungsoberfläche, in der Sie die gewünschte Frequenz festlegen können. Es wird eine Komponente mit Ihrem gewünschten Ausgang als Frequenz erzeugt.
Es befindet sich im IP-Assistenten.
Und dann können Sie angeben, welche Frequenz Sie möchten:
Antworten:
Grundsätzlich gibt es zwei Möglichkeiten, dies zu tun. Der erste ist die Verwendung des nativen Xilinx-Clock-Synthesizer-Kerns. Dies hat unter anderem den Vorteil, dass die Xlinx-Tools die Uhr als solche erkennen und über die erforderlichen Pfade leiten. Die Tools werden auch alle zeitlichen Einschränkungen bewältigen (in diesem Fall nicht wirklich zutreffend, da es sich um einen 2-Hz-Takt handelt)
Die zweite Möglichkeit besteht darin, einen Zähler zu verwenden, um die Anzahl der schnelleren Taktimpulse zu zählen, bis die Hälfte Ihrer langsameren Taktperiode verstrichen ist. In Ihrem Fall beträgt die Anzahl der schnellen Taktimpulse, die eine Taktperiode eines langsamen Taktzyklus ausmachen, beispielsweise 50000000/2 = 25000000. Da wir eine halbe Taktperiode wünschen, sind dies 25000000/2 = 12500000 für jeden Halbzyklus . (die Dauer jedes Hochs oder Tiefs).
So sieht es in VHDL aus:
Dinge zu beachten:
EDIT: clk_2Hz_i dient zum Puffern des Ausgangssignals. VHDL verwendet kein Signal rechts von einer Zuweisung, wenn es auch ein Ausgang ist.
quelle
if prescaler = 50_000_000/4 then ...
undprescaler <= prescaler + 1;
wäre ein bisschen einfacher.clk_2Hz
es sich um eine Ausgabe handelt, aber ihr Wert wird in dieser Zeile gelesenclk_2Hz <= not clk_2Hz;
. Ich habe im Update bearbeitet.prescaler <= (others => '0');
undprescaler <= '0';
?others
ich ein VHDL-Buch gelesen habe. Es ist nur eine Abkürzung, um alle "anderen" Bits auf einen gemeinsamen Wert zu deklarieren, anstatt so etwas wie "0000000000000000 ..." zu verwenden.Verwenden Sie einen Clock Prescaler.
Ihr Vorteilswert ist Ihre (clock_speed / desired_clock_speed) / 2, also (50Mhz (50,000,000) / 2hz (2)) / 2 = 12,500,000, was in binär 101111101011110000100000 wäre.
Einfacher ausgedrückt : (50.000.000) / 2) / 2 = 12.500.000 In Binär umwandeln -> 101111101011110000100000
Hier ist ein Code, wie Sie vorgehen müssen: Verwenden Sie newClock für alles, wofür Sie 2 Hz benötigen ...
quelle
newClock : std_logic := '0'
, bis zu prescaler / 2 zählen und zuweisennewClk <= not newClk
?Normalerweise möchten Sie eigentlich nichts Langsames takten, erstellen Sie einfach eine Freigabe mit der richtigen Rate und verwenden Sie diese in der Logik:
Sie können die Freigabe folgendermaßen erstellen:
Erstellen Sie ein paar Konstanten mit Ihrer Taktfrequenz und der gewünschten Aktivierungsfrequenz, und schon können Sie mit selbstdokumentierendem Code starten.
quelle
Ich würde eher vorschlagen, mit Xilinx Primitice Digital Clock Manager IP .
Es verfügt über eine grafische Einstellungsoberfläche, in der Sie die gewünschte Frequenz festlegen können. Es wird eine Komponente mit Ihrem gewünschten Ausgang als Frequenz erzeugt.
Es befindet sich im IP-Assistenten.
Und dann können Sie angeben, welche Frequenz Sie möchten:
quelle
Faktor = Input-Signal-Frequenz / Output-Prescaler-Frequenz.
CE = Clock Enable. Es sollte ein eintaktiger (clk) breiter Impuls sein oder hoch, wenn er nicht verwendet wird.
Q = Ausgangssignal eines taktbreiten Impulses mit der gewünschten Frequenz.
quelle