Vivado开发套件设计笔记(2)——加法器设计——变量(下)

接上一篇博文Vivado开发套件设计笔记(2)——加法器设计——变量(上)

上一篇博文为读者介绍了 HLS 中自定义的 加法器IP核 的制作,然后在 Vivado 中把 IP核 加入到工程中与 ZYNQ Processing System 相连,然后导出硬件信息供给 SDK 用,至于 SDK 怎么用这个自定义的 加法器IP核 ?笔者在这一篇博文继续给读者讲解。

4 SDK设计

Vivado 软件中运行 SDK 后会出现下面的界面(读者会发现这款 SDK 是用 Eclipse 开发的)。上面两个框是我们的硬件信息,下面的框框内的 add_0 就是 加法器IP核 导出的硬件信息了。

在这里插入图片描述

(1)创建工程

在菜单栏点击 File —— New —— Application Project ,弹出创建工程界面,输入项目名为 add (英文的无空格就可以),如下图所示,然后点击 Next

在这里插入图片描述
然后选择工程模板,选择 Hello World 工程模板,如下图。

在这里插入图片描述
工程创建成功后如下图所示。
在这里插入图片描述

(2)程序设计

点开导航栏左侧的 Project Explorer 会发现里面有很多的文件,其中最最重要的就三个:第一个是 add/src/Helloworld.c ,这个 c文件 里面有ZYNQ的CPU程序入口 main函数 ;第二个是 add_bsp/ps7_cortexa9_0/include/xparameters.h ,这个头文件里面有我们所用到的 加法器IP核 映射到FPGA的DDR中的内存地址和相关驱动参数(这些是 自动生成 的);第三个是add_bsp/ps7_cortexa9_0/include/xadd.h ,其命名方式是与读者设计的 IP核命名 相关,在其前面加上一个 ‘x’ 而已,比如我们的加法器是 add ,因此它的命名方式就是 xadd.h ,这里面存放着我们调用自定义 加法器IP核 的库函数(或者叫做 驱动)。

有了以上三个文件,就可以开始 搞事情 了。

第一步,点开 helloworld.c ,输入以下代码。

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xadd.h"

int main()
{
    init_platform();
    print("Hello World\n\r");

    XAdd MyAdd;

    int status;
    status = XAdd_Initialize(&MyAdd, XPAR_ADD_0_DEVICE_ID);
    if(status == XST_SUCCESS)
    	print("IP Initialize successfully !\n\r");

    int ps_res;
    int ps_a = 15;
    int ps_b = 5;
    int pl_res, pl_a, pl_b;

    XAdd_Set_a(&MyAdd, ps_a);
    XAdd_Set_b(&MyAdd, ps_b);
    XAdd_Start(&MyAdd);
    while(!XAdd_IsDone(&MyAdd));
    pl_a = XAdd_Get_a(&MyAdd);
    pl_b = XAdd_Get_b(&MyAdd);
    pl_res = XAdd_Get_return(&MyAdd);
    ps_res = ps_a + ps_b;

    printf("\n\rARM(PS) : %d + %d = %d \n\r", ps_a, ps_b, ps_res);
    printf("\n\rFPGA(PL) : %d + %d = %d", pl_a, pl_b, pl_res);

    cleanup_platform();
    return 0;
}

首先需要先定义 XAdd 类型的结构体 MyAdd ,再调用 XAdd_Initialize() 初始化 IP核 ,如果返回值为 XST_SUCCESS 即表示初始化成功。然后定义PS端(ZYNQ,ARM)和PL(FPGA)端的变量,之后利用库函数 XAdd_Set_a()XAdd_Set_b() 把变量送到PL端,接着调用 XAdd_Start() 启动PL端的 IP核 开始计算,然后利用 while(!XAdd_IsDone(&MyAdd)); 阻塞方式等待 IP核 运算完毕,最后用 XAdd_Get_return() 取得 IP核 的返回值。最终用ARM和FPGA做计算,对比结果,验证是否有误。

上述的 XAdd 结构体类型,以及对 IP核 的调用的库函数(驱动)全部来自于头文件 xadd.h 中。其中 XAdd_Initialize() 的第二个参数是 IP核ID ,这个 ID 号到 xparameters.h 头文件中找。所有用到的东西都在下面的截图中。注意红色方框。之后有用到我会再补充介绍其他函数,本篇博文节省篇幅先把用到的都介绍了,其他的放到之后的博文介绍。

在这里插入图片描述

在这里插入图片描述

(3)烧录程序

程序写好之后就可以烧录到板子上了。

第一步先把程序烧录到 ZYNQ 上,如下图所示操作。
在这里插入图片描述
用串口连接PC和开发板,(这里假设读者都已经安装好串口驱动之类的,如果不知道怎么做的,提供开发板的产商应该会给相应的资料,照做即可),打开串口调试助手,看运行结果,如下图所示。可以看到这里程序只运行到初始化这一步,没有之后我们所预想的有打印数据出来,这主要是因为硬件信息未烧录到FPGA中,因此在运行 while(!XAdd_IsDone(&MyAdd)); 会阻塞住不正常运行,到下一步。
在这里插入图片描述
第二步,把程序同时烧录到 ZYNQFPGA 上,操作如下图所示。

在这里插入图片描述

在这里插入图片描述
如果出现下面图示的警告,点 OK ,等待串口助手显示我们预想的结果就可以了。

在这里插入图片描述
如果读者都按照以上操作做完的话,会在串口助手上看到这样的结果,跟我们的预期一样,大功告成。

在这里插入图片描述
这里补充两点:

第一点是为什么要先烧录到ARM再烧录到FPGA,因为一个新的工程如果没有进行烧录到ARM的操作的话,之后烧录到FPGA的操作界面会缺少一个生成的System Debugger,有兴趣的读者可以试一下。

第二点是串口正常连接时的设备显示和串口调试助手的配置,如下图所示。

在这里插入图片描述
在这里插入图片描述
正常安装完USB驱动之后,用USB线把开发板上的UART口和JTAG口分别连到PC上,就可以正常使用了。

至此,所有的操作完成。

5 总结

这篇博文笔者详细的介绍了从HLS上IP核的制作,到Vivado上顶层电路的连接,最后到SDK上应用程序的开发,完成了用ARM核控制FPGA完成特定功能的任务。

我们把流程重新理一遍。

  • HLS制作IP核
    • C仿真(C Simulation)
    • C综合(C Synthesis)
    • C/RTL 联合仿真(C/RTL Cosimulation)
    • 导出RTL(Export RTL)
  • Vivado构建完整电路
    • 把自定义IP核添加到IP Catalog(Add Repository)
    • 创建Block Design并添加自定义IP核以及ZYNQ处理系统,然后配置ZYNQ(Create Block Design)
    • 在Block Design中自动连接ZYNQ和自定义IP核并导出必要端口(Open Block Design)
    • 封装HDL并生成硬件输出(Create HDL Wrapper & Generate Output Products)
    • 运行项目(Run Implementation)
    • 生成bitstream并导出硬件(Generate Bitstream & Export Hardware)
  • SDK开发应用程序
    • 包含自定义IP核对应的驱动头文件(例如 xadd.h)
    • 声明自定义IP核对应的结构体并初始化(例如 XAdd MyAdd)
    • 利用库函数把数据输入到IP核,然后等待IP核运算完毕,再取输出数据
    • 把程序烧录到ARM上
    • 把程序同时烧录到ARM和FPGA上
    • 利用串口调试助手检验设计

以上便是全部操作流程,读者之后在自行设计的时候,都要走上面这一串流程,唯一可以跳过的只有C/RTL Cosimulation,因为对一些比较大型的IP核,这个过程特别慢而且非必要,除此之外每一个步骤都不能缺少。

虽然笔者只用了最简单的加法器作为例子给读者讲解这一套开发技巧,但是加法是所有运算的基础,只要加法调通了,之后再做其他的操作都简单很多了,这就像程序员在学习每一门编程语言的“Hello World”一样。希望没有相关开发经验的读者能完整地把这一流程走一遍,之后自己便能举一反三,慢慢摸出自己的一条硬件开发之路。

读到这里,读者们可能会问:如果变量不是int型的而是float型的话话怎么办?如果要用来计算的数据是一个数组的话怎么办?这就是笔者为什么要在标题中加上“变量”这个字眼,是因为我们设计的IP核用的输入输出都是变量而不包含指针,涉及指针的操作会有一些不一样,笔者将在下一篇博文给读者介绍。

6 参考文章

[1]: Xilinx Zynq-7000 嵌入式系统设计与实现(何宾著)
[2]: Vivado开发套件设计笔记(1)——入门简介
[3]: Vivado开发套件设计笔记(2)——加法器设计——变量(上)
[4]: Xilinx官方文档《ug871-vivado-high-level-synthesis-tutorial》
[5]: Xilinx官方文档《xapp1170-zynq-hls》


原创性声明:本文属于作者原创性文章,小弟码字辛苦,转载还请注明出处。谢谢~

如果有哪些地方表述的不够得体和清晰,有存在的任何问题,亦或者程序存在任何考虑不周和漏洞,欢迎评论和指正,谢谢各路大佬。

需要代码和有需要相关技术支持的可咨询QQ:297461921

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值