【第一季】CH09_FPGA多路分频器设计

在第七节的学习中,笔者带大家通过一个入门必学的流水灯实验实现,快速掌握了VIVADO基于FPGA开发板的基本流程。考虑到很多初学者并没有掌握好Vivado 下FPGA的开发流程,本章开始笔者讲更加详细地介绍基于VIVADO FPGA开发的流程规范,让读者掌全面掌握FPGA开发流程包括了如何仿真、综合、执行、下载到开发板测试。

9.1 硬件图片

本章使用到的硬件和前一章一样:LED部分及按钮部分


9.2 硬件原理图

PIN脚定义:

GCLK:Y9(PL输入时钟)

LD0:T22

BTNU:T18

9.3 介于VIVADO的FPGA设计流程


9.4 多路分配器设计思想

FPGA输入全局时钟100MHZ,定义合适的分频计数器,得到对应的时钟。通过chipscope来抓取2分频、3分频(注意:对二分频的时钟进行3分频)、4分频和8分频结果,通过板子上的LED灯,来显示2HZ的时钟。设计总体框图如下所示


9.5时序设计

① 定义寄存器div2_o_r,检测输入时钟上升沿,每次上升沿寄存器div2_o_r反转一次,实现2分频。

② 定义寄存器pos_cnt[1:0],neg[1:0],分别检测div2_o_r的上升沿和下降沿,检测到上升沿和下降沿时,两个寄存器分别累加。计数到2’d2时,寄存器清零。另定义两个div3_o_r0和div3_o_r1,当两个计数器小于2’d1时,div3_o_r0和div3_o_r1均赋值为1,其他情况赋值为0。由div3_o_r0和div3_o_r1组合逻辑相或即为div2_o_r进一步进行3分频所得的结果。

③  定义位宽为2的寄存器div_cnt[1:0],检测输入时钟上升沿,div_cnt==2’b00或2’b01,4分频输出寄存器div4_o_r反转,div_cnt==2’b00时,8分频输出寄存器div8_o_r反转。

④ 由于输入时钟100MHZ,为得到2HZ的时钟,需要定义计数器至少100000000/1=100000000。在此定义一个26位位宽的div2hz_cnt计数器。检测输入时钟上升沿,div2hz_cnt==26’d24_999999或div2hz_cnt==26’d49_999999时,2HZ输出寄存器div2hz_o_r反转。

9.6程序源码

`timescale 1ns / 1ps

//-----------------------------------------------------------------------------------------------------

// Target Devices: XC7Z020-FGG484

// Tool versions:  VIVADO2015.4

// Description: Divider_Multiple

// Revision:  V1.1

// Additional Comments:

//1) _i PIN input  

//2) _o PIN output

//3) _n PIN active low

//4) _dg debug signal

//5) _r  reg delay

//6) _s state machine

*/

//-----------------------------------------------------------------------------------------------------

module Divider_Multiple(

input clk_i,

input rst_n_i,

output div2_o,

output div3_o,

output div4_o,

output div8_o,

output div2hz_o

);

reg div2_o_r;

always@(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div2_o_r<=1'b0;

else

div2_o_r<=~div2_o_r;

end

reg [1:0] div_cnt1;

always@(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div_cnt1<=2'b00;

else

div_cnt1<=div_cnt1+1'b1;

end

reg div4_o_r;

reg div8_o_r;

always@(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div4_o_r<=1'b0;

else if(div_cnt1==2'b00 || div_cnt1==2'b10)

div4_o_r<=~div4_o_r;

else

div4_o_r<=div4_o_r;

end

always@(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div8_o_r<=1'b0;

else if((~div_cnt1[0]) && (~div_cnt1[1]))

div8_o_r<=~div8_o_r;

else

div8_o_r<=div8_o_r;

end

reg [1:0] pos_cnt;

reg [1:0] neg_cnt;

always@(posedge div2_o_r or negedge rst_n_i)

begin

if(!rst_n_i)

pos_cnt<=2'b00;

else if(pos_cnt==2'd2)

pos_cnt<=2'b00;

else

pos_cnt<=pos_cnt+1'b1;

end

always@(negedge div2_o_r or negedge rst_n_i)

begin

if(!rst_n_i)

neg_cnt<=2'b00;

else if(neg_cnt==2'd2)

neg_cnt<=2'b00;

else

neg_cnt<=neg_cnt+1'b1;

end

reg div3_o_r0;

reg div3_o_r1;

always@(posedge div2_o_r or negedge rst_n_i)

begin

if(!rst_n_i)

div3_o_r0<=1'b0;

else if(pos_cnt<2'd1)

div3_o_r0<=1'b1;

else

div3_o_r0<=1'b0;

end

always@(negedge div2_o_r or negedge rst_n_i)

begin

if(!rst_n_i)

div3_o_r1<=1'b0;

else if(neg_cnt<2'd1)

div3_o_r1<=1'b1;

else

div3_o_r1<=1'b0;

end

reg div2hz_o_r;

reg [25:0] div2hz_cnt;

always@(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div2hz_cnt<=0;

else if(div2hz_cnt<26'd50_000000)

div2hz_cnt<=div2hz_cnt+1'b1;

else

div2hz_cnt<=0;

end

always@(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div2hz_o_r<=0;

else if(div2hz_cnt==26'd24_999999 || div2hz_cnt==26'd49_999999)

div2hz_o_r<=~div2hz_o_r;

else

div2hz_o_r<=div2hz_o_r;

end

assign div2_o=div2_o_r;

assign div3_o=div3_o_r0 | div3_o_r1;

assign div4_o=div4_o_r;

assign div8_o=div8_o_r;

assign div2hz_o=div2hz_o_r;

ila_0 ila_0_0 (

.clk(clk_i), // input wire clk

.probe0(div2hz_o), // input wire [0:0]  probe0  

.probe1({div2_o,div3_o,div4_o,div8_o}) // input wire [3:0]  probe1

);

endmodule

9.7行为仿真

9.7.1创建多路分频器工程

Step1:创建工程

Step2:欢迎界面直接单击NEXT

Step3:工程名字命名为Divider_Multiple,并且设置保存的路径,单击NEXT

Step4:新建一个RTL 工程,并且勾选不要添加源文件,单击NEXT

Step5:由于MIZ702和ZEDBOARD是兼容的,因此直接选择ZEDBOARD硬件开发包作为我们MIZ702的开发包。这样可以省去很多麻烦,达到事半功倍的目的。单击NEXT

Step6:最后单击Finish 完成工程的创建



9.7.2添加仿真文件

Step1:单击Add Sources添加仿真文件

Step2:单击Add Sources添加仿真文件

Step3:单击 Add files 把仿真文件添加进来

Step4:单击 Add files 把仿真文件添加进来

Step5:仿真文件源码

module Divider_Multiple_top_TB;

// Inputs

reg clk_i;

reg rst_n_i;

// Outputs

wire div2_o;

wire div3_o;

wire div4_o;

wire div8_o;

wire div2hz_o;

// Instantiate the Unit Under Test (UUT)

Divider_Multiple_top uut (

.clk_i(clk_i),

.rst_n_i(rst_n_i),

.div2_o(div2_o),

.div3_o(div3_o),

.div4_o(div4_o),

.div8_o(div8_o),

.div2hz_o(div2hz_o)

);

initial

begin

// Initialize Inputs4

clk_i = 0;

rst_n_i = 0;

// Wait 100 ns for global reset to finish

#96;

rst_n_i=1;

end

always

begin

#5 clk_i=~clk_i;

end

endmodule

Step6:单击 Simulation Settings对仿真参数做一些设置

Step7:单击 Simulation 设置仿真时间为1000ms


9.7.3行为级仿真

Step1:单击 Run Simulation

Step2:计算机CPU会模拟FPGA的运行,1000ms运行来说通常需要几分钟时间。具体时间和CPU的配置有很大关系。

Step3:仿真结束后查看波形,为了观察方便,右击窗口选择float

Step4:使用放大工具放大后观察

Step5:使用放大工具放大后观察

Step6:断点观察更多信号

1、打开divider_multiple.v文件只要是显示红色圆圈的位置就是可以设置断点,单击红色圆圈。

2、单击运行

3、可以看到红色线框内有很多信号了,这些就是内部的运行信号,可以让我们观察程序更加仔细。

Step7:用鼠标单击这个几个信号,然后右击后单击Add To Wave Window

Step8:可以看到我们添加进来的三个寄存器变量

Step9:重新仿真 按钮1是初始化仿真 按钮2是仿真开始 按钮3是仿真到设置时间

1、去掉刚才设置的断点

2、单击1处按钮重新加载初始化仿真

3、设置仿真时间为1000ms

4、单击3处按钮

Step10:重新仿真后结果

Step11:设置观察的数据类型

1、首先选择一个要观察的变量

2、右击选择Radix

3、假设选择Binary以二进制形式观察

Step12:设置好后的效果


9.8综合 Synthesis

9.8.1添加文件

Step1:把Divider_multiple.v添加进来,并且创建xdc管脚约束文件

XDC约束文件

set_property PACKAGE_PIN Y9 [get_ports {clk_i}]

set_property IOSTANDARD LVCMOS33 [get_ports {clk_i}]

set_property PACKAGE_PIN N15 [get_ports {rst_n_i}]

set_property IOSTANDARD LVCMOS18 [get_ports {rst_n_i}]

set_property PACKAGE_PIN T22 [get_ports {div2hz_o}]

set_property IOSTANDARD LVCMOS33 [get_ports {div2hz_o}]

set_property PACKAGE_PIN T21 [get_ports {div8_o}]

set_property IOSTANDARD LVCMOS33 [get_ports {div8_o}]

set_property PACKAGE_PIN U22 [get_ports {div4_o}]

set_property IOSTANDARD LVCMOS33 [get_ports {div4_o}]

set_property PACKAGE_PIN U21 [get_ports {div3_o}]

set_property IOSTANDARD LVCMOS33 [get_ports {div3_o}]

set_property PACKAGE_PIN V22 [get_ports {div2_o}]

set_property IOSTANDARD LVCMOS33 [get_ports {div2_o}]


9.8.2综合并查看报告

Step1:点击综合按钮

Step2:综合完成后通过查看报告看资源的利用情况

可以看到这个工程只是利用到了很少一部分资源


9.8.3综合时序仿真

Step1:单击Run Simulation 选择 Run Post-synthesis Timing Simulation

Step2:观察波形可以清晰看到综合后仿真加入了延迟更加接近实际芯片的运行情况


9.9执行Implementation

9.9.1执行并查看报告

Step1:点击执行按钮

Step2:执行运行完毕后再次单击

Step3:查看执行运行完毕后的报告,执行完成后的报告比综合后的报告相比,是精确的分析和评估

Step4:点开Table可以看到使用的资料的具体参数

Step5:查看执行完后的时序约束报告

时序约束报告是FPGA开发中很重要的一项参数,所以必须看一下是否有违反时序约束的情况。可以看到有一些黄色的waring。在这里不会影响我们的输出结果,因为我们这输出并没有做时序约束。但是如果要输出很严格的时序就需要加上时序约束。

9.9.2布局布线后时序仿真

Step1:单击Run Simulation 选择 Run Post-Implementation Timing Simulation

Step2:观察波形可以清晰看到布局布线后仿真加入了延迟这要比综合后的时序更加接近真实的情况


9.10 VIVADO在线逻辑分析仪使用

9.10.1 IP Catalog添加IA ip core

Step1: 单击IP Catalog

Step2: 打开Debug & Verification > Debug ->双击 ILA

Step3:游标General Options设置如下

1、Number of probes 2 为设置需要观察信号的组为2组,因为我们准备1组放触发信号,1组放普通观察的信号

2、Sample Data Depth 1024 设置采样的深度,这是需要消耗FPGA的BRAM的BRAM越大可以设置的采样深度就越大,当然编译速度会降低。

Step4:游标Probe_Ports设置如下

Probe Port 探针类似示波器的表笔,只是这里是在FPGA内部,我们设置了Probe0用来检查2HZ的信号,Probe1用来检测另外4个分频信号。

设置好后单击OK关闭窗口

Step5: 直接单击Generate

Step6: 可以看到ila这个逻辑分析仪的IP添加进来了

Step7:切换IP Sources游标下,然后双击 ila_0.veo 打开调用的接口模版

Step8:IP接口调用模版打开后,可以看到这是一个IP接口,显然我们只要把需要被检测的信号根据前面的设置填进去就可以了。 clk就是采样时钟,probe0就是2HZ信号,proble1就是其他需要被观察的信号。

修改,并且嵌入到顶层文件中

ila_0 ila_0_0 (

.clk(clk_i), // input wire clk

.probe0(div2hz_o), // input wire [0:0]  probe0  

.probe1({div2_o,div3_o,div4_o,div8_o}) // input wire [3:0]  probe1

);

9.10.2 逻辑分析仪抓取的信号

设置好逻辑分析仪,需要抓取的信号为

div2_o_r,

div3_o_r,

div3_o_r0,

div3_o_r1,

div4_o_r,

div8_o_r。

逻辑分析仪抓取的信号如下图所示。


9.10.3 逻辑分析仪使用

区域1:设置采样的启动停止,和采样的方式

区域2:设置触发信号

区域3:被观察的信号名字

区域4:被观察的信号波形

区域5:触发模式设置

区域6:触发设置

那么我们主要使用的有1、2、3、4这个几个区域。

9.11小结

本章全面介绍了VIVADO的FPGA开发流程规范。包括了程序设计、行为仿真、综合过程、综合后时序仿真、执行过程、执行后仿真、FPGA资源的利用情况分析、利用VIVADO自带的逻辑分析仪抓取信号波形,进行分析、IAL逻辑分析仪IP的使用和设置。本章非常适合从ISE转向VIVADO开发的工程,或者ALTERA开发转向XILINX 开发的工程师、或者没有FPGA开发基础的初学者。

【第一季】CH09_FPGA多路分频器设计的更多相关文章

  1. QQ聊天界面的布局和设计(IOS篇)-第一季

    我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...

  2. 【第一季】CH06_FPGA设计Verilog基础(三)

    [第一季]CH06_FPGA设计Verilog基础(三) 一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的.学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情. ...

  3. 【第一季】CH05_FPGA设计Verilog基础(二)Enter a post title

    [第一季]CH05_FPGA设计Verilog基础(二) 5.1状态机设计 状态机是许多数字系统的核心部件,是一类重要的时序逻辑电路.通常包括三个部分:一是下一个状态的逻辑电路,二是存储状态机当前状态 ...

  4. 【第一季】CH04_FPGA设计Verilog基础(一)Enter a post title

    [第一季]CH04_FPGA设计Verilog基础(一) 4.1 Verilog HDL 代码规范 u 项目构架设计 项目的构架用于团队的沟通,以及项目设计的全局把控 u 接口时序设计规范 模块和模块 ...

  5. Hadoop 2.x从零基础到挑战百万年薪第一季

    鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ...

  6. 豪斯医生第一季/全集House M.D 1迅雷下载

    豪斯医生 第一季 House M.D. Season 1 (2004)本季看点:态度无礼,表情凶恶,跛足拄着一根藤棍,永远是牛仔裤运动鞋的便装打扮而不是整洁的白大褂,普林斯顿大学附属医院的格雷戈·豪斯 ...

  7. 小课堂week16 编程范式巡礼第一季 三大基石

    编程范式巡礼第一季 三大基石 最近迷上了一些哲史类书籍,回望过去.放眼未来,往往沉浸在其思维之美中无法自拔.计算机编程是一门非常年轻的学科,沉淀不足也是年轻的一个侧面,在编程领域,有足够思想深度的作品 ...

  8. 分布式压测系列之Jmeter4.0第一季

    1)Jmeter4.0介绍 jmeter是个纯java编写的开源压测工具,apache旗下的开源软件,一开始是设计为web测试的软件,由于发展迅猛,现在可以压测许多协议比如:http.https.so ...

  9. 【第一季】CH08_FPGA_Button 按钮去抖动实验

    [第一季]CH08_FPGA_Button 按钮去抖动实验 按键的消抖,是指按键在闭合或松开的瞬间伴随着一连串的抖动,这样的抖动将直接影响设计系统的稳定性,降低响应灵敏度.因此,必须对抖动进行处理,即 ...

随机推荐

  1. 网络文件共享服务—vsftpd服务

    文件传输协议(FTP) 文件传输协议:File Transfer Protocol是用于在网络上进行文件传输的一套标准协议,使用客户/服务器模式.它属于网络传输协议的应用层. 服务器端:vsftpd ...

  2. AddLayer和AddTag

    using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; pu ...

  3. geth入门命令和miner.start返回null的问题

    geth –datadir “./ethdev” –nodiscover console 2>>geth.log //geth 进入控制台 –datadir 指定链的目录 与公有链区分开 ...

  4. 批量停止、删除docker容器

    批量停止 根据NAMES停止所有容器 docker stop `docker ps | awk 'NR!=1{print $NF}'` 根据CONTAINER ID停止所有容器 docker stop ...

  5. Vue —— 从环境搭建到发布

    之前学习 Vue 的时候也是按着别人的文档一步步下载安装构建项目再运行,为了避免忘记步骤,所以还是记在这吧. 参考链接: https://www.zybuluo.com/xudongh/note/75 ...

  6. [go]日志库小例子

    输出日志 //输出日志到console msg := fmt.Sprintf(format, args...) //format里的坑 args解出的数据相匹配 fmt.Fprintf(os.Stdo ...

  7. PAT 甲级 1015 Reversible Primes (20 分) (进制转换和素数判断(错因为忘了=))

    1015 Reversible Primes (20 分)   A reversible prime in any number system is a prime whose "rever ...

  8. Python查询Mysql时返回字典结构的代码

    Python查询Mysql时返回字典结构的代码 MySQLdb默认查询结果都是返回tuple,输出时候不是很方便,必须按照0,1这样读取,无意中在网上找到简单的修改方法,就是传递一个cursors.D ...

  9. AppCode 2016.3 注册码

    43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...

  10. UIApearance的认识

    在参加工作之前一直不知道还有UIApearance的这个属性,并且不知道UIApearance是用来干嘛的,还不知道怎么用,工作之后,看公司代码中都会出现这个UIApearance,我决定学习学习,并 ...