【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;
相关推荐
逐梦之程1 小时前
FPGA-Vivado2017.4-建立AXI4用于单片机与FPGA之间数据互通
fpga开发
XINVRY-FPGA9 小时前
10CL016YF484C8G Altera FPGA Cyclone
嵌入式硬件·网络协议·fpga开发·云计算·硬件工程·信息与通信·fpga
嵌入式-老费21 小时前
产品开发实践(常见的软硬结合方式)
fpga开发
FakeOccupational1 天前
【电路笔记 通信】AXI4-Lite协议 FPGA实现 & Valid-Ready Handshake 握手协议
笔记·fpga开发
I'm a winner1 天前
FPGA+护理:跨学科发展的探索(五)
fpga开发
Turing_kun2 天前
基于FPGA的实时图像处理系统(1)——SDRAM回环测试
fpga开发
I'm a winner3 天前
新手入门Makefile:FPGA项目实战教程(二)
笔记·fpga开发
我爱C编程3 天前
基于FPGA的8PSK+卷积编码Viterbi译码通信系统,包含帧同步,信道,误码统计,可设置SNR
fpga开发·通信·8psk·帧同步·snr·卷积编码·维特比译码
I'm a winner3 天前
新手入门 Makefile:FPGA 项目实战教程(三)
fpga开发
范纹杉想快点毕业3 天前
嵌入式 C 语言编程规范个人学习笔记,参考华为《C 语言编程规范》
linux·服务器·数据库·笔记·单片机·嵌入式硬件·fpga开发