Antworten:
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