【第一季】CH09_FPGA多路分频器设计
【第一季】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程序源码
//----------------------------------------------------------------------------------------------------- // 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 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多路分频器设计的更多相关文章
- QQ聊天界面的布局和设计(IOS篇)-第一季
我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...
- 【第一季】CH06_FPGA设计Verilog基础(三)
[第一季]CH06_FPGA设计Verilog基础(三) 一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的.学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情. ...
- 【第一季】CH05_FPGA设计Verilog基础(二)Enter a post title
[第一季]CH05_FPGA设计Verilog基础(二) 5.1状态机设计 状态机是许多数字系统的核心部件,是一类重要的时序逻辑电路.通常包括三个部分:一是下一个状态的逻辑电路,二是存储状态机当前状态 ...
- 【第一季】CH04_FPGA设计Verilog基础(一)Enter a post title
[第一季]CH04_FPGA设计Verilog基础(一) 4.1 Verilog HDL 代码规范 u 项目构架设计 项目的构架用于团队的沟通,以及项目设计的全局把控 u 接口时序设计规范 模块和模块 ...
- Hadoop 2.x从零基础到挑战百万年薪第一季
鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ...
- 豪斯医生第一季/全集House M.D 1迅雷下载
豪斯医生 第一季 House M.D. Season 1 (2004)本季看点:态度无礼,表情凶恶,跛足拄着一根藤棍,永远是牛仔裤运动鞋的便装打扮而不是整洁的白大褂,普林斯顿大学附属医院的格雷戈·豪斯 ...
- 小课堂week16 编程范式巡礼第一季 三大基石
编程范式巡礼第一季 三大基石 最近迷上了一些哲史类书籍,回望过去.放眼未来,往往沉浸在其思维之美中无法自拔.计算机编程是一门非常年轻的学科,沉淀不足也是年轻的一个侧面,在编程领域,有足够思想深度的作品 ...
- 分布式压测系列之Jmeter4.0第一季
1)Jmeter4.0介绍 jmeter是个纯java编写的开源压测工具,apache旗下的开源软件,一开始是设计为web测试的软件,由于发展迅猛,现在可以压测许多协议比如:http.https.so ...
- 【第一季】CH08_FPGA_Button 按钮去抖动实验
[第一季]CH08_FPGA_Button 按钮去抖动实验 按键的消抖,是指按键在闭合或松开的瞬间伴随着一连串的抖动,这样的抖动将直接影响设计系统的稳定性,降低响应灵敏度.因此,必须对抖动进行处理,即 ...
随机推荐
- golang list使用 双层 循环 删除 遍历
queue队列: import ( "container/list" "sync" ) type Queue struct { l *list.List m s ...
- 数据库中的几个概念 - LGWR, ARCH,ASYNC,SYNC,AFFIRM
双机热备(双机容错)就是对于重要的服务,使用两台服务器,互相备份,共同执行同一服务.当一台服务器出现故障时,可以由另一台服务器承担服务任务,从而在不需要人工干预的情况下,自动保证系统能持续提供服务 双 ...
- C++ 基础学习笔记
c++中的左值与右值 左值与右值这两概念是从 c 中传承而来的,在 c 中,左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式). 清除 ...
- 深入理解Android插件化技术
深入理解Android插件化技术 转 https://zhuanlan.zhihu.com/p/33017826 插件化技术可以说是Android高级工程师所必须具备的技能之一,从2012年插件化概 ...
- java静态标示符static详解
1.static修饰的变量习惯称为静态变量,static修饰的方法称为静态方法,static修饰的代码块叫做静态代码块. 1)static变量 static变量也称作静态变量,静态变量和非静态变量的区 ...
- JDK的新特性
JDK5新特性 a,自动拆装箱 b,泛型 c,可变参数 d,静态导入 e,增强for循环 f,互斥锁 g,枚举 JDK7新特性 * A:二进制字面量 * B:数字字面量可以出现下划线 * C:swit ...
- mongodb查询修改
//查 public StatisticsSchoolPracticeView findByUser(String userId,int statOrgType,int inDateType){ Qu ...
- 无法登录到Windows云服务器怎么办?
当您的云服务器无法远程登录时,我们首先建议您使用VNC方式登录. 是否可以通过控制台远程登录 远程登录失败时,请首先尝试能否通过管理控制台,使用VNC方式登录弹性云服务器. 登录管理控制台. 选择“计 ...
- img标签替换为mip-img标签的方法
function replaceMipImages($content){ preg_match_all('/<img (.*?)\>/', $content, $images); if(! ...
- dp[2019.5.25]
1.实例计算(写出计算过程): 1)对维数为序列<5, 10, 3, 12, 5, 50, 6>的各矩阵,找出其矩阵链乘积的一个最优加全部括号. 这是一个矩阵连乘问题,基本知识可以参考: ...