FPGA例程(1):LED流水灯实验--vivado工程创建、编译及下载bit

《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流水灯视频展示

相关推荐
9527华安4 小时前
Artix7系列FPGA实现SDI视频解码转CameraLink,基于GTP高速收发器+OSERDES2原语架构,提供2套工程源码和技术支持
fpga开发·架构·音视频
!chen5 小时前
自适应滤波算法FPGA实现思路
算法·fpga开发
华舞灵瞳5 小时前
学习FPGA(七)正弦信号合成
学习·fpga开发
葡萄杨5 小时前
【软件使用】Icarus Verilog仿真
fpga开发
s09071365 小时前
常用FPGA实现的图像处理算法
图像处理·算法·fpga开发
s090713612 小时前
FPGA实现Gamma校正的系统性指南
图像处理·fpga开发·gama校正
读书点滴12 小时前
FPGA中如何获取任何一条路径的延时
fpga开发
minglie112 小时前
嵌入式协程AlarmProtothread
mcu·fpga开发
Godspeed Zhao13 小时前
自动驾驶中的传感器技术79——Sensor Fusion(2)
人工智能·fpga开发·自动驾驶