【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;
相关推荐
nanxl11 小时前
FPGA-DDS信号发生器
fpga开发·verilog·vivado
黄埔数据分析3 小时前
RecoNIC 入门:SmartNIC 上支持 RDMA 的计算卸载-FPGA-智能网卡-AMD-Xilinx
fpga开发
nanxl15 小时前
FPGA-数字时钟
fpga开发·verilog·vivado
尤老师FPGA18 小时前
LVDS系列9:Xilinx 7系可编程输入延迟(二)
单片机·嵌入式硬件·fpga开发
内有小猪卖1 天前
时序约束 记录
fpga开发
Cao1234567893211 天前
FPGA时钟设计
fpga开发
JNTeresa1 天前
锁存器知识点详解
fpga开发
Cao1234567893211 天前
FPGA基础之基础语法
fpga开发
一大Cpp1 天前
通过Quartus II实现Nios II编程
fpga开发
7yewh1 天前
Verilog 语法 (二)
fpga开发