软件版本:VIVADO2017.4
操作系统:WIN10 64bit
硬件平台:适用米联客 ZYNQ系列开发板
米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!!
在FPGA中,时钟分频是经常用到的。本节课讲解2分频、3分频、4分频和8分频的Verilog实现,以及如何实现仿真调试。和前面课程采用(*mark_debug = "true"*)标记需要被观察的信号不同,本课采用ILA IP CORE实现被观察信号的采集,当然本节课的ILA IP CORE本质上和上一节课是一样的。
仿真步骤不是必须的,但是仿真可以发现很多我们设计的错误或者隐患问题,进而对设计进行调整。
FPGA输入全局时钟100MHZ,定义合适的分频计数器,得到对应的时钟。通过chipscope来抓取2分频、3分频、4分频和8分频结果,通过板子上的LED灯,来显示2HZ的时钟。设计总体框图如下所示
Step1:启动VIVADO,单击Create Project
Step2:单击NEXT
Step3:创建名为Divider_Multiple的工程,并且设置保存的路径,单击NEXT
Step4:新建一个RTL 工程,并且勾选不要添加源文件,单击NEXT
Step5: 选择芯片的型号和封装速度等级
MZ7XA-7010、MZ7XA-mini7010如下图所示设置:
MZ7XA-7020、MZ7XB如下图所示设置:
Step6:最后单击Finish 完成工程的创建
新建Divider_Multiple_top.v文件。将下面的源码复制到文件中。
Divider_Multiple_top.v源码
`timescale 1ns / 1ps //----------------------------------------------------------------------------------------------------- // Target Devices: XC7Z020-CLG400-2 // Tool versions: VIVADO 2017.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_top( 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 IP ,Chipscope观察信号 //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 |
|
新建一个xdc管脚约束文件。打开提供例程,复制约束文件中的管脚约束,粘贴到新建工程中的xdc文件中。
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 |
Step1: 进入仿真界面:SIMULATION->单击 Run Simulation ->单击Run Behavioral Simulation。
Step2:设置仿真时间,仿真时间为1000ms。计算机CPU会模拟FPGA的运行,1000ms运行来说通常需要几分钟时间。具体时间和CPU的配置有很大关系。
Step3:仿真结束后查看波形,为了观察方便,右击窗口选择float
Step4:使用放大工具放大后观察
Step5:使用放大工具放大后观察
Step6:断点观察更多信号
1、打开divider_multiple_top.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:设置好后的效果
Step1:点击综合按钮
Step2:综合完成后通过查看报告看资源的利用情况
可以看到这个工程只是利用到了很少一部分资源
Step1:单击Run Simulation 选择 Run Post-synthesis Timing Simulation
Step2:观察波形可以清晰看到综合后仿真加入了延迟更加接近实际芯片的运行情况
Step1:点击执行按钮
Step2:执行运行完毕后再次单击
Step3:查看执行运行完毕后的报告,执行完成后的报告比综合后的报告相比,是精确的分析和评估
Step4:点开Table可以看到使用的资料的具体参数
Step5:查看执行完后的时序约束报告
时序约束报告是FPGA开发中很重要的一项参数,所以必须看一下是否有违反时序约束的情况。可以看到有一些黄色的waring。在这里不会影响我们的输出结果,因为我们这输出并没有做时序约束。但是如果要输出很严格的时序就需要加上时序约束。
Step1:单击Run Simulation 选择 Run Post-Implementation Timing Simulation
Step2:观察波形可以清晰看到布局布线后仿真加入了延迟这要比综合后的时序更加接近真实的情况
Step1: 单击IP Catalog
Step2: 打开Debug & Verification > Debug ->双击 ILA
Step3:游标General Options设置如下
Number of probes 2 为设置需要观察信号的组为2组,因为我们准备1组放触发信号,1组放普通观察的信号
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 ); |
设置好逻辑分析仪,需要抓取的信号为
div2_o_r,
div3_o_r,div3_o_r0,div3_o_r1,
div4_o_r,
div8_o_r。
Step1:给开发板通电,并且连接下载器
Step2:单击OpenTarget 然后单击Auto Connect
Step3:连接成功后如下图所示:
MZ7XA-7010、MZ7XA-mini7010如下图所示:
MZ7XA-7020、MZ7XB如下图所示:
Step4:单击Program Device
Step5:单击Program Device(也可以从顶部单击Program device), 然后选择 XC7Z010_1或XC7Z020。
MZ7XA-7010、MZ7XA-mini7010:
MZ7XA-7020、MZ7XB:
Step6:弹出的对话框中有我们要下载的Bit文件
下载过程
Step7:下载后出现Chipscope界面
Step8: Chipscope界面介绍
区域2:设置触发信号
区域3:被观察的信号名字
区域4:被观察的信号波形
区域5:触发模式设置
区域6:触发设置
那么我们主要使用的有1、2、3、4这个几个区域。
Step9: Chipscope运行