一、 概况
之前讲过了IP核的接口信号含义,本章节使用仿真来实现时钟动态相移。通过仿真示例来更清晰看懂始终动态相移的过程,并学会如何使用。
二、 仿真示例
之前我们讲述了Psclk、Psen、Psincdec、psdone这四个接口的含义,这次来建立仿真工程实现这个时钟动态相移的过程。
这四个信号的关系可以先用一个仿真来观察,以便确定psen拉高一个周期后,经过多少个psclk周期psdone会拉高。可以设计一个计数器cnt_psclk7:0,每经过一个psclk周期计数器的值+1,计数器的值等于 127时psen拉高一个周期(这个值尽量高点,因为我们不知道PLL中时钟偏移完成会用多久)。通过仿真观察在PLL中,计数器计数到多少的时候psdone会拉高,这样可以确定时钟偏移完成一次用的时间了。每拉高一次psen信号,cnt_psen的值+1,如果输入的时钟为100MHz,想要使它相移180度,需要使psen拉高560次。

以下作为仿真的顶层模块,在tb中只需要给出两个时钟及复位即可。
module top
(
// Clock out ports
output clk_5x,
output clk_1x,
// Status and control signals
input rst_n,
output locked,
// Clock in ports
input pixel_clk,
input clk_200M
);
always @(posedge clk_200M ) begin
if(!rst_n) begin
cnt_psclk <= 0;
end
else if (cnt_psen == 560) begin
cnt_psclk <= 0;
end
else begin
cnt_psclk <= cnt_psclk +1;
end
end
always @(posedge clk_200M ) begin
if(!rst_n) begin
cnt_psen <= 0;
end
else if (psen == 1) begin
cnt_psen <= cnt_psen +1;
end
end
always @(posedge clk_200M ) begin
if(!rst_n) begin
psen <= 0;
end
else if(cnt_psclk == 'd127)begin
psen <= 1;
end
else begin
psen <= 0;
end
end
clk_wiz_5x clk_wiz_5x_inst
(
// Clock out ports
.clk_1x(clk_1x), // output clk_1x
.clk_5x(clk_5x), // output clk_5x
// Dynamic phase shift ports
.psclk(clk_200M), // input psclk
.psen(psen), // input psen
.psincdec(1), // input psincdec
.psdone(psdone), // output psdone
// Status and control signals
.reset(!rst_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(pixel_clk)); // input clk_in1
仿真波形如图2所示:

在图2中可以看出,在第一次相位偏移后,clk_1x相对于pixel_clk向左移动了18ps。并且clk_cnt计数到13时完成了时钟相位偏移。
具体时序见图4,明显看出clk_1x相对于pixel_clk向左偏移了18ps。


图4为偏移559次时,输入时钟与输出时钟的相位关系,可见还差1次,时钟可以偏移到最初位置。也就是说偏移560次后时钟相位回到最初位置。仿真中输入的时钟为100MHz,所以可以计算出偏移的次数,但实际代码中,我们不知道输入的时钟具体频率,不过不影响实现功能。在工程里实现偏移的时候,计数器需要每计数最少13次拉高一次psen。
三、总结
通过仿真确定了 PSDONE 的响应延迟,为实际代码中合理安排 PSEN 的拉高间隔提供了依据(至少间隔 13 个 PSCLK 周期)。
尽管实际输入时钟频率可能不同,但仿真方法可通用,只需根据具体频率重新计算所需步进次数,或通过连续调整直到达到预期相位效果。
本次实验为后续 HDMI 数据收发中精确调整时钟相位、满足数据建立/保持时间要求奠定了实践基础,强化了对动态相移机制的理解与工程实现能力。
本文章由威三学社威三学院出品
对课程感兴趣可以私信联系