搜索
bottom↓
回复: 0

【正点原子FPGA连载】第四章呼吸灯实验--摘自【正点原子】领航者ZYNQ之HLS 开发指南

[复制链接]

出0入234汤圆

发表于 2020-9-25 10:13:02 | 显示全部楼层 |阅读模式
1)实验平台:正点原子领航者ZYNQ开发板
2)购买链接:https://item.taobao.com/item.htm?id=606160108761
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html
4) 正点原子官方B站:https://space.bilibili.com/394620890
5)对正点原子FPGA感兴趣的同学可以加群讨论:876744900 点击加入:
QQ群头像.png                                                                                                            
6)关注正点原子公众号,获取最新资料


100846rel79a9p4uelap24.jpg

100846f1ce1fg14zbg0va4.png
第四章呼吸灯实验



在前面两个实验中我们学习了如何通过Vivado HLS工具来生成带有一个ap_none接口的IP核。在本章我们将通过呼吸灯实验,来学习如何使用Vivado HLS工具生成一个带有AXI4-Lite总线接口的IP核,并学习Vivado HLS工具C/RTL协同仿真平台的使用,以及在Vivado中对综合结果进行验证的流程。
本章包括以下几个部分:
44.1简介
4.2实验任务
4.3HLS设计
4.4IP验证
4.5下载验证


4.1简介
呼吸灯采用PWM的方式,在固定的频率下,通过调整占空比的方式来控制LED灯亮度的变化。PWM(Pulse Width Modulation),即脉冲宽度调制,它利用微处理器输出的PWM信号,实现对模拟电路控制的一种非常有效的技术,广泛应用于测量、通信、功率控制等领域。
在由计数器产生的固定周期PWM信号下,如果其占空比为0,则LED灯不亮;如果其占空比为 100%,则LED灯最亮。所以将占空比从0到 100%,再从100%到0不断变化,就可以实现LED灯的“呼吸”效果。
PWM 占空比调节示意图如下图所示:
阿莫论坛发帖领航者专用1466.png

图 4.1.1 呼吸灯PWM占空比示意图

由上图可知,LED高电平的时间由长渐渐变短,再由短渐渐变长,如果LED灯是高电平点亮,则LED 灯会呈现出亮度由亮到暗,再由暗到亮的过程。
在本章我们将实现一个频率可调和开关可控制的呼吸灯,因此就需要一个接口来配置呼吸灯的频率和开关。我们可以通过Vivado HLS生成一个带有AXI4-Lite总线接口的IP核,然后在ZYNQ PS端通过AXI4-Lite总线来配置此IP核。
AXI的英文全称是 Advanced eXtensible Interface,即高级可扩展接口,它是 ARM 公司所提出的 AMBA (Advanced Microcontroller Bus Architecture)协议的一部分。AXI协议包含了AXI4、AXI4-Lite和AXI-Stream三种协议。
AXI4 协议支持突发传输,主要用于处理器访问存储器等需要指定地址的高速数据传输场景。AXI-Lite 为外设提供单个数据传输,主要用于访问一些低速外设中的寄存器。而AXI-Stream 接口则像 FIFO 一样,数据传输时不需要地址,在主从设备之间直接连续读写数据,主要用于如视频、高速 AD、PCIe、DMA接口等需要高速数据传输的场合。
AXI4-Lite接口是简化版的AXI4接口,用于较少数据量的存储映射通信。本次实验只需要配置呼吸灯IP核的频率和开关,因此接口类型选择AXI4-Lite接口。
4.2实验任务
本节实验任务是使用正点原子ZYNQ开发板(核心板)上的 PL LED,实现呼吸灯的效果,即由灭渐亮,然后再由亮渐灭,并且PS可以通过AXI接口来控制呼吸灯的开关和呼吸的频率。
4.3HLS设计
我们在电脑中的“F:\ZYNQ\High_Level_Synthesis”目录下新建一个名为breath_led的文件夹,作为本次实验的工程目录。然后打开Vivado HLS工具,创建一个新的工程。设置工程名为“breath_led_hls”,选择工程路径为刚刚创建的文件夹。需要注意的是,工程名以及路径只能由英文字母、数字和下划线组成,不能包含中文、空格以及其他特殊字符。如下图所示:
阿莫论坛发帖领航者专用11425.png

图 4.3.1 工程配置界面

设置好工程名及路径之后,点击“Next”,进入如下界面设置顶层函数:
阿莫论坛发帖领航者专用11520.png

图 4.3.2 设置顶层函数

工程创建完成后,在工程面板中的“source”目录上点击右键,然后在打开的列表中选择“New File”新建源文件,在弹出的对话框中输入源文件的名称“breath_led.c”,如图1.3.3所示。源文件默认的保存路径为HLS工程目录,为方便源文件的管理,我们在工程目录下新建一个名为“src”的文件下,将源文件保存在src目录下。
阿莫论坛发帖领航者专用11747.png

图 4.3.3 输入源文件名

我们在图1.3.3中输入的源文件的后缀名为“.c”,即使用C语言进行设计。如果使用C++语言进行设计,那么后缀名需要设置为“.cpp”。设置好文件名和路径之后,点击“保存”。
“breath_led.c”文件源代码如下:
  1. 1  #include "breath_led.h"
  2. 2  
  3. 3  void breath_led(uint32 sw_ctrl, uint32 freq_step, uint1* led)
  4. 4  {
  5. 5  #pragma HLS INTERFACE ap_none port=led
  6. 6  #pragma HLS INTERFACE s_axilite port=freq_step
  7. 7  #pragma HLS INTERFACE s_axilite port=sw_ctrl
  8. 8  #pragma HLS INTERFACE ap_ctrl_none port=return
  9. 9    uint32 duty_cycle,period_cnt;
  10. 10   if(sw_ctrl == 1){
  11. 11       for(duty_cycle=0; duty_cycle<50000; duty_cycle=duty_cycle+freq_step){
  12. 12          for(period_cnt=0; period_cnt<50000; period_cnt++)
  13. 13              *led = (period_cnt <= duty_cycle) ? 1 : 0 ;
  14. 14       }
  15. 15      
  16. 16       for(duty_cycle=50000; duty_cycle>0; duty_cycle=duty_cycle-freq_step){
  17. 17          for(period_cnt=0; period_cnt<50000; period_cnt++)
  18. 18              *led = (period_cnt <= duty_cycle) ? 1 : 0;
  19. 19       }
  20. 20   }else   
  21. 21       *led = 0;
  22. 22 }
复制代码

在代码的第1行,包含了一个名为“breath_led.h”的头文件,这个是我们自己创建的头文件。“breath_led.h”的创建方式和“breath_led.c”的创建方式相同。创建此头文件的目的是为了函数声明,以便在测试文件中引入此头文件,从而在测试文件中可以调用我们所编写的函数。
在代码的第3行,我们在定义函数参数类型时,使用了“uint1”这种数据类型,它表示1位无符号整数。在代码的第5行到代码的第7行,#pragma为HLS优化指令,它表示led使用的是“ap_none”协议,呼吸灯开关“sw_ctrl”和频率控制字“freq_step”使用的是AXI4-Lite协议。在代码的第8行“ap_ctrl_none”表明没有添加包级别的协议,而是完全在端口接口级别用端口级别协议来做控制。
在代码的第10行是一个条件判断语句,它通过判断sw_ctrl的值来控制呼吸灯的开关。当sw_ctr的值为1时,呼吸灯打开,对应着代码的第11行到第19行;当sw_ctrl的值为0时,呼吸灯关闭,对应着代码的第21行。
在代码第12行的for循环语句通过不断增加每个PWM周期中的占空比(duty_cycle),从而实现呼吸灯从暗到亮的过程。变量freq_step用于控制呼吸灯占空比变化的“步长”,步长越大,占空比变化的越快,那么呼吸灯由暗到亮的时间越短,即呼吸频率变快。
在代码的第13行是一个三目运算符,它通过判断period_cnt和duty_cycle(占空比)值的大小来控制LED灯的输出状态。如果条件满足,即period_cnt小于duty_cycle,led赋值为1,表示点亮LED;反之,led赋值为0,表示熄灭LED。
第16至19行的for循环和第11至14行的for循环基本相同,唯一的区别是第16行中的占空比duty_cycle不断减小,从而实现呼吸灯从亮到暗的过程。
头文件“breath_led.h”的代码如下:
  1. 1 #include "ap_cint.h"
  2. 2
  3. 3 #ifndef _BREATH_LED_H
  4. 4 #define _BREATH_LED_H_
  5. 5
  6. 6 void breath_led(int sw_ctrl, uint32 freq_step, uint1* led);
  7. 7
  8. 8 #endif
复制代码

在代码的第1行我们引入了“ap_cint.h”的头文件来包含任意精度数据类型。在代码的第3行到第4行表示如果没有定义“breath.h”头文件则定义这个头文件,这样可以避免头文件的重复定义。在代码第6行,我们声明了“breath_led”函数,从而在测试文件中可以调用此函数。
在工程面板中的“Test Bench”目录上点击右键,然后在打开的列表中选择“New File”新建测试文件, 在弹出的对话框中输入测试文件的名称“breath_led_tb.c”,如图1.3.4所示。测试文件的保存路径为src目录。
阿莫论坛发帖领航者专用13970.png

图 4.3.4 新建测试文件

在测试文件中编写如下代码:
  1. 1  #include "breath_led.h"
  2. 2  
  3. 3  int main(void)
  4. 4  {
  5. 5      uint1 led;
  6. 6  
  7. 7      breath_led(1, 2000, &led);   //打开呼吸灯,频率步长设置为2000
  8. 8      breath_led(0, 2000, &led);   //关闭呼吸灯
  9. 9  
  10. 10     printf("test passed!\n");
  11. 11     return 0;
  12. 12 }
复制代码

        在测试文件中,我们通过调用“breath_led”函数,设置呼吸灯开关控制“sw_ctrl”为1打开呼吸灯,设置呼吸灯频率步长“freq_step”为2000来实现验证呼吸灯功能。
代码输入完成后,按快捷键Ctrl+S保存。然后点击工具栏中向右的绿色三角形对C代码进行综合,如下图所示:
阿莫论坛发帖领航者专用14399.png

图 4.3.5 运行C综合

综合完成后,会自动打开综合结果(solution)的报告,如下图所示:
阿莫论坛发帖领航者专用14469.png

图 4.3.4 综合报告

在所示的综合报告中,给出了设计的性能评估、资源评估以及接口等信息。本次实验中,我们重点关注综合工具为我们生成的接口信息,如下图所示:
阿莫论坛发帖领航者专用14594.png

图 4.3.5 接口信息

从图中Protocol一栏可以看出,红色方框里的协议类型为“s_axi”,它表示AXI从接口,其中s表示Slave(从端口)。然后在Source Object一栏可以看到,接口类型为“AXILiteS”,即AXI4-Lite从接口。主机可以通过AXI4-Lite总线协议配置此IP核。
下面我们进行仿真,来测试HLS设计是否满足要求。因为Vivado HLS工具不支持“ap_ctrl_none”包级别协议的仿真,所以我们在仿真前先删除所有的优化指令,如下图所示:
阿莫论坛发帖领航者专用14885.png

图 4.3.6 删除优化指令

然后再点击工具栏中的“Solution”按钮,在打开的列表中选择“Run C/RTL Cosimulation”进入C/RTL协同仿真,如下图所示:
阿莫论坛发帖领航者专用15020.png

图 4.3.7 运行C/RTL协同仿真

弹出C/RTL仿真配置界面,我们在配置界面中选择使用“Vivado Simulator”仿真器,“Dump Trace”选择“all”表示生成仿真波形。如下图所示:
阿莫论坛发帖领航者专用15168.png

图 4.3.10 C/RTL仿真配置界面

点击“OK”按钮,C/RTL仿真完成后,会在控制台看到下图所示信息,表明C/RTL协同仿真通过。
阿莫论坛发帖领航者专用15258.png

图 4.3.11 C/RTL协同仿真通过界面

        接着在工具栏中点击波形按钮,如下图所示:
阿莫论坛发帖领航者专用15323.png

图 4.3.12 波形按钮

        Vivado HLS会自动打开Vivado Simulation仿真工具,将图中所示信号添加到波形窗口中,如下图所示:
阿莫论坛发帖领航者专用15418.png

图 4.3.13 添加波形文件

        波形如下图所示:
阿莫论坛发帖领航者专用15464.png

图 4.3.14 波形图

阿莫论坛发帖领航者专用15497.png

图 4.3.15 波形图

当呼吸灯控制“sw_ctrl”为1,呼吸灯功能打开时,生成PWM波的占空比逐渐增大后又逐渐减小,说明呼吸灯由暗到亮后又由亮变暗。当呼吸灯控制sw_ctrl为0,输出“led_ap_vld”信号为高,数据有效时,led的值一直是0,表示呼吸灯关闭。通过C/RTL协同仿真表明HLS综合得到的RTL设计符合预期的功能要求。
至此C/RTL协同仿真设计完成,通过仿真C/RTL协同仿真我们验证了HLS设计的正确性。下面我们将设计打包成IP模块,以供Vivado开发套件中的其他工具(如IP集成器)使用。
将之前删除的优化指令重修添加到Vivado HLS工程中,在工具栏中点击黄色的“田”字按钮,导出RTL,如下图所示:
阿莫论坛发帖领航者专用15838.png

图 4.3.16 导出RTL

在弹出的对话框中保持默认设置,直接点击“OK”,如下图所示:
阿莫论坛发帖领航者专用15904.png

图 4.3.17 将设计导出成IP

设计导出完成后,HLS设计部分就结束了,我们在HLS工程目录下可以找到导出的IP核,如下图红色方框所示:
阿莫论坛发帖领航者专用15995.png


图 4.3.18导出得到的IP

我们到计算机工程目录所指向的文件夹中同样可以看到以ZIP压缩文件形式存在的IP核,如下图所示:
阿莫论坛发帖领航者专用16080.png

图 4.3.19 文件夹中的IP核

HLS设计结束之后,我们将在Vivado中对导出的IP核进行验证。
4.4IP验证
在IP验证环节,我们会使用Vivado工具的IP集成器将生成的IP核添加到Block Design中,然后完成设计后将程序下载到领航者开发板上进行验证。
我们在《领航者ZYNQ之嵌入式开发指南》第一章“Hello World实验”中详细介绍了如何使用Vivado创建工程,以及如何使用IP集成器(IP INTEGRATOR)创建Block Design。如果大家对这一部分内容不熟悉的话,一定要先按照《领航者ZYNQ之嵌入式开发指南》中第一章的描述,把这一流程完整的操作一遍,然后才能进行本章的IP验证环节。
在本次实验中,我们创建一个名为“key_led_ip_test”的Vivado工程。为了方便工程管理,我们将Vivado工程的目录与HLS工程目录保持一致,如下图所示:
阿莫论坛发帖领航者专用16497.png

图 4.4.1 创建Vivado工程

Vivado工程创建完成之后,本次实验的工程目录如下图所示:
阿莫论坛发帖领航者专用16592.png

图 4.4.2 按键控制LED实验工程目录

图 2.4.2中,以“_hls”结尾的文件夹为Vivado HLS工程,以“_ip_test”结尾的是用于IP验证的Vivado工程。
工程创建完成后,需要先将HLS设计过程中导出的IP核拷贝到Vivado工程目录下。我们在Vivado工程目录下新建一个名为“ip_repo”的文件夹,然后将图 2.3.26中的压缩包拷贝到该文件夹中并解压,解压完成后如下图所示:
阿莫论坛发帖领航者专用16890.png

图 4.4.3 拷贝并解压IP

接下来在Vivado中将该IP添加到工程的IP库中。添加IP核完成之后,创建一个名为“system”的Block Design。在设计中添加breath_led和ZYNQ两个IP核,并配置ZYNQ。最后连接两个IP并创建外部端口。如果大家对IP的配置和连接方式不清楚的话,请大家参考《领航者ZYNQ之嵌入式开发指南》中第五章“AXI GPIO 按键控制 LED 实验”第3小节硬件设计部分。最终完成的设计如下图所示:
阿莫论坛发帖领航者专用17160.png

图 4.4.4 完成后的Block Design

到这里我们的Block Design就设计完成了,在Diagram窗口空白处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误,点击“OK”确认。最后按快捷键“Ctrl + S”保存设计。
接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。
然后我们还要为设计创建约束文件navigator.xdc,并在文件中添加以下管脚约束信息:
set_property -dict {PACKAGE_PIN J16 IOSTANDARD LVCMOS33} [get_ports led]
最后在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,对设计进行综合、实现、并生成Bitstream文件。
在生成 Bitstream 之后,在菜单栏中选择 File > Export > Export hardware 导出硬件,并在弹出的对话框 中,勾选“Include bitstream”。然后在菜单栏选择 File > Launch SDK,启动 SDK 软件。
在 SDK 软件中新建一个 BSP 工程和一个空的应用工程,应用工程名为“breath_led”。然后为应用工程 新建一个源文件“main.c”,我们在新建的 main.c 文件中输入本次实验的代码。代码的主体部分如下所示:
  1. 1  #include "xbreath_led.h"
  2. 2  
  3. 3  int main()
  4. 4  {
  5. 5    XBreath_led led;
  6. 6   
  7. 7    XBreath_led_Initialize(&led, XPAR_BREATH_LED_0_DEVICE_ID);
  8. 8   
  9. 9    while(1)
  10. 10   {
  11. 11       XBreath_led_Set_freq_step(&led,40);
  12. 12       XBreath_led_Set_sw_ctrl(&led,1);
  13. 13       sleep(5);
  14. 14       XBreath_led_Set_sw_ctrl(&led,0);
  15. 15       sleep(2);
  16. 16       XBreath_led_Set_freq_step(&led,200);
  17. 17       XBreath_led_Set_sw_ctrl(&led,1);
  18. 18       sleep(5);
  19. 19   }
  20. 20   return 0;
  21. 21 }
复制代码

第1行引入的“xbreath_led.h”是Vivado HLS工具自动为我们生成的头文件,这个头文件包含了初始化和配置Vivado HLS生成IP核的函数。第7行初始化Vivado HLS生成的呼吸灯IP核。第11行到第13行设置呼吸灯频率步进为40,并使呼吸灯工作5秒。第14行到第15行熄灭呼吸灯2秒。第16行到第18行设置呼吸灯频率步进为200,并使呼吸灯工作5秒。
4.5下载验证
编译工程并生成比特流.bit 文件。将下载器一端连接电脑,另一端与开发板上的 JTAG 下载口连接,连 接电源线,并打开开发板的电源开关。 点击 Vivado 左侧“Flow Navigator”窗口最下面的“Open Hardware Manager”,此时 Vivado 软件识别 到下载器,点击“Hardware”窗口中“Progam Device”下载程序,在弹出的界面中选择“Program”下载程 序。 配置 PL 完成后,接下来我们要下载软件程序。在应用工程 user_led 上右击,选择“Run As”,然后选择 第一项“1 Launch on Hardware (System Debugger)”。程序下载完成后,可以看到核心板上的 LED1(PL LED)每7秒钟 LED 灯的呼吸频率切换一次,在切换频率之前,LED 灯会熄灭2秒钟。如下图所示:
阿莫论坛发帖领航者专用18984.png

图 4.5.1 呼吸灯实验现象

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 08:43

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表