Generieren Sie einen 40-MHz-Takt auf einem FPGA mit 100-MHz-Takt

Ich versuche, einen 40-MHz-Takt auf einem 100-MHz-FPGA zu generieren, und ich finde es eine Art Kampf mit Verilog-Code.

Ich habe die Uhr auf einen Pin umgeleitet, um die 100-MHz-Funktionalität zu überprüfen:

assign pin1= clock; //gives me a 100MHz clock
assign pin2= ~clock;  //gives me a 100MHz inverse clock

Der alwaysBlock:

reg clock1;
reg [4:0] prescaler1;

always @(posedge clk) begin
    if(reset==1'b1)begin
        clock1=1'b0;
        prescaler1=2'b0;
    end else begin
        if(prescaler1==2'b01) begin
            clock1=~clock1;
            prescaler1=1'b0;
        end else begin
            prescaler1=prescaler1+1'b1;
            clock1=clock1;
        end
    end
end

Das gibt mir 50, 25, 16,66 und 12,5 MHz, je nachdem, ob der Prescaler auf 0, 1, 2, 3 eingestellt ist.

Gibt es dafür einen Trick?

Es ist ein Zedboard Zynq-7000 Z-7020. Mit XPS können Sie 4 PL-Fabric-Clocks zuweisen, aber ich glaube, sie müssen in Vielfachen von 33 MHz liegen.

Was ist der Unterschied zwischen ARM_PLL, IO_PLL und DRR_PLL?

Hat das FPGA einen Taktphasenregelkreis im Inneren?
Wenn es eine PLL gibt, x4 mit der PLL, um 400 MHz zu erhalten, durch 10 teilen mit dem Prescaler oder einer externen Komponente, um 40 MHz zu erhalten?
Bitte geben Sie uns den FPGA-Gerätenamen an. FPGAs haben Clock Modifying Blocks (CMBs) wie DCMs, PLLs, MMCMs, um diese Aufgabe zu erledigen. Alle Anbieter stellen IP-Core-Generatoren bereit, um eine CMB-Komponente für Ihre Anforderungen zu generieren: ClockIn = 100 MHz, ClockOut0 = 40 MHz.

Antworten (4)

Der einfache Prescaler, den Sie implementiert haben, folgt der Formel

F Ö u T = F M A S T e R ÷ ( 2 ( 1 + P R e S C A l e R N ) )
wobei fMaster der 100-MHz-Haupttakteingang ist und prescalerN der Prescaler-Neuladewert ist. Es gibt keinen ganzzahligen Teiler von (100 MHz/2), der 40 MHz erzeugt. Dies ist eine Einschränkung bei der Implementierung des Vorteilers in einer programmierbaren Allzwecklogik.

Viele FPGAs enthalten spezialisierte Takterzeugungsblöcke wie PLL (Phase-Locked Loop). Hierbei handelt es sich um eine spezialisierte analoge Schaltung, die in FPGA-Silizium implementiert ist und so konfiguriert werden kann, dass sie mit einem schnelleren internen Takt als dem angewendeten Master-Takt läuft. Der externe 100-MHz-Takt kann also auf 200 MHz oder vielleicht bis zu 400 MHz verdoppelt werden. Die PLL verwendet ein Regelkreisprinzip ähnlich dem eines Operationsverstärkers, um aus einer stabilen externen Referenz mit niedrigerer Frequenz eine stabile höhere interne Frequenz zu erzeugen.

Einige Xilinx-FPGAs verfügen über DCM (Digital Clock Manager). Altera nennt so etwas eine "Megafunktion", wenn ich mich richtig erinnere, sollte es eine Megafunktion für PLL geben. Hängt davon ab, welches FPGA Sie verwenden. Konsultieren Sie das Hauptdatenblatt des FPGA.

Wenn Sie keine PLL haben, benötigen Sie einen durch 5 teilenden Zähler (bis 20 MHz), eine um 1,5 Zyklen verzögerte Version desselben (verwenden Sie die entgegengesetzte Taktflanke für 0,5 Zyklen) und ein XOR-Gatter (mit der korrigierten Version , ein ODER-Gatter reicht aus, da beide Signale nie gleichzeitig '1' sind)

Dadurch erhalten Sie ein 40-MHz-Signal mit einem konstanten Tastverhältnis von 40 % (aber nicht 50 % ... bearbeitet!).

NB: Das ODER-Gatter fügt einer geraden Taktteilung einen gewissen Versatz hinzu. Wenn Ihr FPGA über DDR-Register verfügt, können Sie das bereinigen.

process(clk)
variable count : natural range 0 to 4;
begin
  if rising_edge(clk) then
    if count = 4 then
      count  := 0;
      clk_20 <= '1';
    else
      count  := count + 1;
      clk_20 <= '0';
    end if;
    clk_20d1 <= clk_20;   -- delay, thanks to signal assignment semantics
  end if;
end process;

process(clk)
begin
  if falling_edge(clk) then
    clk_20d15 <= clk_20d1; -- +0.5 cycle delay
  end if;
end process;

clk_40 <= clk20 or clk_20d15;

Sollte einfach in Verilog zu übersetzen sein.

Ja, dafür gibt es einen Trick. Dies wird als Fractional Clock Division bezeichnet und oft mit einem Dual-Modulus-Prescaler durchgeführt .

Hier ist eine Webseite mit Beispielcode in VHDL (sorry, kein Verilog): Fractional-Clock-Division-Dual-Modulus

Mit diesen Techniken können Sie ein 40-MHz-Signal aus Ihrem 100-MHz-Takt herausholen, aber beachten Sie, dass der Jitter zunimmt und Sie möglicherweise ein Signal erhalten, das kein Tastverhältnis von 50 % hat.

Da Sie an einem FPGA arbeiten: Prüfen Sie, ob Ihr FPGA einen Digitaluhr-Manager enthält. Dies sind Hardware-Blöcke, die aus einem vorhandenen Takt eine Vielzahl von Frequenzen erzeugen können, indem sie die Frequenz zuerst multiplizieren und dann dividieren. Sie erhalten eine bessere Leistung aus einem Digitaluhr-Manager als aus einem handgeschriebenen Dual-Modulus-Prescaler.

Der beste Weg wäre eine PLL, wie in den anderen Antworten erwähnt - mit 4 multiplizieren, dann durch 10 dividieren. Sie könnten x2/5 tun, aber das bringt Ihnen keine 50% Einschaltdauer (möglicherweise kein Problem).


Aber um diese hinzuzufügen, gibt es eine zweite Option, wenn keine PLL verfügbar ist, die nicht empfohlen wird, da sie auf asynchroner Logik beruht. Das würde ungefähr so ​​gehen:

wire clock2x;
wire clock2xDelay;
assign clock2x = clock100M ^ clock2xDelay;
assign clock2xDelay = ...; //I need to be clock2x delayed by about 5ns

reg [2:0] divider;
always @ (posedge clock2x or posedge reset) begin
  if (reset) begin
    divider <= 3'b0;
  end else if (divider == 3'd4) begin
    divider <= 3'b0;
  end else begin
    divider <= divider + 3'b1
  end
end
assign clock50M = divider[1]; // 40% Duty cycle, 50MHz clock

Der obige Code ist nicht ganz vollständig - Sie werden feststellen, dass clock2xDelay noch nicht fertig ist. Im Grunde muss hier das Interessante passieren und es hängt von Ihrem Gerät ab. Sie müssen grundsätzlich genügend Verzögerung hinzufügen (durch Carry-Chain-Verzögerung, LUT-Verzögerungen usw.), damit das XOR einen Impuls erzeugt, der breit genug ist, um keine Timing-Fehler mit minimaler Impulsbreite zu verursachen. Dem Synthesizer muss auch gesagt werden, dass er die Verzögerungskette nicht wegoptimieren soll.

Dieser Code wird nicht empfohlen, da die asynchrone Verzögerung mit der Temperatur und den Geräteeigenschaften variiert und somit zu einer zittrigen Uhr führt.