本例程将添加按键消抖模块与设计 PLL 调相模块,通过按键 SW1 和按键 SW2 用以触发调整输出时
钟相位。 具体现象可以将 PLL 动态相位调整例程加载到开发板上进行查看。
1.实验说明
管脚说明
本实验不需要外部模块,在PotatoPie上就能进行。
set_pin_assignment { sys_clk } { LOCATION = P11; }
set_pin_assignment { I_key_in_0 } { LOCATION = P83; }
set_pin_assignment { I_key_in_1 } { LOCATION = P45; }
set_pin_assignment { sys_rst_n } { LOCATION = P84; }
set_pin_assignment { O_clk0 } { LOCATION = P10; }
set_pin_assignment { O_clk1 } { LOCATION = P12; }
- clk_osc,PLL参考时钟输入
- I_key_in_0,按键SW1
- I_key_in_1,按钮SW2
- O_clk0,第一路输出时钟
- O_clk1,第二路输出时钟
实验现象
编译下载 FPGA 的位流文件,将输出时钟通过 IO 接口连接示波器,通过示波器显示相位随按键按下
的次数变化不断变化,具体实物演示如下图所示。
2. 原理说明
PotatoPie 板上的EG4 FPGA内嵌多功能锁相环(PLL),EG4 系列 FPGA 最多内嵌有 4 个多功能锁相环( PLL0~PLL3),可实现高性能时钟管理功能。每个PLL 都能实现时钟分频/倍频/输入和反馈时钟对准/多相位时钟输出功能。用户在使用中应关注 PLL 的 Lock 信号是否为高,同时建议用户等待输入信号稳定后,再给锁相环进行复位以保证锁相环输出时钟信号的频率和相位。PLL 参考时钟输入有:时钟网络输出、互连输出和内部振荡器输出。PLL 反馈时钟输入有:时钟网络输出、内部寄存器时钟节点、互连输出、 PLL 内部反馈时钟以及相移时钟 C0~C4。
内嵌多功能锁相环(PLL),可以实现时钟分频、倍频、占空比调整、输入和反馈时钟对准、多相位时钟输出、动态相移等功能,其中 PLL 动态调整相位例程便是利用了 PLL 的动态相移功能。 动态相移特性允许对锁相环的每个独立输出相位进行动态调整,通过对给定的计数器递增或递减实时改变输出时钟相。每次移动相位为 1/8 VCO 周期。多功能锁相环(PLL)是一个相位误差的控制系统,通过比较参考信号和输出信号之间的相位,产生相位误差来调整输出信号,来实现与参考信号同频或倍频等功能的目的。其中 MINI DEMO 板 PLL 的
架构图如下图所示。
该 PLL 支持 4 种时钟反馈模式,包括源同步模式(Source Synchronous Mode)、无补偿模式(No
Compensation Mode)、普通模式(Normal Mode)以及零延迟缓冲模式(Zero Delay Buffer Mode),
这四种模式每种都支持时钟分频/倍频和相移。本例程使用普通时钟反馈模式,在普通模式中, PLL 会补偿 GCLK 网络延迟,保证内部寄存器输入时钟相位和时钟管脚相位一致。本例程需要实现动态相移功
能,具体实现动态相移的控制信号如下表所示。
表 4-3-1 动态相移控制信号
信号名称 | 描述 |
PSCLKSEL | 要进行动态移相的时钟选择信号 |
PSDOWN | 动态相移方向选择, 1=向上, 0=向下 |
PSSTEP | PSSTEP=1,使能动态相移 |
PSCLK | 动态相移时钟 |
PSDONE | 信号为高电平时,表明相位调整结束 |
通过对上述信号时序的调整实现 PLL 动态调相功能,具体进行 PLL 动态调相各信号时序如下图所
示。
动态相移静态配置参数包括:参考/反馈时钟输入/输出选择、参考时钟分频系数(M)、反馈时钟
分频系数(N)、输出时钟分频系数(CO-4),其中参考时钟输入为系统时钟,参考时钟分频系数为 1,
输出时钟分频系数为 CO 和 C1,具体配置参数如下图所示。
3.代码说明
代码层次图如下
key_filter.v就是之前用过的按键消抖模块,这里不再赘述。
PLL.v就是要动态配置的锁相环
pll_control.v是动态配置PLL的功能模块,也是本实验要重点分析的代码。
module pll_control(
input wire I_clk,
input wire I_rst,
input wire I_key_pulse_0,
input wire I_key_pulse_1,
input wire I_psdone,
output reg O_led_0,
output reg O_led_1,
output wire[2:0] O_psclksel,
output reg O_psdown,
output reg O_psstep
);
I_psdone,信号为高电平时,表明相位调整结束
O_led_0,O_led_1实际示用。
O_psclksel,要进行动态移相的时钟选择信号
O_psdown,动态相移方向选择, 1=向上, 0=向下
O_psstep,PSSTEP=1,使能动态相移
动态相位方向选择 I_key_pulse_0:I_key_pulse_1:向下
always@(posedge I_clk or posedge I_rst)begin
if(I_rst)
O_psdown <= 1'b0;
else if(I_key_pulse_0)
O_psdown <= 1'b1;
else if(I_key_pulse_1)
O_psdown <= 1'b0;
else
O_psdown <= O_psdown;
end
检测PSSTEP 边沿
assign S_psstep_nedge = (~O_psstep) && S_psstep_d;
assign S_psstep_pedge = O_psstep && (~S_psstep_d);
延长按键使能
always@(posedge I_clk or posedge I_rst)begin
if(I_rst)
S_clk_switch <= 2'b00;
else if(S_key_pulse_d0)
S_clk_switch <= 2'b01;
else if(S_key_pulse_d1)
S_clk_switch <= 2'b10;
else if(S_sclk_cnt_f == 6'd3)
S_clk_switch <= 2'b11;
else
S_clk_switch <= S_clk_switch;
end
//选择是否使能动态调相
always@(*)begin
case(S_clk_switch)
2'b01:begin
O_psstep= 1'b1;
end
2'b10:begin
O_psstep= 1'b1;
end
2'b11:begin
O_psstep= 1'b0;
end
default:begin
O_psstep= 1'b0;
end
endcase
end
没有回复内容