一种可编程的全数字锁相环路的实现
摘要:介绍了一种基于FPGA可编程技术实现的用于无线通信实验系统的全数字锁相环路。详细叙述了其工作原理、工作性能、电路实现和仿真结果。
关键词:FPGA 全数字锁相环路 VHDL语言
锁相环路已在模拟和数字通信及无线电电子学等各个领域中得到了极为广泛的应用,特别是在数字通信的调制解调和位同步中常常要用到各种各样的锁相环。锁相就是利用输入信号与输出信号之间的相位误差自动调节输出相位使之与输入相位一致,或保持一个很小的相位差。最初的锁相环全部由模拟电路组成,随着大规模、超高速数字集成电路的发展及计算机的普遍应用,出现了全数字锁相环路。所谓全数字锁相环路,就是环路部件全部数字化,采用数字鉴相器(DPD)、数字环路滤波器(DLF)、数控振荡器(DCO)构成锁相环路。在用Altera公司的EPFl0K10TCl44-3芯片设计一种无线通信实验系统的FSK、DPSK、QAM调制解调器时,利用剩余的10%FPGA资源设计出了一种可编程全数字锁相环路,它成功地为该通信实验系统的调制解调器提供了64kHz、56kHz和16kHz三种精确、稳定的时钟信号。
1 全数字锁相环的电路设计
1.1 DPLL工作原理分析
所设计的全数字锁相环路的结构如图1所示。其中,数字鉴相器由异或门EXOR构成,数字环路滤波器由变模可逆计数器Q构成,数控振荡器由加/减脉冲控制器I/D和模N计数器组成。可逆计数器和加/减脉冲控制器的时钟频率分别是Mf0和2Nf0。这里f0是环路的中心频率,为64kHz。Mf0等于14336kHz,由晶振电路产生,它经模H计数器分频后得到2Nf0的时钟频率。异或门鉴相器用于比较输入信号IN64与数控振荡器输出信号OUT64的相位差,其输出信号ud作为可逆计数器的计数方向控制信号。当ud为低电平时,可逆计数器作“加”计数;反之,可逆计数器作“减”计数。当环路锁定时,IN64和OUT64正交,鉴相器的输出信号ud为50%占空比的方波。在这种情况下,可逆计数器“加”与“减”的周期相同,只要可逆计数器的模值K足够大(K>M/4),其输出端就不会产生进位或借位脉冲。这时,加/减脉冲控制器只对频率为2Nf0的时钟进行二分频,使IN64和OUT64的相位保持正交。在环路未锁定的情况下,若ud为低电平时,可逆计数器进行加计数,并产生进位脉冲作用到加/减脉冲控制器的“加”控制端INC,该控制器便在二分频过程中加入半个时钟周期;反之,若ud为高电平,可逆计数器进行减计数,并产生借位脉冲作用到加/减脉冲控制器的“减”输入端DEC,该控制器便在二分频的过程中减去半个时钟周期,这个过程是连续发生的。加/减脉冲控制器的输出经过模N计数器分频后,得到输出信号OUT64,它的相位不断受到调整控制,最终达到锁定状态。最后只要对OUT64进行4分频就能得到16kHz的输出信号OUTl6,对加/减脉冲控制器的输出进行P分频就能得到56kHz的输出信号OUT56。
图1
该全数字锁相环的三个输出信号的频率分别为64kHz、56kHz和16kHz,经过计算可确定锁相环的参数M、N和P。设H=8,因为Mf0=14336kHz=4×4×2×7×64kHz,故M=4×4×2×7=224。因为2Nf0=Mf0/H=4×4×2×7×64kHz/8=2×2×7×64kHz=2×2×8×56kHz,故N=14、P=16。
1.2 DPLL电路实现
1.2.1 数字鉴相器
数字鉴相器由异或门构成,并使用VHDL语言编程来实现。异或鉴相器比较输入信号IN64和输出信号OUT64之间的相位差,输出误差信号ud作为可逆计数器Q的计数方向信号。环路锁定时,ud为一个占空比为50%的方波,此时的绝对相位差为90°,因此异或鉴相器相位差极限为±90°。
图2
1.2.2 数字环路滤波器
数字环路滤波器由变模可逆计数器Q构成。在ud的控制下,当j=0时,Q对时钟Mf0进行“加”计数;当j=1时,Q对时钟Mf0进行“减”计数。可逆计数器的模数K可以通过Ka、Kb、Kc、Kd四个输入端进行预置,当Ka、Kb、Kc、Kd在0001~1110取值时,相应模数的变化范围是2 3~2 16。数字环路滤波器用VHDL语言编程实现,其程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count_zj is
port(clkl,j,Kd,Kc,Kb,Ka,en:in std_logic;
INC,DEC:out std_logic);
End count_zj;
architecture behave Of eonnt_zj is
signal cq,k,mo,k2,mo2,cql:std_logic_vector(16 downto 0);
signal caol,cao2,caoll,cao22,caolll,cao222:std_logic;
signal instruction,aa,q1,q2:std_lOgic_vector(3 downto 0);
begin
instruction<=Kd & Kc & Kb & Ka;
aa<=instruction+1;
with instruction select
mo<=“00000000000000111”when“0001”,
“0000000000000t111”when“0010”,
“000(0)0(000~11111”when“0011”,
“00000000000111111”when“0100”,
“00000000001111111”when“0101”,
“00000000011111111”when“0110”,
“00000000111111111”when“0111”,
“00000001111111111”when“1000”,
“00000011111111111”when“1001”,
“00000111111111111”when“1010”,
“00001111111111111”when“1011”,
“00011111111111111”when“1100”,
“00111111111111111”when“1101”,
“01111111111111111”when“1110”,
“11111111111111111”when“1111”,
“00000000000000111”when others;
with aa select
m02<=“00000000000000111”when“0001”,
“00000000000001111”when“0010”,
“00000000000011111”when“0011”,
“00000000000111111”when“0100”,
“00000000001111111”when“0101”,
“00000000011111111”when“0110”,
“00000000111111111”when“0111”,
“00000001111111111”when“1000”,
“00000011111111111”when“1001”,
“00000111111111111”when“1010”,
“00001111111111111”when“1011”,
“00011111111111111”when“1100”,
“00111111111111111”when“1101”,
“01111111111111111”when“1110”,
“11111111111111111”when“1111”,
“00000000000000111”when othels;
process(clkl,j,mo,en)
begin
if(clkl’event and clkl=‘1’)then
k<=mo;
k2<=mo+1;
if(ell=‘0’)then
cq<=“00000000000000000”;
cql<=mo2;
elSe
if(j=‘0’)then
if(cq=k)then
cao1<=‘1’;
cao2<=‘0’;
cq<=(others=>‘0’);
elSe
cao1<=‘0’;
cao2<=‘0’;
cq<=cq+‘1’;
cql<=cql+‘1’;
end if;
elsif(j=‘1’)then
if(cql=k2)theH
cao1<=‘0’;
cao2<=‘1’;
cql<=mo2;
elSe
cao1<=‘O’;
cao2<=‘O’;
cq<=cq-‘1’;
cql<=cql-‘1’;
end if;
end if;
end if;
end if;
end process;
process(clkl,cao1)
begin
cao111<=cao11 or cao1
if(clkl’event and clkl=‘1’)then
if(cao111=‘1’)then
ca011<=‘1’;
if(q1=“1111”)then
cao11<=‘O’;
q1<=“0000”;
elSe
q1<=q1+‘1’;
end if;
end if;
end if;
end process;
process(clkl,cao2)
beSin
cao222<=cao22 or cao2;
if(clkl’event and clkl=‘1’)then
if(ca0222=‘1’)then
cao22<=‘1’;
if(q2=“1111”)then
cao22<=‘0’;
q2<=“0000”;
e1Se
q2<=q2+‘1’;
end if;
eHd if;
end if;
end process;
INC<=gao11;
DEC<=cao222;
end behave;
1.2.3 数控振荡器
数控振荡器采用加/减脉冲控制器I/D和模N计数器实现,它的输出是一脉冲序列,周期受数字环路滤波器送来的进位或借位校正信号控制。图2是加/减脉冲控制器硬件电路图,该电路由四片7474芯片和一片JK触发器以及其它一些逻辑门构成。
javascript:window.open(this.src);" style="cursor:pointer;"/>