【FPGA开发】Xilinx锁相环IP核仿真输出初始有一段高电平引发的思考与探究

现象

本来是在通过Xilinx提供的 Clocking Wizard IP核做有关锁相环的实验,在Vivado中的仿真结果如下:

后面输出的时钟波形是对的,但4路输出前确有一小段高电平,仔细放大看一下:

这个高电平持续了一个周期,这就奇怪了,无论是源代码还是仿真代码,都不涉及到它们四个wire类型的变量的初值之类的。

原始代码

源代码:

verilog 复制代码
module ip_clk_wiz(
    input  sys_clk_p,
    input  sys_clk_n,
    input  sys_rst_n,
    output o_pll_clk
    );

wire clk_out1;
wire clk_out2;
wire clk_out3;
wire clk_out4;

assign o_pll_clk = clk_out4;
    
clk_wiz_0 instance_name(

    .clk_out1  (clk_out1  ),
    .clk_out2  (clk_out2  ),
    .clk_out3  (clk_out3  ),
    .clk_out4  (clk_out4  ),
               
    .reset     (~sys_rst_n),
    .locked    (          ),

    .clk_in1_p (sys_clk_p ),
    .clk_in1_n (sys_clk_n )
    );
    
endmodule

tb代码:

verilog 复制代码
`timescale 100ps / 100ps
 
module tb_ip_clk_wiz();

reg sys_clk_p;
reg sys_clk_n;
reg sys_rst_n;

initial begin
    sys_clk_p <= 1'b0;
    sys_clk_n <= 1'b1;
    sys_rst_n <= 1'b0;
    #1000
    sys_rst_n <= 1'b1;
end

always begin
    sys_clk_p <= 1'b0;
    sys_clk_n <= 1'b1; 
    #25;
    sys_clk_p <= 1'b1;
    sys_clk_n <= 1'b0;        
    #25;
end

ip_clk_wiz u_ip_clk_wiz(
    .sys_clk_p   (sys_clk_p),
    .sys_clk_n   (sys_clk_n),
    .sys_rst_n   (sys_rst_n),
    
    .o_pll_clk   ()
    );   
     
endmodule

探究

一开始想着,是不是跟 IP 核的高电平复位有关,因为初始的复位是有效的,对于IP核就一直处于复位状态,然后干脆就IP核的复位都直接不接了,但还是会有这么一段高电平。

然后,尝试把 IP 核的例化注释掉,结果如下:

这样似乎就合乎常理了,因为 wire 类型变量按照语法,在仿真开始时,wire 变量的值是不确定的(通常表现为高阻态或未定义值,即 x 或 z ),这里就是表现为 z 高阻态。

想到这我接着探究,既然IP核的例化都注释掉了,那再用 modelsim 仿真一下,看看,结果如下:

与 Vivado 的结果相同。

综合以上的尝试,我们可以知道,出现最开始现象的原因应该是与 IP 核有关,不过结合 testbench 文件仔细研究一下那个输出:

​ 在 t=100ns 复位变为高电平,对于IP而言,开始有效输出,但根据波形可以看出,最终的有效时钟信号是在 200ns 以后产生的,这是因为,IP 核要获取稳定地输出需要一定的时间,与此同时也让人联想到了我前面源代码中没有接的 locked 信号,Xilinx 对它的解释如下:

即只有稳定了以后,才会把它拉高有效,我们继续仿真试试看,把这个信号加进来。

可以发现这个信号会在我们之前看到的有效时钟出来之后才会拉高,也进一步验证了前面的观点。对于我们的启示是,在实际使用 Clocking Wizard IP核时,最好是在判断 lock 信号拉高后再使用它输出的时钟,不然可能会出现一些隐蔽的隐患。

后来看正点原子的视频时发现,它们也提到,实际使用时,可以再给一个内部的复位信号采用以下逻辑给出这个复位信号,然后在这个复位信号有效的情况下再去进行一些用到PLL输出的时钟的操作。

verilog 复制代码
wire        locked;
wire        rst_n;
assign rst_n = sys_rst_n & locked;
相关推荐
电棍2339 小时前
verilog笔记
笔记·fpga开发
ZxsLoves20 小时前
【【Systemverilog学习参考 简单的加法器验证-含覆盖率】】
学习·fpga开发
Ronin-Lotus1 天前
嵌入式硬件篇---数字电子技术中的触发器
嵌入式硬件·fpga开发·触发器·数字电子技术·上位机知识
ehiway2 天前
FPGA+GPU+CPU国产化人工智能平台
人工智能·fpga开发·硬件工程·国产化
蓑衣客VS索尼克2 天前
什么是逻辑分析仪?
arm开发·人工智能·fpga开发
Terasic友晶科技3 天前
第29篇 基于ARM A9处理器用C语言实现中断<五>
c语言·fpga开发·定时器中断
9527华安3 天前
FPGA实现GTY光口视频转USB3.0传输,基于FT601+Aurora 8b/10b编解码架构,提供2套工程源码和技术支持
fpga开发·音视频·aurora·gty·usb3.0·ft601
博览鸿蒙3 天前
FPGA开发要学些什么?如何快速入门?
fpga开发
@晓凡3 天前
FPGA中利用fifo时钟域转换---慢时钟域转快时钟域
fpga开发
乘风~&3 天前
fpga助教面试题
fpga开发