【ZYNQ Ultrascale+ MPSOC FPGA教程】第三十章 自定义IP实验

原创声明:

本原创教程由芯驿电子科技(上海)有限公司(ALINX)创做,版权归本公司全部,如需转载,需受权并注明出处。ide

适用于板卡型号:

AXU2CGA/AXU2CGB/AXU3EG/AXU4EV-E/AXU4EV-P/AXU5EV-E/AXU5EV-P /AXU9EG/AXU15EG测试

 

实验Vivado工程目录为“custom_pwm_ip /vivado”。this

实验vitis工程目录为“custom_pwm_ip /vitis”。spa

Xilinx官方为你们提供了不少IP核,在Vivado的IP Catalog中能够查看这些IP核,用户在构建本身的系统中,不可能只使用Xilinx官方的免费IP核,不少时候须要建立属于本身的用户IP核,建立本身的IP核有不少好处,例如系统设计定制化;设计复用,能够在在IP核中加入license, 有偿提供给别人使用;简化系统设计和缩短设计时间。用ZYNQ系统设计IP核,最经常使用的就是使用AXI总线将PS同PL部分的IP核链接起来。本实验将为你们介绍如何在Vivado中构建AXI总线类型的IP核,此IP核用来产生一个PWM,用这个控制开发板上的LED,作一个呼吸灯的效果。debug

FPGA工程师工做内容

如下为FPGA工程师负责内容。设计

1. PWM介绍

咱们常常使用PWM来控制LED,蜂鸣器等,经过调节脉冲的占空比来调节LED的亮度。3d

在其余开发板中咱们使用过的一个pwm模块以下:调试

////////////////////////////////////////////////////////////////////////////////// // // ////////////////////////////////////////////////////////////////////////////////// // // // Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd // // All rights reserved // // // // This source file may be used and distributed without restriction provided // // that this copyright statement is not removed from the file and that any // // derivative work contains the original copyright notice and the associated // // disclaimer. // // // //////////////////////////////////////////////////////////////////////////////////  //================================================================================ // Description: pwm model // pwm out period = frequency(pwm_out) * (2 ** N) / frequency(clk); // //================================================================================ // Revision History: // Date By Revision Change Description //-------------------------------------------------------------------------------- // 2017/5/3 meisq 1.0 Original //********************************************************************************/ `timescale1ns/1ps module ax_pwm #( parameter N =32//pwm bit width ) ( input clk, input rst, input[N -1:0]period, input[N -1:0]duty, output pwm_out ); reg[N -1:0] period_r; reg[N -1:0] duty_r; reg[N -1:0] period_cnt; reg pwm_r; assign pwm_out = pwm_r; always@(posedge clk orposedge rst) begin if(rst==1) begin period_r <={ N {1'b0}}; duty_r <={ N {1'b0}}; end else begin period_r <= period; duty_r <= duty; end end always@(posedge clk orposedge rst) begin if(rst==1) period_cnt <={ N {1'b0}}; else period_cnt <= period_cnt + period_r; end always@(posedge clk orposedge rst) begin if(rst==1) begin pwm_r <=1'b0; end else begin if(period_cnt >= duty_r) pwm_r <=1'b1; else pwm_r <=1'b0; end end endmodule 

能够看到这个PWM模块须要2个参数“period”、“duty”来控制频率和占空比,”period”为步进值,也就是计数器每一个周期要加的值。Duty为占空比的值。咱们须要设计一些寄存器来控制这些参数,这里须要使用AXI总线,PS经过AXI总线来读写寄存器。rest

2. Vivado工程创建

用”ps_hello”工程另存为一个名为“custom_pwm_ip”工程code

2.1 建立自定义IP

1)点击菜单“Tools->Create and Package IP...”

2)选择“Next”

3)选择建立一个新的AXI4设备

4)名称填写“ax_pwm”,描述填写“alinx pwm”,而后选择一个合适的位置用来放IP

5)下面参数能够指定接口类型、寄存器数量等,这里不须要修改,使用AXI Lite Slave接口,4个寄存器。

6)点击“Finish”完成IP的建立

7)在“IP Catalog”中能够看到刚才建立的IP

8)这个时候的IP只有简单的寄存器读写功能,咱们须要修改IP,选择IP,右键“Edit in IP Packager”

9)这是弹出一个对话框,能够填写工程名称和路径,这里默认,点击“OK”

10)Vivado打开了一个新的工程

11)添加PWM功能的核心代码

12)添加代码时选择复制代码到IP目录

13)修改“ax_pwm_v1_0.v”,添加一个pwm输出端口

14)修改“ax_pwm_v1_0.v”,在例化“ax_pwm_V1_0_S00_AXI”,中添加pwm端口的例化

15)修改“ax_pwm_v1_0_s00_AXI.v”文件,添加pwm端口,这个文件是实现AXI4 Lite Slave的核心代码

16)修改“ax_pwm_v1_0_s00_AXI.v”文件,例化pwm核心功能代码,将寄存器slv_reg0和slv_reg1用于pwm模块的参数控制。

17)双击“component.xml”文件

18)在“File Groups”选项中点击“Merge changers from File Groups Wizard”

19)在“Customization Parameters”选项中点击“Merge changes form Customization Parameters Wizard”

20)点击“Re-Package IP”完成IP的修改

2.2 添加自定义IP到工程

1)搜索“pwm”,添加“ax_pwm_v1.0”

2)点击“Run Connection Automation”

3)导出pwm端口

4)保存设计,并Generate Output Products

5)添加xdc文件分配管脚,把pwm_0输出端口分配给LED1,作一个呼吸灯,编译生成bit文件,导出硬件

软件工程师工做内容

如下为软件工程师负责内容。

3. Vitis软件编写调试

1)启动Vitis,新建APP,模板选择“Hello World”

2)在bsp里找到“xparameters.h”文件,这个很是重要的文件,里面找到了自定IP的寄存器基地址,能够找到自定义IP的基地址。

3)有个寄存器读写宏和自定义IP的基地址,咱们开始编写代码,测试自定义IP,咱们先经过写寄存器AX_PWM_S00_AXI_SLV_REG0_OFFSET,控制PWM输出频率,而后经过写寄存器AX_PWM_S00_AXI_SLV_REG1_OFFSET控制PWM输出的占空比。

#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include "ax_pwm.h" #include "xil_io.h" #include "xparameters.h" #include "sleep.h" unsignedint duty; int main() { init_platform(); print("Hello World\n\r"); //pwm out period = frequency(pwm_out) * (2^N) / frequency(clk);  AX_PWM_mWriteReg(XPAR_AX_PWM_0_S00_AXI_BASEADDR, AX_PWM_S00_AXI_SLV_REG0_OFFSET,17179);//200hz  //duty = (2^N) * (1 - (duty cycle)) - 1  while(1){ for(duty =0x8fffffff; duty <0xffffffff; duty = duty +100000){ AX_PWM_mWriteReg(XPAR_AX_PWM_0_S00_AXI_BASEADDR, AX_PWM_S00_AXI_SLV_REG1_OFFSET, duty); usleep(100); } } cleanup_platform(); return0; } 

4)经过运行代码,咱们能够看到PLLED1呈现出一个呼吸灯的效果。

5)经过debug,咱们来查看一下寄存器

6)进入debug状态,按“F6”能够单步运行。

7)经过菜单能够查看“Memory”窗口

8)添加一个监视地址“0x80000000”

9)单步运行,观察变化

4. 实验总结

经过本实验咱们掌握了更多的Vitis调试技巧,掌握了ARM + FPGA开发的核心内容,就是ARM和FPGA数据交互。

相关文章
相关标签/搜索