FPGA实战(五)时钟IP核(MMCM PLL)
来自正点原子的学习笔记时钟IP核(MMCM PLL)1时钟资源简介2 硬件设计3时钟IP核的使用3.1 设计思路3.2 主要代码3.3 管脚分配3.4 生成比特流文件1时钟资源简介对输入的时钟进行倍频、分频、调整相位。全局时钟是一种专用的互联网络,可以降低时钟的偏斜、占空比的时钟、功耗区域时钟独立于全局时钟一个CMT包含了一个MMCM和一个PL。ZYNQ7020包括了4个CMT2 硬件设计实验目的
来自正点原子的学习笔记
(关于开发板资源的相关理论我不太懂)
(本文侧重于简单的理解和应用层面)
时钟IP核(MMCM PLL)
1时钟资源简介
时钟资源主要是对输入的时钟进行倍频、分频、调整相位。
全局时钟是一种专用的互联网络,可以降低时钟的偏斜、占空比的时钟、功耗
区域时钟独立于全局时钟
一个CMT包含了一个MMCM和一个PL。
ZYNQ7020包括了4个CMT
2 硬件设计
实验任务:输出不同频率的时钟,包括倍频、分频,以及时钟相位的偏移。
我们通过时钟IP核输出的时钟是连接到了扩展口上的引脚。
可以通过示波器来测试几个单口上的时钟,从而验证通过时钟IP核输出的时钟是否正确。
3时钟IP核的使用
3.1 创建和配置时钟IP核
赛灵思提供的IP核在这儿
接下来对IP核进行配置
通常保持默认就好了,不需要做额外的设置。
往下滑动继续配置
点击output clocks对输出的时钟进行配置。
再对输出的时钟进行命名
下面也保持默认,不进行修改
进行下一项port renaming配置(保持默认)
这是最后设置的总结,然后点击OK进行创建
然后弹出来的界面,选择IP核最大为4来生成,点击generate
然后进行等待
直到显示为ready
然后可以看到一个图标,表示已经生成好了。之后如果需要修改的话,直接双击图标,按照之前的步骤进行修改。
3.2 创建模块来例化时钟IP核
3.2.1 模块端口定义
//1 模块端口定义
module ip_clk_wiz(
input sys_clk , //系统时钟
input sys_rst_n , //系统复位,低电平有效
//输出时钟
output clk_100m , //100Mhz时钟频率
output clk_100m_180deg, //100Mhz时钟频率,相位偏移180度
output clk_50m , //50Mhz时钟频率
output clk_25m //25Mhz时钟频率
//注意最后一个端口信号不要添加逗号!
);
3.2.2 寻找IP核的资源:例化模板
然后这样点击来寻找IP核的资源
然后拷贝这一段在代码里(见图片)
,并做适当的修改,把连接的端口的名称对应修改
修改后为:
//1 先编写端口名
module ip_clk_wiz(
input sys_clk , //系统时钟
input sys_rst_n , //系统复位,低电平有效
//输出时钟
output clk_100m , //100Mhz时钟频率
output clk_100m_180deg, //100Mhz时钟频率,相位偏移180度
output clk_50m , //50Mhz时钟频率
output clk_25m //25Mhz时钟频率
//最后一个端口信号不用加上逗号,
);
//2 wire define声明信号
wire locked;
//MMCM/PLL IP核的例化
clk_wiz_0 instance_name
(
// Clock out ports
.clk_out1_100m(clk_100m), // output clk_out1_100m
.clk_out2_100m_180(clk_100m_180deg), // output clk_out2_100m_180
.clk_out3_50m(clk_50m), // output clk_out3_50m
.clk_out4_25m(clk_25m), // output clk_out4_25m
// Status and control signals
.reset(~sys_rst_n), // input reset低电平有效的复位信号
.locked(locked), // output locked
// Clock in ports
.clk_in1(sys_clk)); // input clk_in1
//其实就是把上面定义的端口信号,除了这次不用的locked之外,把下面括号里的都替换成上面对应的就行
endmodule
其实就是把上面定义的端口信号,除了这次不用的locked之外,把下面括号里的都替换成上面对应的就行
这样就例化好了时钟模块
3.3 仿真
到刚才那里模块已经例化完成,如果有开发板的话可以直接分配引脚过后,生成比特流文件然后用示波器测量各个引脚的输出信号。
但是这里,我们可以采用仿真来实现这些功能。
3.3.1 进入仿真
注意是左键点击Run Simulation,然后开始进行功能的仿真
(右键点击出来的是setting)
3.3.2 记录当时出的错
当时第一次弄得时候报错了,,,,也看不懂,不过以上代码都是第二次成功的代码,放心使用
此处记录一下
大概率时当时我直接复制粘贴的正点原子的代码的问题
信号这些不适配,
建议还是老老实实地把IP的那段资源复制过去,稍微调一调
3.3.3 创建仿真文件
然后就进入了这个界面
可以发现时钟和复位的信号都是蓝色的信号,说明是不定态
接下来就是给它添加激励文件,然后才能进行仿真
创建一个仿真文件,点击OK。
然后,在这个路径下就可以找到tb文件
3.3.4 编写tb文件/激励文件
值得注意的是!这一次,仿真的时候,**这一行语句不要删除!**与平时写源文件的时候不一样!
`timescale 1ns / 1ps
module tb_ip_clk_wiz();
//1 声明端口信号
reg sys_clk;
reg sys_rst_n;
wire clk_100m;
wire clk_100m_180deg;
wire clk_50m;
wire clk_25m;
//3 生成时钟的反转信号
always #10 sys_clk = ~sys_clk;
//延时10nm,时钟切换一次,这样系统时钟就是一个50Mhz的时钟了
//2 对时钟和复位进行初始化
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#200//延时200
sys_rst_n = 1'b1;
end
//4 对所要测试的模块进行例化 类似于函数调用
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
3.3.5 重新仿真
然后点击,重新登入仿真
这里的仿真同样没有出现。
之前点击run simulation 的时候,它是默认把ip_clk_wiz当成了顶层文件的,新输入的这个tb模块其实并没有添加进来。
这里需要我们先关掉,再重新进入仿真
SIMULATION,右键点击关掉
然后再重新进入
可以看到现在已经出现了这个tb文件了
所以说平时我们应该先添加tb文件再进行功能仿真!!!!!!!!!!!!
应该都很熟悉这个操作了,里面添加1约束文件(IO分配)2 源文件3 仿真文件
推荐这个操作!
3.3.6 仿真
3.3.6.1 基本操作
点击zoom fit显示所有的波形
是这个样子
然后运行10微妙
再点击zoom fit重新显示所有的波形
点击放大
这里还少了一个lock 的信号,我们把它添加进来。
然后点击重新运行
再运行10微妙,显示所有的波形
然后进行放大
然后继续放大
3.3.6.2 测量sys_clk信号的时钟频率
在测量开始之前,先提醒一下!为了结果!(也就是接下来第三张图的红色字部分!) 设置marker的时候,一定要在locker信号变为高电平之后!将黄色得线停留在sys_clk得上升沿,点击add marker ,添加一个标记
再点击另外一个上升沿,add marker
(等于说是要么选择一致,要么上升沿,要么下降沿,这样测出来就是一个周期。)
然后单击左边的线,可以看到下方多了一个黄色的条,可以看出间隔是20ns,说明sys_clk是50Mhz!!
3.3.6.3 测量clk_100m信号的时钟频率
先点击蓝色的线,右键选择delete all markers
点击100m的上升沿,添加一个蓝色的marker,再添加另一个上升沿的蓝色标记
可以看到,周期是10ns,说明是100Mhz。验证成功
3.3.6.4 测量clk_100m_180deg信号的时钟频率
刚好跟clk_100相位相反,说明OK
3.3.6.5 测量clk_50m信号的时钟频率
跟上面操作一样
3.3.6.6 测量clk_25m信号的时钟频率
然后关闭仿真的界面,可以选择保存
接下来进行开发板上验证设计
3.4 管脚分配
具体参见这个博客 Vivado 2018.3入门教程(二):逻辑编写+IO配置.
输出的时钟需要手动进行分配(其实就是改个名字,改个引脚号)
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
//输出的时钟
set_property -dict {PACKAGE_PIN B19 IOSTANDARD LVCMOS33} [get_ports clk_100m]
set_property -dict {PACKAGE_PIN C20 IOSTANDARD LVCMOS33} [get_ports clk_100m_180deg]
set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS33} [get_ports clk_50m]
set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports clk_25m]
3.5 生成比特流文件
见我之前的博客
Vivado 2018.3入门教程(三):生成比特流文件+硬件连接.
3.6 硬件连接
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)