来自正点原子的学习笔记
(关于开发板资源的相关理论我不太懂)
(本文侧重于简单的理解和应用层面

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 硬件连接

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐