FPGA的学习分享--03 时钟IP核

需要掌握:
1.博宸电子ZYNQ7020DEV开发板
2.Vivado 2018.3
3.一定的verilog语法基础

一.任务剖析

1.1 实验任务

通过引入时钟IP核,实现01节led流水灯的速率加快一倍和减小一倍。

1.2 时钟IP核简介

1.2.1 个人理解

在我看来,时钟IP核就是产生多个时钟的“芯片”。将系统时钟输入此芯片,时钟IP核会根据每个人配备的要求,生成不同的时钟。

不同点在于:1.时钟频率 2.占空比


“当然,特别专业的术语还请读者朋友们在网上搜索一下。因为我本人只是一名大二学生,还不能做到说出那么专业的话语。我也不想进行复制粘贴这一没有意义的工作。我只想在这里分享我在学习此开发板的过程和个人的一些理解,是从一名学习者的视角编写的博客,还请各位大佬见谅。”


基于本实验目的,我们可以利用时钟IP核输出两个时钟A,B。时钟A的频率应该是系统时钟频率的二倍(100MHZ)
时钟B的频率应该是系统时钟频率的一半(25MHZ)

1.2.2 时钟IP核的创建

在这里插入图片描述
双击箭头3中的选项,出现下图
在这里插入图片描述
配置界面与上图一致。然后点击Output Clocks.进行输出时钟的配置。命名最好带有时钟特点。
在这里插入图片描述
配置完成后,下拉界面,选择复位低电平有效。这里主要是想与之前的理解保持一致。
在这里插入图片描述
然后点击OK,这样你就拥有了属于自己的第一个时钟IP核。


之后在软件中间区域的Sources中打开下图的蓝色文件。
在这里插入图片描述


会看到出现了如图所示代码,接下来只需要将这个模块例化到之前所创建的led流水灯代码中即可。
不过这里为了和01节作出区分,博主新建了一个文件,并命名为pll_clock_stream。本文的代码编写和例化均在这一文件下进行。
在这里插入图片描述

二. 实验代码

2.1 代码内容

2.1.1 原速率

module pll_clock_stream(
  input			     sys_clk,
  input 		     sys_rst_n,
  
  output reg [3:0]   led       //设置为寄存器类型,否则第二个always模块会报错
  );

//定义一个1s的计时器,时钟频率为50MHz
reg [25:0] cnt;


//定义时钟IP核的不同频率时钟
wire  clk_out100M;
wire  clk_out25M;

//系统时钟sys_clk --> 50MHZ
always @(posedge sys_clk or negedge sys_rst_n) begin
		if (!sys_rst_n)
		cnt <= 26'd0;
		else if(cnt < 26'd5000_0000)
		cnt <= cnt + 1'b1;
		else cnt <= 26'd0;
end

//通过计时器控制led交替闪烁,1s内闪烁4个灯	
always @(cnt) begin
		if(cnt<26'd1250_0000) led <= 4'b0001;
		if(cnt<26'd2500_0000 && cnt >= 26'd1250_0000) led <= 4'b0010;
		if(cnt<26'd3750_0000 && cnt >= 26'd2500_0000) led <= 4'b0100;
		if(cnt<26'd5000_0000 && cnt >= 26'd3750_0000) led <= 4'b1000;
end

clk_wiz_0 u_clk_wiz_0(
        .clk_out100M                 (clk_out100M), 
        .clk_out25M                  (clk_out25M),  
        
        .resetn                      (sys_rst_n),      
        .locked                      (),      
        
        .clk_in1                     (sys_clk)      

);

endmodule

2.1.2 加快一倍

module pll_clock_stream(
  input			     sys_clk,
  input 		     sys_rst_n,
  
  output reg [3:0]   led       //设置为寄存器类型,否则第二个always模块会报错
  );

//定义一个1s的计时器,时钟频率为50MHz
reg [25:0] cnt;


//定义时钟IP核的不同频率时钟
wire  clk_out100M;
wire  clk_out25M;

//系统时钟clk_out100M --> 100MHZ
always @(posedge clk_out100M or negedge sys_rst_n) begin
		if (!sys_rst_n)
		cnt <= 26'd0;
		else if(cnt < 26'd5000_0000)
		cnt <= cnt + 1'b1;
		else cnt <= 26'd0;
end

//通过计时器控制led交替闪烁,1s内闪烁4个灯	
always @(cnt) begin
		if(cnt<26'd1250_0000) led <= 4'b0001;
		if(cnt<26'd2500_0000 && cnt >= 26'd1250_0000) led <= 4'b0010;
		if(cnt<26'd3750_0000 && cnt >= 26'd2500_0000) led <= 4'b0100;
		if(cnt<26'd5000_0000 && cnt >= 26'd3750_0000) led <= 4'b1000;
end

clk_wiz_0 u_clk_wiz_0(
        .clk_out100M                 (clk_out100M), 
        .clk_out25M                  (clk_out25M),  
        
        .resetn                      (sys_rst_n),      
        .locked                      (),      
        
        .clk_in1                     (sys_clk)      

);

endmodule

2.1.3 减小一倍

module pll_clock_stream(
  input			     sys_clk,
  input 		     sys_rst_n,
  
  output reg [3:0]   led       //设置为寄存器类型,否则第二个always模块会报错
  );

//定义一个1s的计时器,时钟频率为50MHz
reg [25:0] cnt;


//定义时钟IP核的不同频率时钟
wire  clk_out100M;
wire  clk_out25M;

//IP时钟clk_out25M --> 25MHZ
always @(posedge clk_out25M or negedge sys_rst_n) begin
		if (!sys_rst_n)
		cnt <= 26'd0;
		else if(cnt < 26'd5000_0000)
		cnt <= cnt + 1'b1;
		else cnt <= 26'd0;
end

//通过计时器控制led交替闪烁,1s内闪烁4个灯	
always @(cnt) begin
		if(cnt<26'd1250_0000) led <= 4'b0001;
		if(cnt<26'd2500_0000 && cnt >= 26'd1250_0000) led <= 4'b0010;
		if(cnt<26'd3750_0000 && cnt >= 26'd2500_0000) led <= 4'b0100;
		if(cnt<26'd5000_0000 && cnt >= 26'd3750_0000) led <= 4'b1000;
end

clk_wiz_0 u_clk_wiz_0(
        .clk_out100M                 (clk_out100M), 
        .clk_out25M                  (clk_out25M),  
        
        .resetn                      (sys_rst_n),      
        .locked                      (),      
        
        .clk_in1                     (sys_clk)      

);

endmodule

2.2 分析

仔细阅读上述三个代码,其主要逻辑与01节都是相同的。只是将时钟的频率改为100MHZ和25MHZ,而这一功能的实现,依靠的就是时钟IP核。

例化”是将时钟IP核和实验代码相连接的桥梁,通过对应端口连接,将时钟IP核输出的clk_out100M时钟引入到实验代码中,令其成为计数器cnt计数时钟上升沿的时钟。又因为clk_out100M的频率恰好是系统时钟sys_clk的2倍,自然cnt计数就快了原先的一倍,也就达到了流水灯速率提高一倍的实验目的。(减小一倍也是同理,只不过clk_out25M是系统时钟频率的一半罢了)

clk_wiz_0 u_clk_wiz_0(
        .clk_out100M                 (clk_out100M), 
        .clk_out25M                  (clk_out25M),  
        
        .resetn                      (sys_rst_n),      
        .locked                      (),      
        
        .clk_in1                     (sys_clk)      

三. 仿真部分

3.1 仿真代码

3.2 波形图展示

3.2.1 原速率

在这里插入图片描述

3.2.2 加快一倍

在这里插入图片描述

3.2.3 减小一倍

在这里插入图片描述

从波形图上方时间互相对照即可得出,流水灯的速率确实加快和减小了一倍。所以本次实验成功。

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值