PotatoPie 4.0 实验教程(4) —— FPGA实现PLL动态调整相位-Anlogic-安路社区-FPGA CPLD-ChipDebug

PotatoPie 4.0 实验教程(4) —— FPGA实现PLL动态调整相位

本例程将添加按键消抖模块与设计 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 接口连接示波器,通过示波器显示相位随按键按下
的次数变化不断变化,具体实物演示如下图所示。

20231220155737179-image

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
架构图如下图所示。
 

20240329105210340-image

20240329105250605-image

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 动态调相各信号时序如下图所
示。

20231220155555357-image

动态相移静态配置参数包括:参考/反馈时钟输入/输出选择、参考时钟分频系数(M)、反馈时钟
分频系数(
N)、输出时钟分频系数(CO-4),其中参考时钟输入为系统时钟,参考时钟分频系数为 1
输出时钟分频系数为
CO C1,具体配置参数如下图所示。

20231220155610799-image

3.代码说明

代码层次图如下

20240329105657777-image

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
请登录后发表评论

    没有回复内容