LED驱动实验

眼高手低不可取,必须动手去做去调才能逐渐进步。本文是一个简单的FPGA工程,实现了根据按键输入,对应不同LED输出的简单功能。包含了实验资源介绍,仿真内容,实验过程,Verilog设计代码,以及功能/时序仿真,详细展示了FPGA的开发流程和操作细节。

目录

一、资源介绍

二、仿真内容

1、内容:

2、目的:

三、实验过程

1、新建ISE工程:

2、Veilog设计电路

新建设计文件

Veilog设计

功能仿真

         时序仿真​

一些细节

3、上板验证

引脚分配

上板验证

四、笔记总结

1、FPGA开发流程

2、软件

3、设计经验

4、注意

五、参考资料


一、资源介绍

EDA工具:ISE14.7

仿真软件:Modelsim

芯片:Spartan6

开发板:AX309

仿真相关开发板资源介绍:

1、LED

开发板为共阴极LED,即输入为1才能点亮LED。LED电路以及LED连接到FPGA芯片的引脚如下:

LED驱动实验_第1张图片                   LED驱动实验_第2张图片

可以看出,FPGA芯片的这几个引脚连接到LED上,而LED是共阴极。要想驱动LED,就需要在这几个引脚输出高电平。

2、按键

按键电路以及按键连接到FPGA芯片的引脚如下:

LED驱动实验_第3张图片       LED驱动实验_第4张图片

可以看出,FPGA芯片的这几个引脚连接到按键上,而按键按下时会将引脚与地连接。即:这几个引脚作为芯片的输入,按键按下时,输入为0,反之输入为1;

二、仿真内容

1、内容:

配合按键实现LED的不同显示:

  • 默认情况下LED全亮;
  • 按键1按下,LED整体闪烁;
  • 按键2按下,LED流水;

2、目的:

  • 熟悉FPGA开发流程,熟悉ISE软件使用,熟悉调试流程。
  • 初步理解外设资源的使用。
  • 熟悉Verilog语法。

三、实验过程

1、新建ISE工程:

选择File->New Project:

LED驱动实验_第5张图片

随后设置工程名称,以及工程文件存放的位置,点击NEXT:

LED驱动实验_第6张图片

随后选择器件型号等参数:

主要为:系列(family)-型号(Device)-封装(package)-语言(Language)

 LED驱动实验_第7张图片

点击Next后,出现工程的设置信息。检查出现问题,点击Back回到之前的设置部分重新设置;检查无误后点击Finish完成工程创建。

LED驱动实验_第8张图片

2、Veilog设计电路

新建设计文件

开始电路设计的第一步就是新建Veriliog设计文件,不同EDA软件的新建过程或者文件名称略有差异,但是本质都是Verilog设计文件。

以ISE为例:

点击Project->New Source,或者直接在工程文件上右键,即可得到新建文件选项(类似,如果要直接添加已有的设计文件,可以直接点击Add Source选择文件实现添加):

LED驱动实验_第9张图片LED驱动实验_第10张图片

选择文件类型为Verilog Module(即Verilog的电路设计文件) ,设置文件名称以及存储路径,默认将设计文件添加到当前工程中(如右下角√)

LED驱动实验_第11张图片

点击Next,同样为新建设计文件的配置信息,检查出现问题,点击Back回到之前的设置部分重新设置;检查无误后点击Finish完成设计文件创建。

LED驱动实验_第12张图片

注意:

不同EDA软件的新建过程或者文件名称存在差异,但是本质都是一样的。即:先创建一个工程,设置工程名称以及存储,选择器件(即工程要在怎样的平台运行)。工程设置完成需要添加设计文件,测试文件,管脚约束等等,同样有文件名称、存储位置、文件类型等的选择。

如quartus新建Verilog设计文件的步骤如下:

LED驱动实验_第13张图片

Veilog设计

设计代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: CLL guoliang             
// 
// Create Date:    11:41:34 05/17/2020 
// Design Name: 
// Module Name:    led_test 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module led_test(
	input clk,
	input rst_n,
	input key1,
	input key2,
	
	output reg [3:0]led
    );

//
//parameter LEDP = 49_999; 
//
reg [31:0]cnt;
reg key2_r;
wire key2_f;
// 功能描述-led显示部分
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
			led <= 4'b1111;//复位/默认led全亮
		end
	else if(!key1)
		begin
			if(cnt == 32'd49)// key1按下时,led按照1s间隔闪烁
				begin
					led <= ~led;
				end
			else
				begin
					led <= led;
				end
		end
	else if(!key2)
		begin
			if(key2_f)// key2按下时,led首先初始化为只有一个灯亮,随后led按照1s间隔流水闪烁
				begin
					led <= 4'b0001;
				end
			else if(cnt == 32'd49)
				begin
					led <= {led[2:0],led[3]};
				end
			else 
				begin
					led <= led;
				end
		end
	else 
		begin
			led <= 4'b1111;
		end
end

// 功能描述-计数部分(分频)
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
			cnt <= 32'd0;
		end
	else if(cnt==32'd49)
		begin
			cnt <= 32'd0;
		end
	else
		begin
			cnt <= cnt+1'b1;
		end
end

// 功能描述-key2_f生成(按键2按下时,led流水灯初始化)
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
			key2_r <= 1'b1;
		end
	else
		begin
			key2_r <= key2;
		end
end
assign key2_f = key2_r & (~key2);
endmodule

注意:

  • 此时为了功能仿真简单,将计数值设置为了49;但是在实际电路中,必须将计数值设置的比较大。因为在50Mhz的时钟下,计数50次相当于1us,如果LED按照这一频率闪烁,人眼压根分别不出。
  • 为简化设计,此处按键模块未考虑按键去抖。

设计完成,双击Synthesize-XST,执行综合,验证设计是否存在语法错误;无误时会生成相应的RTL硬件电路。

LED驱动实验_第14张图片

 Consel中显示综合结果,显示综合成功与否,如果出错应该返回设计进行查错与修改。可进一步点击Errors和Warnings,查看设计中存在的错误与警告。

功能仿真

新建测试文件,与新建设计文件类似,但是此处选择文件类型为Veilog Test Fixture;随后设置文件名称、存储位置等。

LED驱动实验_第15张图片

随后点击Next,转至设计源文件选择界面(ISE自动生成测试文件,因此必须选择测试文件对应哪一个设计文件)

选择完成点击Next,转至信息界面,显示测试文件位置,类型,名称,以及对应哪一个设计文件。确认无误后点击Finish。

LED驱动实验_第16张图片        LED驱动实验_第17张图片

 测试文件添加完成后,选择simulation进入仿真界面,这时就能看见测试文件。双击打开,可以看到测试文件确实对应之前选定的led设计文件(测试文件中已经进行了模块例化)。但是测试文件只是一个大致框架,需要进一步按照个人意愿修改扩充。

 LED驱动实验_第18张图片

仿真文件如下:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:	guoliang CLL
//
// Create Date:   13:16:31 05/17/2020
// Design Name:   led_test
// Module Name:   F:/IseFiles/led_test/tsb/led_tsb.v
// Project Name:  led_test
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: led_test
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module led_tsb;

	// Inputs
	reg clk;
	reg rst_n;
	reg key1;
	reg key2;

	// Outputs
	wire [3:0] led;

	// Instantiate the Unit Under Test (UUT)
	led_test uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.key1(key1), 
		.key2(key2), 
		.led(led)
	);

	initial
	begin
		clk = 1;
		forever #10 clk = ~clk;
	end
	
	initial 
	begin
		// Initialize Inputs
		rst_n = 0;
		key1 = 1;
		key2 = 1;

		// Wait 100 ns for global reset to finish
		#100;
		rst_n = 1;
		key1 = 0;
		#(20000)
		key1 = 1;
		key2 = 0;
		#20000;
		$stop;
	end
      
endmodule

测试文件编写完成以后,选中测试文件,随后双击Simulate Behavioral Model,启动仿真。 仿真结果如下:

 LED驱动实验_第19张图片
 

LED驱动实验_第20张图片

LED驱动实验_第21张图片

可以看出:

    默认(复位结束)LED为全亮(1111);

    按键1按下(为0),按键2未按下(为1)时:LED按照一定周期亮灭交替,与设计一致。

    按键1未按下(为1),按键2按下(为0)时:LED开始按照同样的周期进行流水循环,并且流水循环初始化(即led=0001)只进行了一次,与设计一致。

    led状态的改变在计数到49处发生,说明LED周期也和设计一致。

至此,功能仿真验证通过。

 时序仿真

在功能仿真部分,我们设置了激励,验证了设计的逻辑无误。完成功能仿真后,我们需要进行布局布线,随后进行时序仿真。

要进行时序仿真,首先需要进行实现(布局布线),即将综合输出的逻辑网表翻译成所选器件的底层模块与硬件原语(翻译过程),将设计映射到器件结构上(映射过程),进行布局布线(布局布线过程)。

双击Implement Design,进行实现。

LED驱动实验_第22张图片

翻译-映射-布局布线成功后,即可调用Modelsim进行时序仿真。 操作类似,选择Simulation选项,随后选择Post-Route仿真模式,选定仿真测试文件,随后双击Simulate Post-Place 选项,唤起Modelsim执行时序仿真。

LED驱动实验_第23张图片                    LED驱动实验_第24张图片

LED驱动实验_第25张图片

可以看出,时序仿真的时候,计数值相比于clk的上升沿存在一定的时延;同样,led状态的转换相比于计数值,也存在一定的时延。作为比较,下图是功能仿真的结果:

LED驱动实验_第26张图片

可以看出,时序仿真时,计数值cnt在clk上升沿来临后一段时间才会改变;

led状态的转换,发生在时钟上升沿来临后,并且计数值为49以后,因此滞后于计数值改变。

一些细节

1、为便于修改计数值,设计中最好不要将计数值写死,否则修改起来需要全篇改动,增加额外的工作量。

2、每次修改了设计文件,或者测试文件后,不必要再次重启Modelsim进行仿真,而需要在Modelsim中Recompile改动了的文件,Restart仿真即可。

详细:

在WORK中找到修改了的文件,右键点击Recompile,完成后Restart仿真即可。

LED驱动实验_第27张图片

3、Modelsim中如何添加模块内部信号到波形窗口。

在sim栏中,选中希望观测的模块,然后右键,选择add wave即可将该模块中所有的信号添加到波形界面;也可以左键选中该模块,然后在右侧隔壁的Objects窗口中,可以选择你希望观测的信号,然后右键,选择add wave按钮。

详见:【Modelsim常见问题】如何添加子模块信号到波形窗口观测

4、文件存放时注意区分类型,如工程文件存放在prj文件夹,测试文件放在tsb文件夹,设计文件放在rtl文件夹等,通过这样的操作可以方便以后的文件管理。

3、上板验证

引脚分配

上板验证的首要任务应该完成引脚分配,此处采用约束文件方式进行管脚约束。

新建一个Text文件,在其中进行管脚约束,随后按照.ucf格式存储。

LED驱动实验_第28张图片

约束文件如下:


##
NET clk LOC = T8 | TNM_NET = sys_clk_pin | IOSTANDARD = "LVCMOS33";
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;
##


##
NET rst_n                                 LOC = L3 | IOSTANDARD = "LVCMOS33"; ## Reset Button
##

########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

NET key1                        		       LOC = C3 | IOSTANDARD = "LVCMOS33";       ## key1
NET key2                       	          LOC = D3 | IOSTANDARD = "LVCMOS33";       ## key2

保存后,需要将编写的约束文件添加到工程中:ADD Source,选择对应文件,添加后可以在工程目录看到。

LED驱动实验_第29张图片                  LED驱动实验_第30张图片

保存项目,点击Generate Programming File 进行编译,生成bit流文件,用于FPGA的配置。 编译成功后,可以在console窗口看到成功信息。

LED驱动实验_第31张图片

至此,经过了工程建立,Verilog代码的编写与调试,经过了功能仿真,布局布线,时序仿真,端口分配,生成bit流文件,以及期间不断地调试修改。终于可以将bit流文件下载到板子上进行实际验证。

上板验证

双击Configure Target Device打开iMpact软件进行FPGA的下载。

LED驱动实验_第32张图片

双击Boundary Scan进行JTAG链路扫描。

LED驱动实验_第33张图片

随后,右键选择Initialize Chain ,初始化链路后识别到FPGA芯片。

LED驱动实验_第34张图片      LED驱动实验_第35张图片

双击芯片,即可选择要下载的bit文件,选择后,点击右键选择Program进行下载,下载成功会有提示。

LED驱动实验_第36张图片     LED驱动实验_第37张图片

至此,可以观测板子上的现象,进一步验证设计。

实测:看不出LED闪烁---原因是之前为了便于仿真,将延时设置为了1us(49计数),频率过高导致无法分辨;

修改设计文件,再次仿真成功!

 

至此,led实验基本结束。如果要固化程序,则需要进一步将配置文件下载到掉电不丢失的Flash中。此处不再进行。

四、笔记总结

1、FPGA开发流程

  • 明确设计(要求、功能等)
  • 电路设计
  • 编译综合,调试修改
  • 功能仿真,调试修改
  • 布局布线
  • 时序仿真,调试修改
  • IO分配
  • 生成bit文件
  • 下载实测,调试修改
  • 固化、存档

2、软件

  • 常见的EDA工具有XiIinx的ISE、Vivado,Alter的Quartus。具体操作可能有所差异,但是本质是一样的。

3、设计经验

  • 可以灵活使用parameter参数,便于设计的调试与修改
  • 时刻记得一个良好的代码风格的重要性,编写整齐、统一、易懂、易调、易移植的代码。

4、注意

  • 文件存储时注意分类,工程文件、测试文件、设计文件、约束文件,以及文档等分开存储,无疑给后续的文件管理提供了便利。

五、参考资料

黑金Sparten6开发板AX309教程

小梅哥系列学习教材

你可能感兴趣的:(FPGA项目实战)