FPGA上的点灯程序类似于编程上的Hello World,利用此程序可以快速熟悉硬件开发的全流程,为后续的开发奠定基础,故撰此文。开发使用的软硬件参数如下:
开发板提供商 | Alinx |
FPGA提供商 | Xilinx XCZU4EV-SfVC784-1-i |
HLS开发软件 | Vitis HLS 2022.2 |
RTL开发软件 | Vivado 2022.2 |
Vitis HLS IP核开发
创建工程
首先利用Vitis HLS软件进行IP核的开发。小白提示,下载完Vitis后会出现两个软件:Xilinx Vitis和Vitis HLS,我们要点及Vitis HLS并等待一段时间,命令行黑框消失后会弹出开发界面,大致这个样子的界面才是HLS开发的正确界面:
点击Create Project创建新工程,本文创建工程名称为led_control。一路next到如下界面,点击Part Selection栏右侧方框选择自己的芯片型号:
Finish后进入工程页面:
左侧可以看到名为Source的源代码文件夹和名为Test Bench的仿真代码文件夹。我们在Source处右键-new source file,创建文件led_control.cpp,并输入如下代码:
#include <ap_int.h>
void led_control(ap_uint<1> &led)
{
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=led
unsigned int i;
led=0;
for(i=0; i<50000000; i++)
{
#pragma HLS PIPELINE
led = (i<50000000/2)?(~led):led;
}
}
保存后的页面结构:
值得注意的是,工程内显示的led_control.cpp文件仅仅是一个连接,这意味着在工程内删除此文件并不会删除源文件,同理的,我们可以在任何位置写源文件,并在工程内添加文件的链接即可。
添加顶层文件
综合项目前我们需要添加项目的顶层文件。方法为点击顶部project-project settings-synthesis,在右侧选择Browse并添加方法led_control即可
综合工程
写完source代码后,点击左侧Run C Synthesis或者点击顶部Solution-Run C Synthesis-Active Solution进行程序综合。
综合结束后会弹出综合报告,显示设计需要的资源。
导出工程IP核
在综合成功后,我们需要导出设计文件对应的IP核供后续使用,因此点击左侧Exprot RTL或者顶部Solution-Export RTL进行导出。当控制台显示“Finished Export RTL/Implementation.”后导出成功。此时整个IP核体现在Solutin1文件夹内。
至此,Vitis部分的工作已经完成。
Vivado硬件部署
当我们获得IP核后,我们需要在Vivado端对IP核进行封装、约束、生成bit文件等操作后方可向硬件平台部署。
新建Vivado项目
新建细节不再赘述,注意新建过程中要选择与Vitis中相同的芯片型号:
新建后的项目:
引用HLS IP核
首先需要对HLS生成的IP核进行引用,点击Settings-IP-Repository-加号,将路径定位在Vitis项目文件夹内solution1内并点击Select,随后Vivado会识别到此IP核:
识别后点击OK将此IP核保存。点击IP Catalog并选择User Repository可以查看此IP核是否正确导入:
双击Led_control可以看到此IP核的结构:
点击OK-Generate后令此IP核出现在Sources框的Design Sources中:
封装IP核,生成wrapper文件
点击Create Block Design生成设计文件,点击加号➕添加刚刚导入的led核,分别点击三个端口并ctrl+T生成输入输出接口:
随后回到Sources部分,右键design_1文件并点击Create HDL Wrapper生成Wrapper文件。
生成顶层文件和测试文件
分别添加设计文件top.v和仿真文件test.v对IP核进行引用和仿真。两个文件内容如下:
top.v:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/01/09 19:54:09
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top(
input sys_clk_p,
input sys_clk_n,
input ap_rst,
output out
);
wire sys_clk ;
IBUFDS IBUFDS_inst (
.O(sys_clk), // Buffer output
.I(sys_clk_p), // Diff_p buffer input (connect directly
.IB(sys_clk_n) // Diff_n buffer input (connect directly to
);
reg[31:0] cnt=32'd0;
wire led;
assign out = led;
always@(posedge sys_clk)begin
if(ap_rst==1'b1)begin
cnt<=32'd0;
end
else begin
cnt<=cnt+32'd1;
end
end
design_1_wrapper design_1_wrapper(
.ap_clk_0(sys_clk),
.ap_rst_0(ap_rst),
.led_0(led)
);
endmodule
test.v:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/01/09 19:54:24
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module test();
// Inputs
reg sys_clk_p;
reg rst_n ;
wire sys_clk_n;
// Outputs
wire led;
// Instantiate the Unit Under Test (UUT)
top uut (
.sys_clk_p(sys_clk_p),
.sys_clk_n(sys_clk_n),
.ap_rst(rst_n),
.out(led)
);
initial
begin
// Initialize Inputs
sys_clk_p = 0;
rst_n = 0;
// Wait for global reset to finish
#1000;
rst_n = 1;
end
//Create clock
always #2.5 sys_clk_p = ~ sys_clk_p;
assign sys_clk_n = ~sys_clk_p ;
endmodule
仿真模拟
点击Run Simulation-Run Behavior Simulation,可以看到rst_n为0时,led每个上升沿到来后反转,达到了预期效果。
添加管脚约束
添加Constraints文件led_control并添加如下代码完成管脚约束:
set_property PACKAGE_PIN AE5 [get_ports sys_clk_p]
set_property PACKAGE_PIN AF12 [get_ports ap_rst]
set_property PACKAGE_PIN AE12 [get_ports out]
set_property IOSTANDARD LVCMOS33 [get_ports out]
set_property IOSTANDARD LVCMOS33 [get_ports ap_rst]
set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_p]
保存后也可以点击Open Elaborated Design后在下方Package Pin一栏查看绑定的管脚。其中out绑定到了PL端的led灯,ap_rst绑定到了PL端的按键上。
硬件部署
部署前,分别点击Run Synthesis和Run Implementation进行综合和实现,随后点击Generate Bitstream生成比特流文件。生成后点击Open Hardware Manager选项并点击OK打开硬件管理器:
随后将开发板启动状态拨到JTAG(0000),连接JTAG下载器后上电:
在硬件管理器界面点击Open target-Auto Connect连接开发板:
其中xczu是PL端,arm是PS端。右键PL端并点击Program Device,将生成的比特文件下载到PL端:
下载完成后测试IP核功能:按下PL端按键后PL端LED灯开始闪烁(不是太清楚,大致效果如下):