一.前言
我们通过一个
LED
例程来熟悉 PL
(
FPGA
)的开发流程,熟悉
Vivado
软件的基本操作,这个开发流程和不带
ARM
的 FPGA 芯片完全一致。
在本例程中,我们要做的是 LED
灯控制实验,每秒钟控制开发板上的
LED
灯翻转一次,实现亮、灭、亮、灭的控制。主要是关于Vivado开发流程和程序的操作过程。
二.创建Vivado工程
我使用的是这个版本Vivado 2022.2版本,这个版本大家可以在官网下载。
1.点击Create Project创建工程
2.弹出一个建立新工程的向导,点击“Next”
在弹出的对话框中输入工程名和工程存放的目录,我们这里取一个
led
的工程名。需要注
意工程路径“
Project location
”不能有中文空格,路径名称也不能太长。
3.在工程类型中选择“RTL Project”
4.目标语言“Target language”选择“Verilog”,虽然选择 Verilog,但 VHDL 也可以使用,支持多语言混合编程。
5.点击“Next”,不添加任何文件
6.选择芯片类型
7.点击finish工程创建完毕
8.页面显示
三.创建Verilog工程文件
1点击 Project Manager 下的 Add Sources 图标
2.创建文件
3.输入文件名,点击OK
4.点击Finsh完成文件创建
5.在弹出的模块定义“Define Module”,中可以指定“led.v”文件的模块名称“Module name”,这里默认不变为“led”,还可以指定一些端口,这里暂时不指定,点击“OK”
6.在对话框中点击YES
7.双击点开led可以进行编辑
注:这里比较推荐用vscode进行编辑,可能是我个人的习惯,这里可以更改程序编辑器方式如下:
1)点击tools下的setting
2)点击Text Editor,在这里选择Custom Editor
3)输入VS Code的绝对路径
我的路径是这个D:\Microsoft VS Code\Code.exe -g [file name]:[line number],这里需要键入的表达式是: C:/Program Files/Microsoft VS Code/Code.exe -g [file name]:[line number],大家根据个人的安装位置进行更改。
4)点击OK,然后apply
5)此时双击LED我们进入vscode编辑界面
8.程序代码
编写“
led.v
”
,
这里定义了一个
32
位的寄存器
cnt0,
用于循环计数
0~49999999(1
秒钟
), 计数到 49999999(1
秒
)
的时候
,
寄存器
timer
变为
0
,此时反转led的状态。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/09/12 16:07:55
// Design Name:
// Module Name: led
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module led(
input clk,
input rst_n,
output [3:0] led
);
reg [32:0] cnt0;
wire add_cnt0;
wire end_cnt0;
reg [3:0] led_r ;
localparam TIME_1S = 49_999_999;//计数到1s
//**************************************计数一秒***********************************//
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt0 <= 0;
else if(add_cnt0)
begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
end
assign add_cnt0 = 1;
assign end_cnt0 = add_cnt0 && cnt0 == TIME_1S - 1;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
led_r<=4'b0;
end
else if(end_cnt0)
begin
led_r <=~led_r;
end
else
begin
led_r <= 4'b0;
end
end
assign led =led_r;
endmodule
四.添加管脚约束
1.点击“Open Elaborated Design”
2.在弹出的窗口中点击“OK”按钮
3.在菜单中选择“Window -> I/O Ports”
4.在弹出的 I/O Ports 中可以看到管脚分配情况
修改电气标准:
这里我已经对管脚进行了分配,分配后记得保存。
5.弹出窗口,要求保存约束文件,文件名我们填写“led”,文件类型默认“XDC”,点击 “OK”
6.打开刚才生成的“led.xdc”文件,我们可以看到是一个 TCL 脚本,如果我们了解这些语法,完全可以通过自己编写 led.xdc 文件的方式来约束管脚。
set_property PACKAGE_PIN J16 [get_ports {led[3]}]
set_property PACKAGE_PIN K16 [get_ports {led[2]}]
set_property PACKAGE_PIN M14 [get_ports {led[0]}]
set_property PACKAGE_PIN N15 [get_ports clk]
set_property PACKAGE_PIN M15 [get_ports {led[1]}]
set_property PACKAGE_PIN U18 [get_ports rst_n]
create_clock -period 20.000 -name clk -waveform {0.000 10.000} [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
五.添加时序约束
1.点击“Run Synthesis”开始综合
2.点击OK
3.点击Cancel
4.点击“Constraints Wizard”
5.点击next
6.时序约束向导分析出设计中的时钟,这里把“sys_clk”频率设置为 50Mhz,然后点击“Skip to Finish”结束时序约束向导。
7. 弹出的窗口中点击“OK”
8. 点击“Finish”
9.这个时候 led.xdc 文件已经更新,点击“Reload”重新加载文件,并保存文件
六.生成BIT文件
1.点“Generate Bitstream”
2.编译的过程可以细分为综合、布局布线、生成 bit 文件等,这里我们直接点击“Generate
Bitstream”,直接生成 bit 文件。
2.可以看右上角发现我们此时已经在编译
3.编译中没有任何错误,编译完成,弹出一个对话框让我们选择后续操作,可以选择“Open Hardware Manger”,当然,也可以“Cancel”,我们这里选择 “Cancel”,先不下载。
七.Vivado仿真
1.设置 Vivado 的仿真配置,右击 SIMULATION 中 Simulation Settings。
2.在 Simulation Settings 窗口中进行如下图来配置,这里设置成 50ms(根据需要自行设定), 其它按默认设置,单击 OK 完成。
3.添加激励测试文件,点击 Project Manager 下的 Add Sources 图标,按下图设置后单击 Next。
4. 点击 Create File 生成仿真激励文件。
这里我们先不添加IO端口。
在
Simulation Sources
目录下多了一个刚才添加的
vtf_led_test
文件。双击打开这个文件,可以看到里面只有 module
名的定义,其它都没有。
接下去我们需要编写这个
vtf_led_test.v
文件的内容。首先定义输入和输出信号,然后需要实例化 led_test
模块,让
led_test
程序作为本测试程序的一部分。再添加复位和时钟的激励。
module vtf_led_test;
// Inputs
reg clk;
reg rst_n ;
// Outputs
wire [3:0] led;
// Instantiate the Unit Under Test (UUT)
led uut (
/* input */ .clk(clk),
/* input */ .rst_n(rst_n),
/* output */.led(led)
);
initial
begin
// Initialize Inputs
clk = 0;
rst_n = 0 ;
#1000 ;
rst_n = 1;
end
//Create clock
always #10 clk = ~ clk;
endmodule
5.编写好后保存,vtf_led_test.v 自动成了这个仿真 Hierarchy 的顶层了,它下面是设计文件led.v。
6.点击 Run Simulation 按钮,再选择 Run Behavioral Simulation。这里我们做一下行为级的仿真就可以了。
7.观察仿真
八.小结
本次led的实验已经完成,主要是初次接触还是有很多步骤要一步步慢慢来。可能在处理过程中会有少许的问题,欢迎大家的批评与指正。