1、M序列产生电路
M序列产生以移位寄存器为基础,每次输出移位寄存器的最后一位,并更新数值,从而形成伪随机序列。
m_p:process(clk,reset)
begin
dataout<=shifter(7);
if (reset='0') then shifter<="00001111"; -——移位寄存器的初始值
elsif rising_edge(clk) then
shifter(7 downto 1)<=shifter(6 downto 0); ——输出最后一位
shifter(0)<=shifter(3) xor shifter(4) xor shifter(5) xor shifter(7); ——移位更新数据
end if;
end process;
```
(2)位时钟提取电路
为了程序的易读性以及编程的可控性,在编程实现位时钟同步提取电路的过程中主要使用状态机来完成。第一个状态机用来检测一段时间内两个上升沿之间的最小间隔,用来提取同步时钟
```
process(clk)
begin
if clk'event and clk='1' then
case state is
when 0=> min_reg<=20000000; ——设定最小值
state<=1;
when 1=> if m='1' and m_delay1='0' then ——当检测到M序列的上升沿
state<=2;
count2<=0;
end if;
when 2=> count1<=count1+1; ——探测时间范围控制
count2<=count2+1; ——两个上升沿之间的时间间隔
if m='1' and m_delay1='0' then
state<=3;
end if;
when 3=> if count2<min_reg then
min_reg<=count2;
end if;
if count1>=30000000 then
state<=4;
count1<=0;
else
state<=1;
end if;
when 4=> min_reg2<=min_reg;
if min_reg2=min_reg then ——为了防止跳变,使用一级寄存器,当连
min<=min_reg2; ——两次检测到相同的最小值,才输出
end if;
state<=0;
end case;
end if;
end process;
待检测到最小时间间隔后,可用时钟计数除
2作为同步时钟的周期,并根据
M
序列做相位同步。
process(clk)
begin
if clk'event and clk='1' then
case step is
when 0=>
period<=min+26;
step<=1;
when 1=> if m='1' and m_delay1='0' then ——检测
M
序列的上升沿
step<=2;
end if;
when 2=> if count3<period/4 then ——产生高电平
reclk<='1';
count3<=count3+1;
else
if count5<127 then ——每个M序列的周期同步一次相位
step<=3;
count3<=0;
count5<=count5+1;
else
step<=1;
count5<=0;
end if;
end if;
when 3=> if count4<period/4 then ——产生低电平
reclk<='0';
count4<=count4+1;
else
count4<=0;
if period>=min then
re<=period-min;
else
re<=min-period;
end if;
if re>37 then ——用来防止信号的不稳定带来的跳变
step<=0;
else
step<=2;
end if;
end if;
when others=> step<=0;
end case;
end if;
end process;
```
因为前级模拟电路中低通滤波器的频率响应不平整,造成相位的变化,加之FPGA在整除过程中对结果进行了舍位操作,导致测周法提取的时钟存在误差,所以在要求严格要求相位抖动的时候还是应该使用锁相环法,对于一位FPGA的菜鸟来说,锁相环的工作原理和实现方法值得我们去探究。