Generieren Sie eine 100-Hz-Uhr aus einer 50-MHz-Uhr in Verilog


7

Ich habe eine DE0-Karte mit einer 50-MHz-Uhr, die ich in Verilog auf 100 Hz senken möchte. Könnte mir jemand mit dem Code helfen, um dies zu tun?


Sie können eine pll (z. B. in Qsys) verwenden, um eine Uhr zu generieren, die Sie benötigen.
Qiu

Antworten:


15

Erstellen Sie einen 18-Bit-Zähler. Jedes Mal, wenn 250.000 erreicht werden, schalten Sie einen Flip-Flop um. 50 MHz / 250.000 = 200 Hz. Wenn Sie einen Pin mit 200 Hz umschalten, erhalten Sie 100 Hz mit einem Tastverhältnis von 50 Prozent. Wenn Sie nur einen Impuls mit einer Wiederholungsfrequenz von 100 Hz benötigen, erstellen Sie einen 19-Bit-Zähler und erzeugen Sie einen Impuls, wenn er 500.000 erreicht.

Glücklicherweise sind 250.000 und 500.000 gerade Zahlen. Wenn Sie mit einem ungeraden Teiler ein perfektes Tastverhältnis von 50 Prozent erzeugen, müssen Sie den Ausgang bei einer steigenden Flanke ein- und bei einer fallenden Flanke ausschalten. Bei einem Xilinx-FPGA kann dies mit einem ODDR / ODDR2 und einem Zähler mit leichtem Kopfkratzen erfolgen, um die D0 / D1-Eingänge korrekt einzustellen. Dies funktioniert jedoch nur zum Senden des Signals aus dem Chip über einen E / A-Pin, da der Ausgang eines ODDR / ODDR2 nicht innerhalb eines Entwurfs verwendet werden kann. Ein Puls ist jedoch wirklich alles, was Sie in einem Design benötigen.

Das Generieren von Elementen mit einem nicht ganzzahligen Verhältnis ist komplizierter. Wenn es sich um einen rationalen Bruch handelt, können Sie möglicherweise eine PLL oder ein DDS verwenden, um entweder allein oder in Kombination mit einem Zähler zu helfen. Wenn es sich nicht um einen rationalen Bruch handelt, haben Sie mehr oder weniger kein Glück, es sei denn, Sie können ihn mit einem rationalen Bruch approximieren. Wenn eine PLL nicht verfügbar ist, nicht niedrig genug ist oder Sie aus einer Kombination aus PLL und Zähler nicht das richtige Verhältnis erhalten, können Sie einen gebrochenen DDS verwenden. Die Idee mit einem gebrochenen DDS ist, dass Sie einem Akkumulator bei jedem Taktzyklus eine Konstante hinzufügen und den Ausgang umschalten, wenn der Akkumulator überrollt. Dies erzeugt eine Ausgabe mit etwas Jitter, kann jedoch im Durchschnitt eine präzise Frequenz erzeugen. Um eine Rechteckwelle mit 50 Hz und 100 Hz und einem 32-Bit-Akkumulator zu erzeugen, müssen Sie lediglich 100 * 2 ^ 32 / 50e6 = 8589 hinzufügen. 93459 ~ = 8590 pro Taktzyklus. Das MSB des Akkumulators schaltet auf 50e6 / (2 ^ 32 * 8590) = 100.00076145 Hz um. Je größer der Akku, desto genauer ist dies. Die Frequenzauflösung eines 32-Bit-Akkumulators ist recht gut - wenn Sie um 1 LSB nach oben oder unten gehen, erhalten Sie entweder 98,989119 oder 100,012403 Hz. Sie erhalten jedoch eine Taktperiode von +/- 1 für den sogenannten deterministischen Jitter. Mit anderen Worten, die Flanken werden nach Taktperioden quantisiert und können daher bis zu 1/2 Taktperiode früh oder spät sein. Im Gegensatz zu normalem Jitter sehen Sie beim Betrachten von deterministischem Jitter auf einem Oszilloskop eine sehr bimodale Verteilung der Zykluszeiten mit zwei oder mehr diskreten Durchschnittswerten im Gegensatz zu einer glatten Verteilung. Da die .00076145 ein Offset und kein Durchschnitt ist, verschiebt sich die Phase langsam in Bezug auf den Systemtakt.

Beispielverilog zur Erzeugung von 100 Hz aus 50 MHz mit einem Tastverhältnis von 50%:

// generate 100 Hz from 50 MHz
reg [17:0] count_reg = 0;
reg out_100hz = 0;

always @(posedge clk_50mhz or posedge rst_50mhz) begin
    if (rst_50mhz) begin
        count_reg <= 0;
        out_100hz <= 0;
    end else begin
        if (count_reg < 249999) begin
            count_reg <= count_reg + 1;
        end else begin
            count_reg <= 0;
            out_100hz <= ~out_100hz;
        end
    end
end

Beispiel eines Verilogs zur Erzeugung eines 100-Hz-Wiederholungsimpulses von 10 ns aus einem 50-MHz-Takt:

// generate 100 Hz pulse chain from 50 MHz
reg [18:0] count_reg = 0;
reg out_100hz = 0;

always @(posedge clk_50mhz or posedge rst_50mhz) begin
    if (rst_50mhz) begin
        count_reg <= 0;
        out_100hz <= 0;
    end else begin
        out_100hz <= 0;
        if (count_reg < 499999) begin
            count_reg <= count_reg + 1;
        end else begin
            count_reg <= 0;
            out_100hz = 1;
        end
    end
end

Beispiel eines Verilogs zur Erzeugung eines 10-MHz-Ausgangs mit einem Tastverhältnis von 50% aus einem 250-MHz-Takt mit einem ODDR2 auf einem Spartan 6:

// generate 10 MHz from 250 MHz
// 25 cycle counter, falling edge interpolated
reg [4:0] count_reg = 0;
reg q0 = 0;
reg q1 = 0;

always @(posedge clk_250mhz or posedge rst_250mhz) begin
    if (rst_250mhz) begin
        count_reg <= 0;
        q0 <= 0;
        q1 <= 0;
    end else begin
        if (count_reg < 24) begin
            count_reg <= count_reg + 1;
        end else begin
            count_reg <= 0;
        end
        q0 <= count_reg < 12;
        q1 <= count_reg < 13;
    end
end

ODDR2
clk_10mhz_out_oddr2_inst
(
    .Q(clk_10mhz_out),
    .C0(clk_250mhz),
    .C1(~clk_250mhz),
    .CE(1),
    .D0(q0),
    .D1(q1),
    .R(0),
    .S(0)
);

Beispiel eines Verilog-Codes zum Erzeugen von 100 Hz aus 50 MHz mit einem Tastverhältnis von 50% unter Verwendung eines Akkumulators:

// generate 100 Hz from 50 MHz
reg [31:0] count_reg = 0;
wire out_100hz = count_reg[31];

always @(posedge clk_50mhz or posedge rst_50mhz) begin
    if (rst_50mhz) begin
        count_reg <= 0;
    end else begin
        count_reg <= count_reg + 8590; //(((100 * 1 << 32) + 50000000/2) / 50000000)
    end
end

Ich bin mir ziemlich sicher, dass ein DDS auf rationale Vielfache der Referenzen beschränkt ist, genau wie eine PLL. Wenn auch nur, weil die zur Programmierung verwendeten Register keine Möglichkeit haben, irrationale Zahlen auszudrücken. Die verfügbare Genauigkeit ist auf einem DDS möglicherweise höher, aber selbst eine PLL mit gebrochenem N und einem 16-Bit-Nenner ergibt eine Genauigkeit von mehr als 20 ppm, was besser ist als die Referenzgenauigkeit in vielen Designs.
Das Photon

Mit einem DDS können Sie tun, was Sie wollen, wenn es nicht genau sein muss. Ein 32-Bit-DDS, der 100 Hz aus 50 MHz erzeugt, liefert 100.00076145 Hz. Das sind 7,6 ppm. Dies ist ein Versatz und kein Durchschnitt, so dass dies je nach Anwendung ein Problem sein kann oder nicht - die Phase driftet sehr langsam. der Referenzoszillator.
Alex. Forencich

Ja, aber es ist immer noch ein rationales Vielfaches der Referenz, oder? Ihre Antwort implizierte, dass DDS nicht auf rationale Vielfache beschränkt sind. Wenn es eine Möglichkeit gibt, ein DDS so zu programmieren, dass es eine Ausgangsfrequenz von oder , würde mich das interessieren. fref/2fref/π
Das Photon

Ah ja, jetzt sehe ich, worauf du hinaus willst. Ein DDS ist immer noch ein rationaler Bruch, aber normalerweise können Sie mit einem DDS viel mehr Bruchbits erhalten als mit einer FPGA-basierten Bruch-PLL.
Alex. Forencich
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.