《FPGA经典例程及解读--基于xilinx K325T平台》系列导航
本专栏主要针对与想学习FPGA的同学,从基础的点灯到之后的复杂功能实战例程,从入门到进阶,通过这些例程的学习和了解,希望可以帮助你从一个FPGA小白进阶到FPGA中级阶段,能够处理工作中大多数的FPGA使用场景。
本篇是该系列的第一篇内容
下一篇:FPGA例程(2):LED流水灯--vivado FPGA程序固化下载-CSDN博客
1 引言
通过LED流水灯实验,介绍使用vivado软件开发FPGA的基本流程 :创建工程、器件选择、设置、代码编写、编译、引脚约束、时钟约束,以及生成bit下载到开发板进行测试 。对于初学 XILINX FPGA 的读者请注意,bit 文件断电后就丢失了,需要重新下载一次,适用于项目开发过程中的测试。
2 硬件环境
开发环境使用vivado2019.1

开发板使用米联客的MK7160FA

对应的原理图如下

3 新建vivado工程
第一步:双击启动vivdao--选择Create Project

点击Next

**第二步:**创建一个名为LED_test的工程到对应的文件目录下,文件路径可以自定义,但是不能有中文和非法字符,点击Next

**第三步:**勾选这个复选框---Next
如果不勾选复选框,next之后就会跳出创建和选择.v文件的界面,但是我们一般都不会在这里添加文件,而是在整个工程创建好之后再添加,所以这里就把复选框勾上就能直接到选择器件的界面了。

**第四步:**选择FPGA芯片的 型号、封装、速度等级----点击Next

**第五步:**点击finish完成工程创建

4 添加工程文件
**第一步:**单击Add Sources,选择Add or Create design sources,点击Next


**第二步:**点击Create File,创建一个名为led_test的verilog文件,点击ok


添加完的界面如下图,点击Finish

弹出来的这个对话框是用来设置一些输入输出的端口的,我们这里不进行设置,直接点击OK就好

**第三步:**创建完成后,我们就可以再Design Sources里面看到这个led_test.v的文件了,这个文件就是我们用来编写Verilog程序的文件。

5 Verilog FPGA流水灯程序编写
双击打开led_test.v文件,我们可以看到,工具已经帮我们写好了module 名称,需要我们自己来编写输入输出和逻辑代码。

那正常情况下,外部输入必须有时钟和复位信号,但是我这个开发板比较特殊,目前它的外部输入只有时钟信号,那我们需要在程序内部先做一个复位信号,作为全局复位来使用;
一般来说,当FPGA外部没有全局复位的时候,内部产生复位的方式有两种:
第一种:使用锁相环PLL ip核产生
第二种:自己计数产生
那为了便于大家理解和学习,我们本次就使用第二种方式,自己计数产生。
5.1 自己产生复位程序
程序的第一个always块是一个计数器,即当检测到sys_clk时钟的上升沿的时候我们从0开始计数,当计数到128时,就一直保持128这个值;
第二个always块刚开始的时候rst_n为0,等rst_cnt变成128的时候,rst_n就变为1,因为rst_cnt之后会一直持续为128,故rst_n之后将持续为1;
// ---------------------- 产生全局复位 -------------------------------
parameter RST_DELAY = 8'd128;
reg [7:0] rst_cnt;
always @(posedge sys_clk) begin
if(rst_cnt < RST_DELAY)begin
rst_cnt <= rst_cnt + 1'd1;
end else if(rst_cnt == RST_DELAY) begin
rst_cnt <= rst_cnt;
end else begin
rst_cnt <=0;
end
end
reg rst_n;
always @(posedge sys_clk) begin
if(rst_cnt == RST_DELAY) begin
rst_n <= 1;
end else begin
rst_n <= 0;
end
end
5.2 流水灯控制程序
第一个always块依旧是计数器,led_cnt每计数500ms,就清零一次,重新计数,为什么要500ms-1?因为咱们的计数器是从0开始计数到,计数到500ms-1,刚刚是500ms了。
第二个always块就是led流水灯的产生逻辑了:
刚开始的时候led[0]处于亮的状态,
当计数500ms的时候就左移一位即led[1]亮,其余都灭,
再计数500ms之后继续左移led[2]亮,其余灭,
......
当led[3]的亮状态已经持续了500ms之后,就重新回到led[0]的状态。
状态的切换只在计数满500ms的时候进行,其余情况状态需要保持。
// -----------------------------------------------------------------
reg [31:0] led_cnt;
always @ (posedge sys_clk or negedge rst_n) begin
if (!rst_n) begin
led_cnt <= 32'd0;
end
else begin
if (led_cnt == 32'd50_000_000 - 1) begin // 对应500ms
led_cnt <= 32'd0;
end
else begin
led_cnt <= led_cnt + 32'd1;
end
end
end
reg [3:0] led_c;
always @ (posedge sys_clk or negedge rst_n) begin
if (!rst_n) begin
led_c <= 4'b0001;
end
else begin
if (led_cnt == 32'd50_000_000 - 1) begin
if (led_c == 4'b1000) begin
led_c <= 4'b0001;
end
else begin
led_c <= led_c <<1 ; //左移1位。
end
end
else begin
led_c <= led_c;
end
end
end
assign LED_o = led_c;
5.3 语法错误检查
这样我们就编写好了LED流水灯的测试代码,使用Run Synthesis先综合一下看是否有语法错误
这样的界面没有报错,即咱们综合是正常的,暂时也不进行Run Imple....(实现)的操作(实现需要引脚约束之后才进行),点击取消即可。

6 添加引脚约束文件
方法1:手动添加xdc文件
**第一步:**单击Add Sources-->选择Add or Create Constrains-->Next


**第二步:**点击Create File创建一个新的xdc文件,命名为fpga_pin点击OK-->Finish


在Constrains--Constrs_1底下就会有fpga_pin.xdc文件

**第三步:**双击fpga_pin.xdc文件,按如下编写约束
将sys_clk约束为一个100MHz的输入时钟,对外引脚为AA3,电压为1.5V,这些均来自于原理图
底下是led灯的对外引脚约束。
最后的SPI X4这一部分是为了最后生成的bit可以以spi x4的形式写进板子,如果不约束,默认就是x1的,写入速度会稍微慢一些,但不影响使用。
## ----------- clock -----------------------
create_clock -period 10.000 -name sys_clk [get_ports sys_clk]
set_property PACKAGE_PIN AA3 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS15 [get_ports sys_clk]
## ------------ led pin -----------------------------
set_property PACKAGE_PIN G14 [get_ports {LED_o[0]}]
set_property PACKAGE_PIN H14 [get_ports {LED_o[1]}]
set_property PACKAGE_PIN J10 [get_ports {LED_o[2]}]
set_property PACKAGE_PIN J11 [get_ports {LED_o[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_o[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_o[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_o[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_o[3]}]
## ========================== SPI X4 =================================
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]
方法2:综合完成之后添加约束文件
第一步:点击Open Synthesized Design
综合完成之后就在这里。

如果你已经点击了取消,就从这里点开。

**第二步:**打开之后Synthesized Design之后点击Windows-->I/O Ports

**第三步:**这里下拉菜单进行引脚选择即可,或者也可以自己输入引脚。

**第四步:**点击保存,并给xdc文件命名为fpga_pin即可


7 生成bit文件并下载板子
7.1 bit文件生成
依次点击Run Synthesis(综合)--->Run Implementation(实现)--->Generate Bitstream(生成bit),完成bit文件的生成。

7.2 下载程序
**第一步:**给板子上电,并连接下载器
**第二步:**点击Open Target-->Auto Connect

正常连接后显示如下图:

**第三步:**点击Program Device

**第四步:**选择bit文件,一般打开之后默认就有了,点击Program,等待下载完成即可


8 实验结果
下载完成之后,就可以看到流水灯运行起来了
led流水灯视频展示
