一、基本介绍
1.1引入
时钟IP核实现的功能:对输入的时钟实现信号的分频和倍频,或者调整相位
MMCM PLL:混合模式时钟管理和锁相环,他们可以对时钟网络进行系统级的时钟管理和控制
1.2时钟资源
全局时钟:专用的互连网络,降低时钟的偏斜,占空比的时间和功耗
xlinx在这设计了专用的时钟缓存和驱动结构,使得全局时钟到达FPGA的逻辑资源和存储资源RAM和I/O口的延迟非常低。
区域时钟:独立于全局时钟网络,只能驱动区域内部逻辑资源和I/O口
一个CMT包括一个MMCM和一个PLL

1.3结构视图
BUFG 16:全局时钟缓存
CMT Backbone:cmt的主干道
I/O Column:外部信号/时钟输入管脚
GT Column:FPGA内部高速串行收发器
重点:了解FPGA时钟被划分为多个区域,各个区域可以单独工作也可以通过时钟主干道进行联合工作

1.4单个区域放大图
BUFH相当于低配版BUFG,他只能通过HROW在左右相近的时钟区域工作
BUFR相当于低配版BUFH,他输出的时钟只能作用在自己的时钟区域
CC:时钟的专用引脚,能连接BUFG,BUFH等等

我们在看原理图可以看到,有些时候部分引脚会有SRCC和MRCC,他们都是时钟专用引脚,但是有些区别:
SRCC:只能作用于本时钟区域
MRCC:除了能作用于本时钟区域,还可以作用于相邻的时钟区域
P,N代表可以连接差分时钟输入,如果我们不是差分时钟,就连在P端

1.5CMT框图
BUFR:区域时钟缓存器
IBUFG(CC):时钟专用引脚
BUFG:全局时钟缓存器
GT:高速时钟收发器
BUFH:水平时钟缓存器

1.6MMCM内部框图
D:可编程的计数分频器
PFD:相位的频率检测器
CP:电荷泵
LF:环路滤波器
VCO:压控振荡器
Lock:锁信号,从低电平到高电平代表用户的输出时钟变成稳定状态了
MMCM相比PLL多了高级功能:分数倍频率综合,反向时钟输出,动态时钟相位调整

1.7PLL内部框图
MMCM相当于PLL升级款,PLL实现的功能MMCM都可以实现

1.8时钟IP核

二、IP核配置
1、IP核(clocking options)
按如图所示步骤,双击clocking wizard(时钟向导)

双击打开IP核
clock monitor是时钟监控,使能这个信号可以对输入的时钟做监控
primitive是用来选择我们所用的原理是MMCM还是PLL
frequency features:频率合成,如果勾选就可以输出不同频率的时钟
phase alignment:相位矫正
dynamic reconfig:动态的重配置
minimize power:低功耗,勾选后时钟精度会降低
jitter optimization:对一些抖动选项的设置,一般选balance平衡即可
input clock information:

对于input clock information,首先我们需要对input frequency(输入时钟频率)进行改动,我们一般情况下的时钟频率是mhz,然后source这部分,我们拉开详细目录,single ended clock capable pin表示单端时钟,different clock capable pin是差分时钟,global buffer:全局时钟缓存,no buffer:不添加缓存

2、IP核(output clocks)
这一部分是对输出时钟进行配置
第一个表格,output freq是写我们想要得到的输出时钟频率,actual是实际生成的时钟频率
phase是写我们想要相位的部分(180就代表反相)
duty cycle表示占空比
drives代表来源,默认选bufg走全局时钟网络
enable optional inputs里面reset表示是否添加复位信号,locked表示是否添加锁信号
reset type表示默认复位信号是高电平有效还是低电平有效

3、IP核(port renaming)
这部分是对locked信号做重命名的页面

4、IP核(MMCM setings)
其中clkfbout_mult_f表示我们对原信号进行了10倍频,下面的divide是表示对输出信号做了几分频

5、IP核(summary)
这部分对前面我们的操作做了总结,确认没问题即可创建ip核

我们确定无误直接生成,这部分run settings里面的number of jobs,你选的越大越好(似乎是看你电脑多线程处理的性能,直接拉最大就行)

后续需要改动可以在design source里面找到ip核双击打开修改即可。

三、例化IP核
先添加一个design source

然后,点击下方的IP source,instantiation template,双击clk_wize_0.veo

打开后一直往下划,找到例化模板,复制粘贴到我们刚刚创建好的模块里面

这边需要注意,我们一般写代码的时候,系统复位信号都是低电平有效,而刚刚我们设计的ip核中复位信号是高电平有效,所以我们需要连接取反的系统复位信号

这两部分都是一样的代码(前者观赏性好一点)
module ip_clk_wiz(
input sys_clk,
input sys_rst_n,
output clk_100m,
output clk_100m_180deg,
output clk_50m,
output clk_25m
);
wire locked;
clk_wiz_0 instance_name
(
// Clock out ports
.clk_out1(clk_100m), // output clk_out1
.clk_out2(clk_100m_180deg), // output clk_out2
.clk_out3(clk_50m), // output clk_out3
.clk_out4(clk_25m), // output clk_out4
// Status and control signals
.reset(~sys_rst_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(sys_clk) // input clk_in1
);
endmodule
四、编写仿真文件
1、编写testbench
首先,我们需要完成对这些信号定义,然后编写好时钟这些信号的初始化,然后编写时钟激励的代码,最后例化源代码就可以:
`timescale 1ns / 1ps
module tb_ip_clk_wiz();
reg sys_clk;
reg sys_rst_n;
wire clk_100m;
wire clk_100m_180deg;
wire clk_50m;
wire clk_25m;
always #10 sys_clk=~sys_clk;//50mhz输入时钟
initial begin //初始化仿真
sys_clk = 1'b0;
sys_rst_n=1'b0;
#200;
sys_rst_n=1'b1;
end
ip_clk_wiz u_ip_clk_wiz(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_100m(clk_100m),
.clk_100m_180deg(clk_100m_180deg),
.clk_50m(clk_50m),
.clk_25m(clk_25m)
);
endmodule
注意:需要将测试文件设置为simulation的顶层文件
2、观察测试图像
如果你需要观察的信号没出现,可以像这样add进观测图像中

这个播放键是持续运行直到程序结束(我们的测试文件没写结束符号,他会一直运行)
他左边的这个是重新运行
右边这个是运行10us
最右边的是重新加载(一般针对我们修改了testbench就点这个)
