FPGA学习笔记(1)——点亮流水灯

开发环境:

  • 开发平台:黑金AX309开发板,核心为xilinx的spartan 6芯片
  • 开发软件:ISE和Modelsim
  • 开发语言:verilog

在这里插入图片描述

目的及实现功能:

1.通过点亮板子上的4颗led入门FPGA开发的流程与步骤。
2.熟悉软件ISE和Modelsim的功能及使用。

硬件原理:

1.简介

本次用到的是板载的四个LED。
LED,又名发光二极管。 发光二极管与普通二极管一样具有单向导电性。 给它加上阳极正向电压后,通过 5mA 左右的电流就可以使二极管发光。
在这里插入图片描述

2.硬件原理图:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210205215606710.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MTM1MzUy,size_16,color_FFFFFF,t_70
通过原理图我们可以看到,四个共阴极的LED阳极通过470Ω的排阻连接到FPGA的IO上,只要FPGA的IO输出高电平,就可以点亮LED。其中排阻做为限流电阻使用。

3.时钟,复位,LED端口管脚分配:

信号名 方向 管脚 端口说明
sys_clk input T8 系统时钟, 50M
sys_rst_n input L3 系统复位, 低电平有效
Led[0] output P4 LED0
Led[1] output N5 LED1
Led[2] output P5 LED2
Led[3] output M6 LED3

sys代表系统级别的,clk代表时钟;rst指reset,n指代低电平有效。

4.UCF约束文件:

UCF文件可以进行引脚对应与时序约束等。

UCF文件语句常采用如下编写格式:
NET “端口名称” LOC = 引脚编号 | IOSTANDARD = “电压” ;

我们使用到的有如下资源有:
(1)50Mhz 的系统全局时钟:命名为“sys_clk”,这里用sys代表系统级别,clk是时钟clock的缩写;
(2)全局复位信号:命名为“rst_n”,rst是复位reset的缩写,后缀n代表低电平有效;
(3)四个 led 灯“led<0~3>”。
约束文件也只需要写出这几个管脚的分配信息就可以了,另外将除系统时钟之外的所有管脚的电平标准约束为 3.3V 以满足要求,这个设置是和 FPGA 硬件设计的 bank 电压有关,黑金的大部分开发板的 IO BNAK 电压为 3.3V,所以设置为“3.3-V LVTTL”。输出电压和设置没有关系,如果 BANK 电压是 3.3V,你这里设置 2.5V,也不会改变 IO 输出的电压幅度。当然在其他应用场合我们也可以根
据不同的应用要求来分配不同的电平标准

5.UCF文件如下:

NET sys_clk LOC = T8 | TNM_NET = sys_clk_pin;							  #时钟
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;

##
NET sys_rst_n            LOC = L3 | IOSTANDARD = "LVCMOS33"; 		  ##复位信号

########LED Pin define#####################
NET led<0>                LOC = P4 | IOSTANDARD = "LVCMOS33";       ## LED1
NET led<1>                LOC = N5 | IOSTANDARD = "LVCMOS33";       ## LED2
NET led<2>                LOC = P5 | IOSTANDARD = "LVCMOS33";       ## LED3
NET led<3>                LOC = M6 | IOSTANDARD = "LVCMOS33";       ## LED4

程序设计:

思路:

流水灯就是使板子上的4个LED按照一定的时间依次交替亮灭。比如,我们要设计1秒的流水灯,就是最开始LED0亮,1s后LED0灭,LED0灭掉同时LED1被点亮;再过1s后LED1灭LED2亮,依此类推。

  • 灯的亮灭: 由于二极管的阳极分别与 FPGA 相应的管脚相连,只需要改变与 LED 灯相连的 FPGA 管脚的电平, LED灯的亮灭状态就会发生变化。当 FPGA 管脚为高电平时, LED 灯点亮; 为低电平时, LED 灯熄灭。
  • 计时: FPGA 的设计中通常使用计数器来计时,对于 50Mhz 的系统时钟,一个时钟周期是 20ns,那么表示一秒需要 5000 0000 个时钟周期,如果一个时钟周期计数器累加一次,那么计数器从 0 到4999 9999 正好是 5000 0000 个周期,就是 1 秒的时钟。0.5s就是25000 0000个周期,也就是计数到24999 9999.由于人眼的视觉暂留效应, 流水灯状态变换间隔时间最好不要低于 0.1s,否则就不能清晰地观察到流水效果。

流水灯模块代码:

module led_test
(
	input           sys_clk,          //板载的50M晶振
	input           sys_rst_n,        // 复位键,低电平有效
	output reg[3:0] led            	  // 流水灯
);

reg [25:0]      timer;					  //计数器

//计数器控制
always@(posedge sys_clk or negedge sys_rst_n)	    //时钟信号到来或者复位,常用语句
begin
	if (!sys_rst_n) 								//等价于if(sys_rst_n == 1'b0)
		timer <= 32'd0;                             //复位时计数器清零
	else if (timer == 32'd100_000_000 - 2'b1)       //计数到2s时(4*0.5s)
		timer <= 32'd0;                     //计数到一个周期,四个灯都亮一遍后,计数器清零,重新开始计数
	else
		timer <= timer + 32'd1;             //计数器计数
end

//流水灯控制
always@(posedge sys_clk or negedge sys_rst_n)
begin
	if (!sys_rst_n )
		led <= 4'b0001;                     	//复位时,第一个灯亮
	else if(timer == 32'd25_000_000 - 2'b1 )	//每当计数到0.5s时,更换亮的灯
		led[3:0] <= {led[2:0], led[3]} ;
	else
		led <= led;			
end

endmodule

开发流程:

一、新建工程

1.我们首先在将要存放工程的地方建立一个led文件夹,用于存放我们的代码,良好的文件分类习惯可以使我们更加有效率。在里面新建三个文件夹,其中:
prj文件主要用来存放工程文件,如ucf文件等;
rtl主要用来存放".v"文件,也就是激励文件;
sim主要用来存放simulink文件(仿真文件)。
注意,存放工程的目录都要使用英文字符,不要出现汉字。

在这里插入图片描述
2.打开ISE开发环境,选择菜单 File->New project。
在这里插入图片描述
或者直接选择New Project选项。
在这里插入图片描述
3.因为我们这次是做流水灯,所以我们起名叫led,并填在name选项,然后在下图中的第二步找到我们之前建立的prj文件夹作为存放位置,选择好之后选择next。
在这里插入图片描述
在这里插入图片描述
4.
(1)选择芯片的型号和配置,如下面第一个框中的,这里我用的AX309的芯片,所以是下面的配置。如果不清楚芯片信息的可以查看另一篇博客了解:Xilinx 芯片的命名规则
(2)选择仿真软件,这里面我使用的是modelsim,然后选择语言,这里使用verilog
选择好之后点击next。

在这里插入图片描述
5.出现的界面显示了我们工程的信息,有问题选择Back返回调整,如果都对了选择finish。在这里插入图片描述
6.一个新工程就初步建立完成了,我们也可以在软件中核对工程的信息。如下图在这里插入图片描述

二、编写Verilog文件

1.新建 Verilog HDL 文件,在工程文件目录区单击右键,选择 New Source。
在这里插入图片描述

2.选择 Verilog module 文件, 填写模块文件的名称,将模块的保存路径切换为工程目录
下的 rtl文件夹(之前手动建立好的),点击 Next。
在这里插入图片描述
在这里插入图片描述
3.保持默认直接点击 Next。
在这里插入图片描述
4.点击 Finish 完成模块建立。
在这里插入图片描述
5.我们可以看到在工程文件目录区已经有了我们建立的 led_test 的源文件,右边的代码编写区也有了 Xilinx 官方提供的代码编写模板
在这里插入图片描述
6.在代码编写区编写我们的代码。
在这里插入图片描述

7.然后点击编译,如果代码没有语法错误则在 Synthesize - XST和Implement 菜单前会出现运行成功标志,同时右边的代码编辑区会出现代码的编译信息,包括寄存器和查找表, Buffer 等资源的消耗情况在这里插入图片描述

三、编写UCF文件

1.在工程文件目录区单击鼠标右键选择 New Source
在这里插入图片描述
2.选择Implementation Constraints File文件,ilename起名叫led,在Locations选项中将文件保存在我们之前建立好的工程文件夹下面。完成后选择Next。
在这里插入图片描述
3.选择Finish。
在这里插入图片描述
4.将我们之前写好的UCF代码写在右侧代码编写页面中。
在这里插入图片描述
重新编译,没有报错说明UCF文件书写完成没有语法错误。

四、下载程序到FPGA中

下载程序到FPGA我们才能看到我们代码的实际运行情况,在这之前,需要我们先生成可执行文件。可执行文件,也就是编译器根据编写的程序和管脚信息还有约束信息所生成的后缀名为“.bit”的文件。这个文件可以通过JTAG 方式下载到 FPGA 运行,但不能直接固化到 Flash。
步骤如下:
1.右键点击Generate Program File选项,选择run。
在这里插入图片描述
2.前面过程正确的话这一步成功后也会在选项左侧显示绿色的对勾。这时候,bit文件就生成了。
在这里插入图片描述

3.双击Config Target Device选项。
在这里插入图片描述
4.选择OK。
在这里插入图片描述
5.把开发板和JTAG下载器分别和电脑连接好,然后再把下载器与板子连接好后打开板子的供电开关。
在这里插入图片描述
6.双击boudary scan选项。
在这里插入图片描述
7.点击initial chain选项。
在这里插入图片描述
8.选择Yes。
在这里插入图片描述
9.选择后缀为bit的文件,这就是我们之前生成的可执行文件,然后open。
在这里插入图片描述
10.选择NO。
在这里插入图片描述
11.选择OK。
在这里插入图片描述
12.双击Program选项,出现蓝色框,并显示Identify Succeded证明下载成功。 此时,板子上出现4个灯交替闪烁,证明我们点灯成功!
在这里插入图片描述
但是,当我们关闭开发板的的电源开关后,再打开电源开关就会发现之前的板子的状态变了。这说明我们的程序随着板子掉电消失了。想要使板子一直运行所需的代码,就需要固化程序到flash里永久保存,这样一上电就会实现我们所需要的功能。

五、固化程序到flash里

1.在之前的基础上,我们进行固化程序。双击Create Prom File选项。
在这里插入图片描述
2.这一步用于生成mcs文件的配置,比较多,选项及操作顺序如下图。注意output file name 选项填入的名字就是最后生成的mcs文件的名字。然后location也就是mcs文件的存放位置我们依旧选择之前的prj文件夹。

在这里插入图片描述
3.选择OK。
在这里插入图片描述
4.弹出如下界面,选择之前生成的“led.bit”文件并打开。在这里插入图片描述
5.选择OK。
在这里插入图片描述
6.双击Genrate File。
在这里插入图片描述
7.这一步就会生成mcs文件,生成成功会出现蓝色框提示成功。
在这里插入图片描述
1.双击 Boundary Scan 回到 Boundary
Scan 界面
在这里插入图片描述
2.点击菜单上的扫描链。
在这里插入图片描述
2.选择yes。
在这里插入图片描述
3.选择之前的bit文件
在这里插入图片描述
4.选择Yes。
在这里插入图片描述
5.添加生成的 MCS 文件。在工程保存位置选择 后缀名为mcs的文件并打开。
在这里插入图片描述
6.在弹出的 Select Attached SPI/BPI 窗口中我们根据开发板上的 flash 来选择。我这里的AX309开发板是选择 M25P16。然后选择OK。
在这里插入图片描述
7.选择OK。
在这里插入图片描述
8. 选中芯片图标的 Flash,右键单击选择 Program。
在这里插入图片描述
在这里插入图片描述
9.选择OK。
在这里插入图片描述
10.下载到 Flash 成功后会出现蓝色的框提示成功。
在这里插入图片描述

主要参考资料:
AX309流水灯教程
正点原子超越者FPGA开发指南流水灯章节

猜你喜欢

转载自blog.csdn.net/qq_46135352/article/details/113703413