Creating a Custom IP core using the IP Integrator
Important!
This guide is out of date. The flow as described may be significantly different in recent versions of Vivado, especially those since Vitis was introduced in 2019.2.
Prerequisites
- Completed the ZyboGetting Started Guide- Have SDK installed
教程
This demo will show how to build a basic PWM controller to manipulate on board LEDs using the processing system of the Zynq processor. We will be able to change the PWM window size from the IP graphic interface and then control the duty cycle in C written for the processor.
1. Open Vivado and create a new project
打开一个新项目,如《 Zybo入门指南》中所示
去Tools→Create and package IP
2. Create your custom IP project
2.1) Select创建一个新的AXI4外围and clickNext
2.2) Input “My_PWM_Core” in the name field and clickNext
2.3) No changes to the AXI interface are required, so clickNext
2.4)选择编辑IPand clickFinish
3.设计IP核心
3.1) A new instance of Vivado will open up for the new IP core. Expand the top level fileMy_PWM_Core_v1_0。然后双击My_PWM_Core_v1_0_S00_AXI在编辑器中打开它。
4.修改my_pwm_core_v1_0_s00_axi
4.1)To allow for the user to change the maximum value of the PWM window in the top level, change this:
/ /用户add parameters here // User parameters ends // Do not modify the parameters beyond this line
To this://用户要添加参数此处参数整数pwm_counter_max = 1024,//用户参数end //请勿修改此行之外的参数
4.2) To give the PWM signals a port out of the custom IP core, change this:
/ /用户add ports here // User ports ends // Do not modify the ports beyond this line
To this:/ /用户add ports here output wire PWM0, output wire PWM1, output wire PWM2, output wire PWM3, // User ports ends // Do not modify the ports beyond this line
4.3) The following modification creates a counter that is 16-bits wide with a maximum of (2^16)-1, which will be more than enough for most applications. Scroll to the bottom of the file and change this:
// Add user logic here // User logic ends
To this://在此处添加用户逻辑[15:0] Counter = 0;//简单的计数始终 @(posEdge s_axi_aclk)if(counter
总体而言,该模块将将数据写入处理器的从寄存器中。简单的计数器将计算到最大值并永远重置。然后,每个比较器语句都会检查当前计数器值是否大于从属寄存器中存储的值,如果比较值小于当前计数器,则将PWM设置为高。
我们完成了什么:
- 用pwm_counter_max参数化PWM窗口大小
- 添加的端口,因此更高级别的文件可以获取PWM信号
- 添加了一个从零到pwm_counter_max-1的简单计数器
- 添加了四个创建PWM信号的异步比较器信号
5.修改my_pwm_core_v1_0
5.1) Double-click onMy_PWM_Core_v1_0在编辑器中打开它。
以下修改将PWM信号的端口和参数添加到顶部HDL文件。这将允许GUIto change, connect, and modify the IP core.
5.2) Change this:
module My_PWM_Core_v1_0 # ( // Users to add parameters here // User parameters ends // Do not modify the parameters beyond this line
To this:module My_PWM_Core_v1_0 # ( // Users to add parameters here parameter integer PWM_COUNTER_MAX = 128, // User parameters ends // Do not modify the parameters beyond this line
5.3)然后更改以下方式:
/ /用户add ports here // User ports ends
To this:/ /用户add ports here output wire PWM0, output wire PWM1, output wire PWM2, output wire PWM3, // User ports ends
5.4) And this:
// Instantiation of Axi Bus Interface S00_AXI My_PWM_Core_v1_0_S00_AXI # ( .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH), .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH) ) My_PWM_Core_v1_0_S00_AXI_inst ( .S_AXI_ACLK(s00_axi_aclk), .S_AXI_ARESETN(s00_axi_aresetn), .S_AXI_AWADDR(s00_axi_awaddr), .S_AXI_AWPROT(s00_axi_awprot), .S_AXI_AWVALID(s00_axi_awvalid), .S_AXI_AWREADY(s00_axi_awready), .S_AXI_WDATA(s00_axi_wdata), .S_AXI_WSTRB(s00_axi_wstrb), .S_AXI_WVALID(s00_axi_wvalid), .S_AXI_WREADY(s00_axi_wready), .S_AXI_BRESP(s00_axi_bresp), .S_AXI_BVALID(s00_axi_bvalid), .S_AXI_BREADY(s00_axi_bready), .S_AXI_ARADDR(s00_axi_araddr), .S_AXI_ARPROT(s00_axi_arprot), .S_AXI_ARVALID(s00_axi_arvalid), .S_AXI_ARREADY(s00_axi_arready), .S_AXI_RDATA(s00_axi_rdata), .S_AXI_RRESP(s00_axi_rresp), .S_AXI_RVALID(s00_axi_rvalid), .S_AXI_RREADY(s00_axi_rready));
To this:/ /实例化的总线接口S00_AXI My_PWM_Core_v1_0_S00_AXI # ( .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH), .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH), .PWM_COUNTER_MAX(PWM_COUNTER_MAX) ) My_PWM_Core_v1_0_S00_AXI_inst ( .PWM0(PWM0), .PWM1(PWM1), .PWM2(PWM2), .PWM3(PWM3), .S_AXI_ACLK(s00_axi_aclk), .S_AXI_ARESETN(s00_axi_aresetn), .S_AXI_AWADDR(s00_axi_awaddr), .S_AXI_AWPROT(s00_axi_awprot), .S_AXI_AWVALID(s00_axi_awvalid), .S_AXI_AWREADY(s00_axi_awready), .S_AXI_WDATA(s00_axi_wdata), .S_AXI_WSTRB(s00_axi_wstrb), .S_AXI_WVALID(s00_axi_wvalid), .S_AXI_WREADY(s00_axi_wready), .S_AXI_BRESP(s00_axi_bresp), .S_AXI_BVALID(s00_axi_bvalid), .S_AXI_BREADY(s00_axi_bready), .S_AXI_ARADDR(s00_axi_araddr), .S_AXI_ARPROT(s00_axi_arprot), .S_AXI_ARVALID(s00_axi_arvalid), .S_AXI_ARREADY(s00_axi_arready), .S_AXI_RDATA(s00_axi_rdata), .S_AXI_RRESP(s00_axi_rresp), .S_AXI_RVALID(s00_axi_rvalid), .S_AXI_RREADY(s00_axi_rready) );
6.包装IP核心
Now that we have written the core, it is time to package up the HDL to create a complete IP package.
6.1) Now click onPackage IPin the Flow Navigator and you should see the Package IP tab. Select兼容性and make sure “Artix7” and “Zynq” are present. If those are not there, you can add them by clicking the plus button. The Life Cycle does not matter at this point.
6.2) Select定制Parameters并选择the line for从自定义参数向导合并更改。This will add the PWM_COUNTER_MAX parameter from the top file under the hidden parameters folder.
6.3)选择定制GUI。This is were we get to change our graphical interface. One problem, there is not a window for our parameter. Right-clickPWM计数器最大并选择编辑参数…。检查box next to可见自定义GUI。检查Specify Range盒子。选择Range of Integersfrom theType下拉式菜单。由于我们的最大值为(2^16)-1 = 65535,最小值为0,因此这不是有用的,而是任何有用的。点击Ok。
6.4)拖动PWM计数器最大进入Page 0在主页上获取它。
6.5)现在核心应该完成,因此请选择Review and Packageand click theRe-package IPbutton.
6.6)弹出窗口会询问您是否要关闭项目,选择是的。
7. Create Zynq design
7.1) In the project manager page of the original window, clickCreate Block Design。这为项目添加了一个块设计。
7.2) Use the Add IP按钮添加Zynq Processing System。
7.3)使用 Add IPbutton again to add ourPWM core。
7.4)运行块自动化。
7.5)您的设计应该看起来像这样:
7.6) Double-click ourPWM coreto customize the parameter that we made earlier. Set the PWM Counter Max to 1024. and clickOK。
7.7) Right-click each of the PWM signals and selectCreate Port…
7.8)单击按钮验证设计。
7.9)单击Project Manager,右键单击“ design_1.db”文件,然后创建HDL包装器…
7.10)双击design_1_wrapper.v在编辑器中打开它。记下PWM信号的名称。添加可以下载的“ zybo_master.xdc”约束文件here.删除XDC文件中LED的代码行,然后更改以下内容:
##IO_L23P_T3_35 set_property PACKAGE_PIN M14 [get_ports {led[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}] ##IO_L23N_T3_35 set_property PACKAGE_PIN M15 [get_ports {led[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}] ##IO_0_35 set_property PACKAGE_PIN G14 [get_ports {led[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}] ##IO_L3N_T0_DQS_AD1N_35 set_property PACKAGE_PIN D18 [get_ports {led[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
To this:##IO_L23P_T3_35 set_property PACKAGE_PIN M14 [get_ports PWM0] set_property IOSTANDARD LVCMOS33 [get_ports PWM0] ##IO_L23N_T3_35 set_property PACKAGE_PIN M15 [get_ports PWM1] set_property IOSTANDARD LVCMOS33 [get_ports PWM1] ##IO_0_35 set_property PACKAGE_PIN G14 [get_ports PWM2] set_property IOSTANDARD LVCMOS33 [get_ports PWM2] ##IO_L3N_T0_DQS_AD1N_35 set_property PACKAGE_PIN D18 [get_ports PWM3] set_property IOSTANDARD LVCMOS33 [get_ports PWM3]
7.11) ClickGenerate Bitstream。Building the bit file can take some time.
7.12)通过去导出硬件文件→导出→导出硬件…
7.13) Check the box包括Bitstreamand clickOk
7.14) SelectFile→Launch SDK,,,,and hitOk在弹出的窗口上。
8. Programming in SDK
8.1) Create a new application project
8.2)设置窗口,单击NextandFinish。
8.3)扩展PWM_AXI_tutorial→srcfolder. Right-click thesrcfolder and添加新文件。创建一个名为“ main.c”的文件。
8.4) Add the lines:
#include "xparameters.h" #include "xil_io.h" //#define MY_PWM XPAR_MY_PWM_CORE_0_S00_AXI_BASEADDR //Because of a bug in Vivado 2015.3 and 2015.4, this value is not correct. #define MY_PWM 0x43C00000 //This value is found in the Address editor tab in Vivado (next to Diagram tab) int main(){ int num=0; int i; while(1){ if(num == 1024) num = 0; else num++; Xil_Out32(MY_PWM, num); Xil_Out32((MY_PWM+4), num); Xil_Out32((MY_PWM+8), num); Xil_Out32((MY_PWM+12), num); for(i=0;i<300000; i++); } }
8.5) To program the FPGA, Go toXilinx Tools→Program FPGA。要将SDK应用程序加载到Zybo上,请展开PWM_AXI_tutorial→binariesand right-click on “PWM_AXI_tutorial.elf” and selectRun As→Launch on Hardware (GDB)。
9.庆祝!
Now the 4 LEDs on the ZYBO will be pulsing. Lean back in your chair and feel accomplished because you just created your own custom IP core.