【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;
相关推荐
小麦嵌入式3 小时前
FPGA入门(十一):受控线性序列机 UART 发送升级
stm32·单片机·嵌入式硬件·mcu·fpga开发·硬件工程
X_xcccc5 小时前
2026硬核拆解:高性能异构计算板卡选型指南
fpga开发
tju新生代魔迷2 天前
Verilog HDL 学习笔记(十)| 第10章 时序和延迟
笔记·学习·fpga开发
aprilaaaaa2 天前
(TC397 学习笔记)二、ICU和TIM的时钟计算
笔记·学习·fpga开发
X_xcccc2 天前
2026高端FPGA开发平台权威评测与选型指南
fpga开发
威嵌神州2 天前
军工加固计算机七大核心特性解析|国产化、宽温、强加固工程实现
嵌入式硬件·计算机网络·fpga开发
FPGA小迷弟2 天前
高云半导体深度解读:国产FPGA车规赛道的领跑者
fpga开发
努力搬砖的小H2 天前
FPGA应用技巧之Block Design基本使用方法
功能测试·fpga开发·zynq·block design
ALINX技术博客2 天前
【黑金云课堂】FPGA技术教程FPGA 基础:HDMI视频输入与环路输出实验
fpga开发·音视频
hahaha60162 天前
HLS高层次综合设计--axi之burst纠偏
开发语言·算法·fpga开发·c#