Table of Contents
Digitale Phasenregelschleifen (PLLs) in VHDL zu entwerfen ist eine grundlegende Fähigkeit für Ingenieure, die an Frequenzsynthese und Taktmanagement in digitalen Systemen arbeiten. PLLs sind wesentliche Komponenten, die bei der Synchronisierung von Signalen und der Erzeugung stabiler Frequenzen helfen, was sie in modernen elektronischen Geräten wie drahtlosen Transceivern, Datenkonvertern und digitalen Prozessoren von entscheidender Bedeutung sind. Im Gegensatz zu analogen PLLs bieten digitale PLLs (DPLLs) größere Flexibilität, Programmierbarkeit und Immunität gegen Prozessvariationen, was sie zur bevorzugten Wahl für System-on-Chip-Implementierungen macht. Dieser Artikel bietet eine umfassende, schrittweise Anleitung zum Entwerfen von DPLLs in VHDL, die theoretische Grundlagen, Kernkomponentendesign, Simulationstechniken und praktische Überlegungen für die Frequenzsynthese abdeckt. Ob Sie ein erfahrener FPGA-Entwickler sind oder ein Student, der neu im digitalen Design ist, DPLL-Implementierung wird erweiterte Takterzeugungs- und Taktwiederherstellungsfähigkeiten in Ihren Projekten freisetzen.
Digitale PLLs verstehen
Eine digitale PLL ist ein Rückkopplungssteuerungssystem, das die Phase eines Eingangsreferenzsignals mit der Phase eines erzeugten Ausgangssignals vergleicht, wobei das Ziel darin besteht, die Ausgangsphase mit dem Eingang auszurichten, wobei die Frequenz effektiv auf der Frequenz liegt. In einem geschlossenen Regelkreis stellt die DPLL die Frequenz eines digitalen numerisch gesteuerten Oszillators (NCO) kontinuierlich ein, bis die Phasendifferenz auf einen kleinen stationären Fehler abnimmt. Dieser Prozess stellt sicher, dass das Ausgangssignal auch bei Vorliegen von Rauschen oder Frequenzdrift mit der Referenz synchronisiert bleibt. Digitale PLLs werden in digitalen Systemen bevorzugt, da sie vollständig in Hardwarebeschreibungssprachen wie VHDL implementiert werden können, zu Gate-Level-Netlists synthetisiert und in FPGAs oder ASICs ohne externe analoge Komponenten integriert werden können.
Die grundlegende Architektur einer DPLL besteht aus vier Hauptblöcken: einem Phasendetektor, einem Schleifenfilter, einem NCO und einem Rückkopplungspfad. Der Phasendetektor berechnet die Differenz zwischen der Referenzphase und der Rückkopplungsphase. Dieses Fehlersignal wird durch das Schleifenfilter gefiltert, das typischerweise einen PI-Regler zur Einstellung der Schleifendynamik enthält. Das gefilterte Steuerwort steuert das NCO an, das den Ausgangstakt oder die Ausgangsform erzeugt. Der Ausgang wird an den Phasendetektor zurückgeführt, wodurch die Schleife geschlossen wird. Das Verständnis der Wechselwirkung dieser Blöcke ist für die Gestaltung einer stabilen und ansprechenden DPLL wesentlich.
Schlüsselkomponenten einer digitalen PLL
Bevor Sie in die VHDL-Implementierung einsteigen, ist es wichtig, die Funktion jeder Komponente zu verstehen und Kompromisse zu entwerfen.
Phasendetektor
Der Phasendetektor (PD) erzeugt ein Fehlersignal, das proportional zur Phasendifferenz zwischen Referenz- und Rückkopplungssignalen ist.
- Ein XOR-Phasendetektor: vergleicht zwei binäre Signale und gibt ein Signal aus, dessen mittlerer Tastgrad proportional zur Phasendifferenz ist. Es funktioniert am besten, wenn beide Signale 50% Tastgrade und eine Quadraturbeziehung haben (90° Phasenverschiebung).
- Phasenfrequenzdetektor (PFD): Ein PFD verwendet sequentielle Logik (z. B. zwei Flip-Flops und ein UND-Gatter), um sowohl Phasen- als auch Frequenzunterschiede zu erkennen. Es gibt Auf- und Abwärtsimpulse aus, die anzeigen, ob die Referenz die Rückkopplung leitet oder verzögert. Der PFD hat einen breiteren linearen Bereich (±2π) und kann sperren, selbst wenn die Frequenzen weit voneinander entfernt sind, was es zur bevorzugten Wahl für die Frequenzsynthese macht.
Schlaufenfilter
Bei einer digitalen PLL ist das Schleifenfilter üblicherweise ein digitales PI-Filter. Der Proportionalterm liefert eine sofortige Korrektur auf der Grundlage des Stromfehlers, während der Integralterm Fehler im Laufe der Zeit akkumuliert, um den Phasenversatz im stationären Zustand zu eliminieren. Die Koeffizienten des Filters (Kp und Ki) bestimmen die Schleifenbandbreite, die Sperrzeit und die Stabilität. Ein gut konzipiertes Schleifenfilter muss die schnelle Erfassung mit niedrigem Jitter ausgleichen.
Numerisch gesteuerter Oszillator (NCO)
Der NCO erzeugt die Ausgangswellenform - oft eine Rechteck- oder Sinuswelle - mit einer programmierbaren Frequenz. Er enthält typischerweise einen Phasenakkumulator, der bei jedem Taktzyklus ein Frequenzsteuerwort (FCW) hinzufügt. Der Ausgang des Akkumulators, der die momentane Phase darstellt, adressiert eine Lookup-Tabelle (LUT), in der Sinus- oder Kosinuswerte gespeichert sind. Alternativ kann der NCO für die Taktsynthese einfach das höchstwertige Bit des Phasenakkumulators ausgeben, um eine quadratische Welle mit einem Tastverhältnis von 50% zu erzeugen. Die Auflösung des NCO wird durch die Anzahl der Bits im Akkumulator (z. B. 32 Bit) bestimmt, was sehr feine Frequenzschritte ermöglicht.
Rückkopplungspfad
Der Rückkopplungspfad ist einfach: er leitet den NCO-Ausgang zurück zum Phasendetektor. In einigen Ausführungen kann ein Frequenzteiler in den Rückkopplungspfad eingesetzt werden, um der PLL die Erzeugung von Frequenzen zu ermöglichen, die Vielfache der Referenz sind (z. B. Ganzzahl-N-Synthese).
Entwerfen einer digitalen PLL in VHDL
Die Implementierung einer digitalen PLL in VHDL beinhaltet die Codierung jeder Komponente als separate Einheit und deren hierarchische Verbindung. Die folgenden Unterabschnitte enthalten VHDL-Designbeispiele für jeden Block, wobei der Schwerpunkt auf synthetisierbaren Konstrukten und Best Practices liegt.
Phasendetektor-Implementierung
Wir werden eine PFD implementieren, da sie robuster für die Frequenzsynthese ist. Die PFD verwendet zwei D-Flip-Flops, ein UND-Reset-Gatter und Aufwärts-/Abwärts-Ausgänge. Der VHDL-Code für eine einfache PFD ist unten dargestellt.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pfd is
port (
clk_ref : in std_logic;
clk_fb : in std_logic;
reset : in std_logic;
up : out std_logic;
down : out std_logic
);
end pfd;
architecture rtl of pfd is
signal q_ref, q_fb : std_logic;
begin
process(clk_ref, reset)
begin
if reset = '1' then
q_ref <= '0';
elsif rising_edge(clk_ref) then
q_ref <= '1';
end if;
end process;
process(clk_fb, reset)
begin
if reset = '1' then
q_fb <= '0';
elsif rising_edge(clk_fb) then
q_fb <= '1';
end if;
end process;
up <= q_ref and not q_fb;
down <= q_fb and not q_ref;
reset <= q_ref and q_fb; -- internal reset for both flip-flops
end rtl;
Bei dieser Ausführung wird das Signal FLT: 1 durch ein kombiniertes UND beider Flip-Flops angesteuert, wodurch sichergestellt wird, dass nach dem Eintreffen beider Flanken der Detektor schnell zurückgesetzt wird. Diese PFD gibt einen Impuls auf FLT: 2 aus, wenn die Referenz die Rückkopplung leitet, und einen Impuls auf FLT: 3 , wenn die Rückkopplung führt. Die Pulsbreite ist proportional zur Phasendifferenz.
Implementierung von Loop Filtern
Ein digitales PI-Filter kann mit einem Akkumulator und parallelen Multiplikatoren realisiert werden. Der Einfachheit halber wird angenommen, dass die PFD-Ausgänge in einen vorzeichenbehafteten Fehlerwert umgewandelt werden. Die Filterkoeffizienten sind so gewählt, dass sie einen Dämpfungsfaktor von 0,7 und eine Eigenfrequenz liefern, die die Sperrzeitanforderung erfüllt. Der VHDL-Code zeigt ein grundlegendes PI-Filter mit 16-Bit-signierter Arithmetik.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity loop_filter is
port (
clk : in std_logic;
rst : in std_logic;
phase_err: in signed(15 downto 0);
freq_ctrl: out signed(15 downto 0)
);
end loop_filter;
architecture rtl of loop_filter is
-- Coefficients: Kp = 0.25, Ki = 0.03125 (example values)
constant Kp : signed(15 downto 0) := to_signed(8192, 16); -- 0.25 in Q14
constant Ki : signed(15 downto 0) := to_signed(1024, 16); -- 0.03125 in Q14
signal integral : signed(31 downto 0) := (others => '0');
signal prop_term, int_term : signed(31 downto 0);
begin
process(clk, rst)
begin
if rst = '1' then
integral <= (others => '0');
elsif rising_edge(clk) then
integral <= integral + (phase_err * Ki); -- saturated accumulation
end if;
end process;
prop_term <= phase_err * Kp;
int_term <= integral(31 downto 16); -- truncate to 16-bit
freq_ctrl <= prop_term(15 downto 0) + int_term(15 downto 0);
end rtl;
In diesem Beispiel sind Koeffizienten im Festpunkt-Q14-Format dargestellt. Der Integralakkumulator ist 32 Bit, um Überlauf zu verhindern, und der Ausgang ist auf 16 Bit gekürzt. Dieses Filter steuert das Frequenzsteuerwort des NCO an.
NCO-Einführung
Der NCO erzeugt den Ausgangstakt. Für die Frequenzsynthese benötigen wir oft eine Rechteckwelle mit 50 % Tastverhältnis. Der Phasenakkumulatoransatz funktioniert gut. Der folgende VHDL-Code implementiert einen 32-Bit-NCO mit einem Taktausgang (der MSB des Akkumulators).
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity nco is
port (
clk : in std_logic;
rst : in std_logic;
freq_word: in unsigned(31 downto 0);
out_clk : out std_logic
);
end nco;
architecture rtl of nco is
signal accumulator : unsigned(31 downto 0) := (others => '0');
begin
process(clk, rst)
begin
if rst = '1' then
accumulator <= (others => '0');
elsif rising_edge(clk) then
accumulator <= accumulator + freq_word;
end if;
end process;
out_clk <= accumulator(31); -- MSB toggles at half the NCO frequency
end rtl;
Die Ausgangsfrequenz wird durch gegeben. Mit einem 32-Bit-Akkumulator wird eine Frequenzauflösung von bereitgestellt. Für die Sinuswellensynthese ersetzen Sie den Ausgang durch eine Lookup-Tabelle, die von den höherwertigen Bits des Akkumulators adressiert wird.
Integration und Top-Level Design
Sobald die einzelnen Module entworfen sind, erstellen wir eine Top-Level-Entität, die PFD, Schleifenfilter und NCO instanziiert. Der Rückkopplungspfad verbindet den NCO-Ausgang mit dem Rückkopplungseingang des PFD. Ein einfaches Top-Level-VHDL-Design ist unten gezeigt.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity digital_pll is
port (
ref_clk : in std_logic;
rst : in std_logic;
pll_out : out std_logic
);
end digital_pll;
architecture rtl of digital_pll is
signal up, down : std_logic;
signal phase_err_signed : signed(15 downto 0);
signal freq_ctrl : signed(15 downto 0);
signal fb_clk : std_logic;
begin
-- Convert up/down to signed error
phase_err_signed <= (to_signed(1, 16) when up='1') else
(to_signed(-1, 16) when down='1') else
(others => '0');
u_pfd : entity work.pfd
port map (
clk_ref => ref_clk,
clk_fb => fb_clk,
reset => rst,
up => up,
down => down
);
u_loop_filter : entity work.loop_filter
port map (
clk => ref_clk,
rst => rst,
phase_err => phase_err_signed,
freq_ctrl => freq_ctrl
);
u_nco : entity work.nco
port map (
clk => ref_clk,
rst => rst,
freq_word => unsigned(freq_ctrl),
out_clk => fb_clk
);
pll_out <= fb_clk;
end rtl;
In der Praxis kann ein ausgeklügelterer Phasendetektor (z. B. Zeit-Digital-Wandler) eine feinere Auflösung liefern. Schleifenfilter und NCO laufen auf demselben Referenztakt, was den Aufbau vereinfacht, aber die maximale Ausgangsfrequenz begrenzt. Für höhere Ausgangsfrequenzen kann ein separater Hochgeschwindigkeitstaktbereich verwendet werden.
Simulation und Verifikation
Die Simulation einer digitalen PLL ist entscheidend, um die Sperrzeit, Stabilität und Jitterleistung zu überprüfen. Ein VHDL-Testbench sollte eine Referenzuhr anwenden, die PLL sperren lassen und dann den Phasenfehler messen. Verwenden Sie das -Verfahren, um die Simulation nach einer angemessenen Zeit zu stoppen.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_digital_pll is
end tb_digital_pll;
architecture sim of tb_digital_pll is
signal ref_clk : std_logic := '0';
signal rst : std_logic := '0';
signal pll_out : std_logic;
constant T : time := 20 ns; -- 50 MHz reference
begin
ref_clk <= not ref_clk after T/2;
rst <= '1', '0' after 100 ns;
dut : entity work.digital_pll
port map (ref_clk, rst, pll_out);
-- verification process
process
begin
wait until rising_edge(rst);
wait for 1 us; -- allow lock
-- check frequency and phase
report "Simulation complete";
std.env.finish;
end process;
end sim;
Es können Simulationswerkzeuge wie ModelSim, Vivado Simulator oder GHDL verwendet werden. Es ist auch ratsam, umfangreiche Eckfallsimulationen mit jittered Referenzuhren und Power-Up-Transienten auszuführen. Eine hilfreiche Ressource für PLL-Simulationstechniken ist das Whitepaper zu PLL Simulation Best Practices von RF Centers.
Frequenzsynthese mit digitaler PLL
Wenn die DPLL einmal gesperrt ist, können wir sie für die Frequenzsynthese verwenden, indem wir das Frequenzsteuerwort des NCO ändern. In einer typischen Anwendung ist der Referenztakt ein stabiler Kristalloszillator, und der DPLL erzeugt einen Hochfrequenzausgang, der ein Vielfaches der Referenz ist. Für die Ganzzahl-N-Synthese kann ein Teiler im Rückkopplungspfad hinzugefügt werden. Für die Fraktional-N-Synthese wird der Rückkopplungsteiler moduliert (z. B. unter Verwendung eines Sigma-Delta-Modulators), um nicht-ganzzahlige Multiplikationsfaktoren zu erzielen. Digitale PLLs zeichnen sich bei der Fraktional-N-Synthese aus, weil das Frequenzsteuerwort des NCO in Echtzeit mit hoher Auflösung aktualisiert werden kann.
Die Beziehung zwischen der Ausgangsfrequenz und dem Steuerwort wird durch f out = (FCW / 2N* f clk gegeben, wobei N die Anzahl der Akkumulatorbits ist. Durch Variation von FCW kann der DPLL einen breiten Frequenzbereich erzeugen. In Frequency Hopping Spread Spectrum (FHSS)-Systemen kann der DPLL durch Aktualisierung von FCW Frequenzen innerhalb weniger Taktzyklen schalten, vorausgesetzt, die Schleifenbandbreite ermöglicht ein schnelles Einsetzen.
Für weitere Informationen zur digitalen Frequenzsynthese siehe den klassischen Text Phase-Locked Loops: Design, Simulation, and Applications von Roland E. Best (McGraw-Hill, 2007).
Praktische Überlegungen
Die Gestaltung eines DPLL, der zuverlässig in Hardware funktioniert, erfordert eine sorgfältige Aufmerksamkeit auf mehrere praktische Probleme.
Sperrzeit und Bandbreite
Die Sperrzeit eines DPLL ist umgekehrt proportional zur Schleifenbandbreite. Eine breitere Bandbreite sperrt schneller, erlaubt aber mehr Referenz-Sporndurchführung und Jitter. Eine schmale Bandbreite dämpft das Rauschen, dauert aber länger. Die Schleifenfilterkoeffizienten müssen auf die Anwendungsanforderungen abgestimmt werden. Beginnen Sie mit einem Dämpfungsfaktor von 0,707 (kritische Dämpfung) und passen Sie die Eigenfrequenz auf der Grundlage der akzeptablen Sperrzeit an. Verwenden Sie die Formel ω n ≈ 2 * π * (Bandbreite), um abzuwägen.
Jitter und Phase Noise
Digitale PLLs leiden unter Quantisierungsjitter aufgrund der endlichen Auflösung des NCO- und Phasendetektors. Eine Erhöhung der Akkumulatorbreite reduziert das Frequenzquantisierungsrauschen. Die Verwendung eines Multi-Bit-Phasendetektors (z. B. eines Time-to-Digital-Wandlers mit 10 s ps-Auflösung) verbessert das Phasenrauschen. Für Hochleistungsanwendungen sollten Sie einen Bang-Bang-Phasendetektor (binär) mit einem Hochgeschwindigkeits-Digitalschleifenfilter implementieren. Externe Referenzen mit niedrigem Phasenrauschen, wie z. B. Ofen-gesteuerte Kristalloszillatoren (OCXOs), verbessern auch den Gesamtjitter.
Stromverbrauch
Um die Leistung zu reduzieren, verwenden Sie Gatter-Uhren oder aktivieren Sie Signale für den NCO, wenn keine Frequenzumkonfiguration erforderlich ist. Moderne DPLL-Architekturen mit niedriger Leistung, wie z. B. solche, die Zeitbereichsverarbeitung verwenden, werden in der Forschungsarbeit von Chen et al. diskutiert.
Prozess-, Spannungs-, Temperaturvariationen (PVT)
Digitale Designs sind immuner gegen PVT-Variationen als analoge Schaltungen, aber der Schleifenfilterverstärkung und NCO-Frequenz hängen immer noch von der Systemuhr, die über Ecken variieren kann. Die Verwendung eines kleinen Abstands in Schleifenfilterkoeffizienten und die Durchführung einer statischen Zeitanalyse stellt sicher, dass die DPLL erfüllt Timing über alle Bedingungen. Simulation mit SDF (Standard-Delay-Format) Back-Annotation wird für die Abmeldung empfohlen.
Fortgeschrittene Themen
Für Ingenieure, die bereit sind, über die Grundlagen hinauszugehen, gibt es mehrere fortschrittliche DPLL-Topologien.
Volldigitale PLL (ADPLL)
Eine ADPLL ersetzt alle analogen Komponenten durch digitale Äquivalente, einschließlich eines Time-to-Digital-Wandlers (TDC) als Phasendetektor und eines digital gesteuerten Oszillators (DCO). Dieser Ansatz wird in Nanometer-CMOS für HF-Anwendungen weit verbreitet. Die VHDL-Design-Methodik erstreckt sich natürlich auf ADPLLs, indem ein TDC-IP-Block und eine Oszillatorsteuerschnittstelle hinzugefügt werden.
Fractional-N PLL mit Sigma-Delta Modulation
Fractional-N synthesis allows arbitrary frequency ratios, enabling fine frequency steps without reducing the phase detector frequency. The feedback divider's modulus is modulated by a sigma-delta modulator (SDM) to shape quantization noise away from the loop bandwidth. The SDM can be implemented in VHDL as a third-order error feedback structure. A tutorial on SDM-based fractional-N PLLs is available from Analog Devices.
Schlussfolgerung
Digitale phasengekoppelte Schleifen in VHDL für die Frequenzsynthese zu entwerfen ist eine anspruchsvolle, aber lohnende Aufgabe, die digitale Signalverarbeitung, Steuerungstheorie und Hardwaredesign kombiniert. Dieser Artikel hat die grundlegenden Komponenten - Phasendetektor, Schleifenfilter und NCO - mit synthetisierbaren VHDL-Beispielen und Simulationsstrategien behandelt. Durch das Verständnis dieser Bausteine können Sie robuste DPLLs erstellen, die stabile, hochfrequente Uhren für eine Vielzahl von Anwendungen erzeugen können. Denken Sie daran, Ihr Design immer durch Simulation zu überprüfen, praktische Kompromisse wie Sperrzeit und Jitter zu berücksichtigen und fortschrittliche Architekturen zu erkunden, um strenge Leistungsanforderungen zu erfüllen. Die Beherrschung des DPLL-Designs wird Ihre Fähigkeiten als Digitaldesigner erheblich verbessern.