您现在的位置是:首页 >技术交流 >Vivado 下 LED 流水灯实验网站首页技术交流

Vivado 下 LED 流水灯实验

OliverH-yishuihan 2024-06-17 11:27:59
简介Vivado 下 LED 流水灯实验

目录

Vivado 下 LED 流水灯实验

1、实验简介

2、实验环境

3、实验原理

3.1、LED硬件电路

3.2、程序设计

4、Vivado 工程

4.1、创建工程

8.选择所用的 FPGA 器件

4.2、编写流水灯的 verilog代码

1. 点击 Project Manager 下的 Add Sources 图标(或者使用快捷键 Alt+A)。

 2. 选择 Add or create design sources 选项,点击 Next。

3. 点击 Add Files 可以一个个添加源文件,点击 AddDirectories 可以按目录添加源文件。因为现在我们还没有设计程序,这里要点击 Create File 按钮。

 4.点击“Finish”完成。

5. 编写 led_test.v 的程序

6. 编写好代码后保存,点击菜单 File -Save All Files。

4.3、添加 XDC管脚约束文件

1. 点击 Project Manager 下的 Add Sources 图标。

 2. 选择 Add or create constraints 选项,点击 Next。

 3. 点击 Create File 按钮。

 4.点击“Finish”完成。

 5. 双击打开这个 led.xdc 文件,在这个文件里添加以下的引脚定义。

4.4、编译

4.5、vivado仿真验证

1. 设置 Vivado 的仿真配置,右击 SIMULATION 中 Simulation Settings。

2.设置仿真时间

3. 添加激励测试文件

 4. 点击 Create File 生成仿真激励文件。

 6. 点击 Finish 按钮返回。

7.编写 vtf_led_test.v 文件的内容

8. 编写好后保存,vtf_led_test.v 自动成了这个仿真 Hierarchy 的顶层了,它下面是设计文件 led_test.v。

9.进行功能仿真

10. 在弹出仿真界面后如下图,界面是仿真软件自动运行到仿真设置的 50ms 的波形。

11. 点击 Restart 按钮复位一下,再点击 Run All 按钮。(需要耐心!!!),可以看到仿真波形与 设计相符。

 4.6 下载和调试

4.7、FLASH 程序固化


Vivado 下 LED 流水灯实验

1、实验简介

通过 LED 流水灯实验,介绍使用 vivado 软件开发 FPGA 的基本流程,器件选择、设置、代码
编写、编译、分配管脚、下载、程序 FLASH 固化、擦除等;同时也检验板上 LED 灯是否正常。

2、实验环境

  • Windows 10  64
  • vivado 2017.4
  • Xinlinx 黑金 FPGA 开发板(AX7A035 开发板、AX7A100 开发板、AX7A200 开发板)

3、实验原理

3.1、LED硬件电路

        从上面的 LED 部分原理图可以看出,AX7A035/ AX7A100/ AX7A200 开发板都是将 IO 经过一个电阻和 LED 串联接电源端,FPGA IO 输出低电平点亮 LEDIO 输出高电平 LED 灯熄灭,其中的串联电阻都是为了限制电流。

3.2、程序设计

       FPGA 的设计中通常使用计数器来计时,对于 200Mhz 的系统时钟,一个时钟周期是 5ns, 那 么表示一秒需要 200000000 个时钟周期,如果一个时钟周期计数器累加一次,那么计数器从 0 到199999999 正好是 200000000 个周期,就是 1秒的时钟。
程序中定义了一个 32 位的计数器:
//Define the time counter 
reg [31:0] timer;
      最大可以表示 4294967295 ,十六进制就是 FFFFFFFF ,如果计数器到最大值,可以表示 85.89934592 秒。程序设计中是每隔 0.25 LED 变化一次,一共消耗 1 秒做一个循环。
always @(posedge sys_clk or negedge rst_n) begin
    if (~rst_n) 
        timer <= 32'd0; 
    else if (timer == 32'd199_999_999) 
        timer <= 32'd0; 
    else
        timer <= timer + 1'b1; 
end
0.25 秒、第 0.5 秒、 0.75 秒、 1 秒到来的时候分别改变 LED 的状态,其他时候都保持原来的值不变。
// LED control
always@(posedge sys_clk or negedge rst_n) begin
    if (~rst_n)
         led <= 4'b0000; 
    else if (timer == 32'd49_999_999) 
         led <= 4'b0001;
    else if (timer == 32'd99_999_999) 
         led <= 4'b0010;
    else if (timer == 32'd149_999_999) 
         led <= 4'b0100;
    else if (timer == 32'd199_999_999) 
         led <= 4'b1000;
end

4、Vivado 工程

4.1、创建工程

1. 启动 Vivado 2017.4 开发环境

 2. Vivado 2017.4 开发环境里双击 Create Project,如下图:

 3. 弹出一个 Vivado 的工程向导,点击 Next 按钮。

 4. 在弹出的对话框中输入工程名和工程存放的目录,这里取一个 led_test 的工程名,点击 Next

5. 在下面的对话框中 默认选择 RTL Project, 因为我们这里使用 verilog 行为描述语言来编程。下面的 Do not specify source at this time 的勾也可以打上。如果不打上,下一步会进入添加 source file 界面,

 6. 进入添加 source file 界面,这里先不添加任何设计文件。点击 Next

 7. 提示是否添加已有的约束文件,这里约束文件我们也没有设计好,也不添加。

8.选择所用的 FPGA 器件

在接下来的对话框 选择所用的 FPGA 器件 ,以及进行一些配置。 FPGA 芯片型号一定要跟开发板 上的型号一致,首先在 Family 栏里选择 Artix-7 , Speed grade 栏选择-2 , 当开发板型号为 AX7A100 时, 在 Package 栏选择 fgg484, 然后在下面的列表中选择 xc7a100tfgg484-2 当开发板型号为 AX7A200 时,在 Package 栏选择 fbg484, 然后在下面的列表中选择 xc7a200tfbg484-2 ;当开发板型号为 AX7A035 时,在 Package 栏选择 fgg484, 然后在下面的列表中选择xc7a35tfgg484-2 单击 NEXT 进入下一界面:

 9. 再次确认一下板子型号有没有选对, 没有问题再点击“Finish”完成工程创建。

 

 10. 工程创建后如下图所示:

4.2、编写流水灯的 verilog代码

1. 点击 Project Manager 下的 Add Sources 图标(或者使用快捷键 Alt+A)。

 2. 选择 Add or create design sources 选项,点击 Next

3. 点击 Add Files 可以一个个添加源文件,点击 AddDirectories 可以按目录添加源文件。因为现在我们还没有设计程序,这里要点击 Create File 按钮。

 在弹出的对话框里选择 File type verilog, File name led_test, 点击 OK 按钮。

 4.点击“Finish”完成。

向导会提示您定义 I/O 的端口,这里我们可以不定义,后面自己在程序中编写就可以 , 单击 OK
成。

 

 这时在 Project Manager 界面下的 Design Sources 里已经有了一个 led_test.v 文件, 并且自动成为项目的顶层(Top)模块了。

5. 编写 led_test.v 的程序

编写 led_test.v 的程序,这里我们定义了一个 32 位的寄存器 timer, 用于循环计数 0~199_999_999(1 秒钟), 当计数到 49_999_999(0.25 秒)的时候,熄灭第一个 LED 灯;当计数到 99_999_999(0.5 秒)的时候,熄灭第二个 LED 灯;当计数到 149_999_999(0.75 秒)的时候,熄灭 第三个 LED 灯;当计数到 199_999_999(1 秒)的时候,熄灭第四个 LED 灯,计数器再重新计数。 具体的操作直接看代码吧。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/03/20 21:39:15
// 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(
    //Differential system clocks
    sys_clk_p,  //system clock positive
    sys_clk_n,  //system clock negative
    rst_n,      // reset ,low active            
    led         // LED,use for control the LED signal on board
    );    
//===========================================================================
// PORT declarations
//===========================================================================
input         sys_clk_p;
input         sys_clk_n;
input         rst_n;
output [3:0]  led;

//define the time counter
reg [31:0]   timer;                  
reg [3:0]    led;
wire         sys_clk;          

IBUFDS sys_clk_ibufgds
(
	.O            (sys_clk       ),
	.I            (sys_clk_p     ),
	.IB           (sys_clk_n     )
);
//===========================================================================
// cycle counter:from 0 to 1sec
//===========================================================================
  always @(posedge sys_clk or negedge rst_n)    
    begin
      if (~rst_n)                           
          timer <= 32'd0;   // when the reset signal valid,time counter clearing
      else if (timer == 32'd199_999_999)  //1 seconds count(200M-1=199999999)
          timer <= 32'd0;   //count done,clearing the time counter
      else
		    timer <= timer + 1'b1;   //timer counter = timer counter + 1
    end

//===========================================================================
// LED control
//===========================================================================
  always @(posedge sys_clk or negedge rst_n)   
    begin
      if (~rst_n)                      
          led <= 4'b0000;                  //when the reset signal active         
      else if (timer == 32'd49_999_999)    //time counter count to 0.25 sec,LED1 lighten 
          led <= 4'b0001;                 
      else if (timer == 32'd99_999_999)    //time counter count to 0.5 sec,LED2lighten
      begin
          led <= 4'b0010;                  
      end
      else if (timer == 32'd149_999_999)   //time counter count to 0.75 sec,LED3 lighten
          led <= 4'b0100;                                          
      else if (timer == 32'd199_999_999)   //time counter count to 1 sec,LED4 lighten
          led <= 4'b1000;                         
    end
endmodule

6. 编写好代码后保存,点击菜单 File -Save All Files

4.3、添加 XDC管脚约束文件

       Vivado 使用的约束文件格式为 xdc 文件。 xdc 文件里主要是完成管脚的约束, 时钟的约束 以及组的约束。这里我们需要对 led_test.v 程序中的输入输出端口分配到 FPGA 的真实管脚上 这需要准备一个 FPGA 的引脚绑定文件 .xdc 并添加到工程中。

1. 点击 Project Manager 下的 Add Sources 图标。

 2. 选择 Add or create constraints 选项,点击 Next

 3. 点击 Create File 按钮。

 在弹出的对话框里选择 File type XDC, File name led, 点击 OK 按钮。

 4.点击“Finish”完成。

这时在 Project Manager 界面下的 Constraints 目录的 constrs_1 目录下已经有了一个 led.xdc 文件。

 5. 双击打开这个 led.xdc 文件,在这个文件里添加以下的引脚定义。

############## NET - IOSTANDARD 配置 CFGBVS 管脚的电压和配置电路的电压##################
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
############## clock define 时钟周期、时钟引脚、电平信号约束#######################
create_clock -period 5.000 [get_ports sys_clk_p]
set_property PACKAGE_PIN R4 [get_ports sys_clk_p]
set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_p]
############## reset key define##########################
set_property PACKAGE_PIN F15 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
##############LED define############################
set_property PACKAGE_PIN L13 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]

set_property PACKAGE_PIN M13 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]

set_property PACKAGE_PIN K14 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]

set_property PACKAGE_PIN K13 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
#############SPI Configurate Setting##################
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]

 

 完成后选择菜单 File->Save all files 保存所有文件。

4.4、编译

点击 Run Synthesis ,即可开始综合并生成网表文件:

 Tcl Console 窗口或者 Messages 窗口可以看到一些状态信息。

 

 

 

 

4.5、vivado仿真验证

让仿真工具 Vivado 来输出波形验证流水灯程序设计结果和我们的 预想是否一致。具体步骤如下:

1. 设置 Vivado 的仿真配置,右击 SIMULATION Simulation Settings

2.设置仿真时间

Simulation Settings 窗口中进行如下图来配置,这里设置成 50ms(根据需要自行设定),其它按 默认设置,单击 OK 完成。

3. 添加激励测试文件

点击 Project Manager 下的 Add Sources 图标 , 按下图设置后单击 Next

 4. 点击 Create File 生成仿真激励文件。

 

 在弹出的对话框中输入激励文件的名字,这里我们输入名为 vtf_led_test

 6. 点击 Finish 按钮返回。

 这里我们先不添加 IO Ports,点击 OK

 

Simulation Sources 目录下多了一个刚才添加的 vtf_led_test 文件。双击打开这个文件,可以
看到里面只有 module 名的定义,其它都没有。

7.编写 vtf_led_test.v 文件的内容

接下去我们需要编写这个 vtf_led_test.v 文件的内容。 首先定义输入和输出信号 ,然后需要 实例化 led_test 模块让 led_test 程序作为本测试程序的一部分再添加复位和时钟的激励。完成后的 vtf_led_test.v 文件如下:
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/03/20 22:45:27
// Design Name: 
// Module Name: vtf_led_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module vtf_led_test();
    // Inputs
    //differential system clocks
	reg sys_clk_p;    // Differential input clock 200Mhz
	wire sys_clk_n;   // Differential input clock 200Mhz
	reg rst_n;        //reaet, low active

	// Outputs
	wire [3:0] led;

	// Instantiate the Unit Under Test (UUT)
	led_test uut (
		.sys_clk_p        (sys_clk_p   ), 
		.sys_clk_n        (sys_clk_n   ), 		
		.rst_n            (rst_n       ), 
		.led              (led         )
	);

	initial
	begin
		// Initialize Inputs
		sys_clk_p = 0;
		rst_n = 0;

		// Wait 100 ns for global reset to finish
		#1000;
          rst_n = 1;        
		// Add stimulus here
		#20000;
      //  $stop;
	 end
   
    always #25 sys_clk_p = ~ sys_clk_p;  //5ns 一个周期,产生 200MHz 时钟源
    assign sys_clk_n=~sys_clk_p;
   
endmodule

8. 编写好后保存,vtf_led_test.v 自动成了这个仿真 Hierarchy 的顶层了,它下面是设计文件 led_test.v。

9.进行功能仿真

点击 Run Simulation 按钮,再选择 Run Behavioral Simulation 。这里我们做一下行为级的仿真就可以了。

 如果没有错误,Vivado 中的仿真软件开始工作了。

10. 在弹出仿真界面后如下图,界面是仿真软件自动运行到仿真设置的 50ms 的波形。

由于 LED[3 0] 在程序中设计的状态变化时间长,而仿真又比较耗时,在这里 观测 timer[31:0]计数 器变化。把它放到 Wave 中观察(点击 Scope 界面下的 uut, 再右键选择 Objects 界面下的 timer, 在弹出的下拉菜单里选择 Add Wave Window)

添加后 timer 显示在 Wave 的波形界面上,如下图所示。

 

11. 点击 Restart 按钮复位一下,再点击 Run All 按钮。(需要耐心!!!),可以看到仿真波形与 设计相符。

我们可以看到 led 的信号会逐一变 1 ,说明 LED1~LED4 灯逐个熄灭。
(我这里仿真时间设为20s)

 4.6 下载和调试

       经过前面的编译和仿真,我们可以把 bit 文件下载到 FPGA 芯片中,看一下 LED 实际运行的效果。下载和调试之前先连接硬件,把 JTAG 下载器和开发板连接(如下图是 AX7A200 开发板 JTAG 连接 作为参考),然后开发板上电。
1. 下载之前还需进行设置:右击 PROGRAM AND DEBUG 按下图进行设置。

 设置完成后单击 Generate Bitstream 产生中 bit bin 文件。

2. 点击 Open target 按钮 -->Auto Connect ,在 hardware 界面下 AX7A100 板会显示 xc7a100t_0 的图 标,AX7A200 板会显示 xc7a200t_0 的图标,说明 JTAG 连接已经建立。 注意以下步骤都是以 AX7A100 开发板( xc7a100t_0 )为进行讲述, AX7A200 开发板( xc7a200t_0 )步骤与 AX7A100 的 一致,可以参考下面步骤。

 

 右键选择 xc7a100t_0,在弹出的选项里选择 Program Device 项。

在弹出的 Program Device 对话框中,选择 led_test 项目生成的 bit 文件,点击 Program 按钮烧写
FPGA

 

烧写完成后 , 这时我们可以看到开发板上的四个 LED 灯已经在做流水灯动作了。
你也可以试着别的花样来点亮 LED ,比如,让灯跑得更快一些,或几个灯同时亮同时灭等等,就看你的想象力了,通过自己写程序更能有成就感,而且还能把书本的知识用到实际中,何乐而不为呢!是吧?

4.7、FLASH 程序固化

      可能已经有朋友发现下载 Bit 文件到 FPGA 后,开发板重新上电后配置程序已经丢失,还需要 JTAG 下载。这岂不麻烦!好吧,这一节我们来介绍如何把配置程序固化到开发板上的 FLASH 中, 这样不用担心掉电后程序丢失了。
       在我们的开发板上有一个 8Pin 128Mbit FLASH, 用于存储配置程序。我们不能直接把 Bit
文件下载到这个 FLASH 中,需要把 Bit 文件转换成 BIN 文件或者 MCS 文件。下面以下载 BIN 文件为例为大家介绍 FLASH 程序的固化。
1. 在如下图中右键选择 xc7a100t_0 芯片( AX7A100 开发板为例 ),在弹出的列表中选择 Add
Configruation Memory Device...

 注意:发现此项变为灰色不能选,是因为工程中已经选有 FLASH 配置,不用再添加 flash,如下

当然自己如果想在已有 flash 的工程中再次添加一下进行实验也有办法,可按如下图移除
flash,然后按上面添加 flash 的步骤进行即可:

 2. Add configruation Memory Device 的配置界面里选择正确的 FLASH 型号,如下图所示:

. 提示是否对 SPI FLASH 进行编程, 点击 OK

 

 

       至此, SPI FLASH 烧写完毕, led_test 程序已经固化到 SPI FLASH 中了。我们来验证一下,关电重新启动开发板,等待一会儿你就可以看到开发板上的 LED 灯已经在做跑马运动了。
      可能您也发现了,关电后重新上电需要等好一会儿,开发板上的 LED 灯才会开始启动跑马动作。 这对有些上电马上就要工作的项目肯定是不满足了,那有没有办法解决的呢!当然有的,我们可 以提高 SPI FLASH 的读写时钟,另外使用 x4 的方式读写, QSPI 是支持 4 根数据线读写的哦!方法 很简单,我们只要在 xdc 文件里加入以下 3 条语句:
#############SPI Configurate Setting##################
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] 
set_property CONFIG_MODE SPIx4 [current_design] 
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
      修改 xdc 文件后需要重新编译,再重新生成 bit bin 文件,然后按前面的方法再烧写一遍 SPI FLASH 芯片哈。完成后开发板上电,这下是不是一上电, LED 灯就开始做运动了吧?
      这里为止,我们的第一个项目就圆满完成了,相信您也掌握了 Vivado FPGA 开发的整个流
程,再也不是那个 FPGA 的门外汉了吧! 师傅领进门,修行还需要靠本身!vivado 软件的一些技 巧的使用和掌握就需要靠大家在长期实践和探索中慢慢熟悉了。
注意:在定义寄存器时,如果寄存器在 always 块里使用必须定义为 reg 类型,如果仅是用于
连线或是直接赋值需定义为 wire 类型,输入信号的类型不能定义为 reg 型,不管是 reg 类型信号
还是 wire 类型的信号,定义的寄存器宽度必须满足使用时的需要,但必须稍大于或等于需要使用
的位宽。若定义寄存器位宽远远大于使用需求则会浪费资源,如果定义的位宽小于使用需求,则
会造成数据位截断,导致程序错误。还有其他信号的类型及用法请大家参考 Verilog 语法教程。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。