使用IP Integrator创建自定义IP核


先决条件

-完成了Zybo入门指南-安装SDK


教程

这个演示将展示如何构建一个基本的PWM控制器来使用Zynq处理器的处理系统来操纵板上的led。我们将能够从IP图形界面改变PWM窗口大小,然后用C为处理器编写的占空比控制。

1.打开Vivado并创建一个新项目

在Zybo入门指南中打开一个新项目
工具→创建并打包IP

2.创建您的自定义IP项目

2.1)选择创建一个新的AXI4外围设备并点击下一个

2.2)在名称字段中输入“My_PWM_Core”,然后点击下一个

2.3)无需修改AXI接口,点击即可下一个

2.4)选择编辑的知识产权并点击完成

3.设计IP核

3.1) Vivado的新实例将为新的IP核打开。展开顶层文件My_PWM_Core_v1_0.然后双击My_PWM_Core_v1_0_S00_AXI在编辑器中打开它。

4.修改My_PWM_Core_v1_0_S00_AXI

4.1)为了允许用户在顶层改变PWM窗口的最大值,改变如下:

//此处添加参数的用户//用户参数结束//不要修改该行以外的参数


:

//此处添加参数的用户参数整数PWM_COUNTER_MAX = 1024, //用户参数结束//不要修改超过该线的参数
4.2)给PWM信号一个自定义IP核的端口,改变这个:
//此处添加端口的用户//用户端口结束//不要修改超出这一行的端口


:

//此处用户添加端口输出线PWM0,输出线PWM1,输出线PWM2,输出线PWM3, //用户端口端//请勿修改超出该线的端口
4.3)下面的修改创建了一个16位宽的计数器,最大为(2^16)-1,这对于大多数应用来说已经足够了。滚动到文件的底部,并更改如下:
//此处添加用户逻辑//用户逻辑结束


:

//添加用户逻辑reg [15:0] counter = 0;//简单的计数器总是@(posedge S_AXI_ACLK) begin if(counter < PWM_COUNTER_MAX-1) counter <= counter + 1;Else counter <= 0;驱动PWM信号的比较器语句指定PWM0 = slv_reg0 < counter ?1 'b0: 1 'b1;指定PWM1 = slv_reg1 < counter ?1 'b0: 1 'b1;指定PWM2 = slv_reg2 < counter ?1 'b0: 1 'b1;指定PWM3 = slv_reg3 < counter ? 1'b0 : 1'b1; // User logic ends
总的来说,这个模块将把数据从处理器写到从寄存器中。简单计数器将计数到最大值并永远重置。然后,每个比较器语句检查当前计数器的值是否大于存储在从寄存器中的值,如果比较值小于当前计数器,则设置PWM高。

取得的成就:
参数化PWM窗口大小与PWM_COUNTER_MAX
-增加端口,以便更高级别的文件可以得到PWM信号
增加了一个简单的计数器,从0计数到PWM_COUNTER_MAX-1
-增加了四个异步比较器信号,创建PWM信号

5.修改My_PWM_Core_v1_0

5.1)双击My_PWM_Core_v1_0在编辑器中打开它。

下面的修改将PWM信号的端口和参数添加到顶部HDL文件中。这将允许GUI修改、连接和修改IP核。
5.2)变化:
module My_PWM_Core_v1_0 #(//这里添加参数的用户//用户参数结束//不要修改超过这一行的参数


:

module My_PWM_Core_v1_0 #(//此处添加参数的用户参数整数PWM_COUNTER_MAX = 128, //用户参数结束//不要修改超过该线的参数
5.3)然后改变这个:
//此处添加端口的用户//用户端口结束


:

//此处用户添加端口输出线PWM0,输出线PWM1,输出线PWM2,输出线PWM3, //用户端口结束
5.4)和:
/ /实例化的总线接口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)));


:

/ /实例化的总线接口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_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核

现在我们已经编写了核心,是时候打包HDL来创建一个完整的IP包了。

6.1)现在点击包的IP在Flow Navigator中,您应该看到Package IP选项卡。选择兼容性确保Artix7和Zynq都在场如果没有,您可以通过单击加号按钮添加它们。生命周期在这一点上并不重要。

6.2)选择自定义参数然后选择对应的行从自定义参数向导合并更改.这将从隐藏参数文件夹下的顶部文件中添加PWM_COUNTER_MAX参数。

6.3)选择定制GUI.这是我们要改变我们的图形界面。一个问题是,我们的参数没有窗口。右键单击Pwm计数器马克斯并选择编辑参数….勾选旁边的方框可见在定制GUI.检查指定范围内盒子。选择范围的整数类型下拉菜单。因为我们有一个最大值(2^16)-1 = 65535和一个最小值0,这是没有用的,但无论如何。点击好吧

6.4)拖动Pwm计数器马克斯0页把它放到主页上。

现在核心应该是完整的,所以选择审查和包并单击重新包装的IP按钮。

一个弹出窗口会问你是否想要关闭项目,选择是的


7.创建Zynq设计

7.1)在原窗口的项目经理页面,单击创建块设计.这将向项目添加块设计。
7.2)使用 添加IP按钮添加Zynq处理系统

7.3)使用 添加IP按钮再次添加我们的PWM核心

7.4)块自动化运行

7.5)你的设计应该是这样的:

7.6)双击我们PWM核心来定制我们之前创建的参数。设置PWM计数器最大值为1024。并点击好吧

7.7)右键单击每个PWM信号并选择创建端口…

7.8)点击按钮验证设计

7.9)点击项目经理,右键单击“design_1.db”文件,然后创建高密度脂蛋白包装…

7.10)双击design_1_wrapper.v在编辑器中打开它。注意PWM信号的名称。添加“Zybo_master。Xdc "约束文件,可以下载在这里。取消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[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}##IO_L3N_T0_DQS_AD1N_35 set_property PACKAGE_PIN D18 [get_ports {led[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]


:

## io_l23_t3_35 set_property IOSTANDARD LVCMOS33 [get_ports PWM0] set_property IOSTANDARD LVCMOS33 [get_ports PWM0] ## io_l23_t3_35 set_property IOSTANDARD LVCMOS33 [get_ports PWM1]##IO_L3N_T0_DQS_AD1N_35 set_property PACKAGE_PIN D18 [get_ports PWM3] set_property IOSTANDARD LVCMOS33 [get_ports PWM3]
7.11)点击产生的比特流.构建比特文件可能需要一些时间。
7.12)导出硬件的方式为文件→出口→出口硬件……

7.13)勾选复选框包括比特流并点击好吧

7.14)选择文件→启动SDK,点击好吧在弹出的窗口上。

8.在SDK编程

8.1)创建一个新的应用项目

8.2)设置窗口,单击下一个完成

8.3)扩大PWM_AXI_tutorial→src文件夹中。右键单击src文件夹和添加新文件.创建一个名为“main.c”的文件。

8.4)添加行:
#include "xparameters.h" #include "xil_io.h" //#define MY_PWM XPAR_MY_PWM_CORE_0_S00_AXI_BASEADDR //由于Vivado 2015.3和2015.4的一个bug,这个值是不正确的。#define MY_PWM 0x43C00000 //这个值是在Vivado的地址编辑器标签(旁边的图表标签)int main(){int num=0;int我;While (1){if(num == 1024) num = 0;其他num + +;Xil_Out32 (MY_PWM num);Xil_Out32 ((MY_PWM + 4), num);Xil_Out32 ((MY_PWM + 8), num);Xil_Out32 ((MY_PWM + 12), num);(我= 0;< 300000; i++); } }
8.5) FPGA编程,执行Xilinx FPGA工具→程序.要加载SDK应用到ZYBO上,请展开PWM_AXI_tutorial→二进制文件右键单击“PWM_AXI_tutorial”。精灵”并选择运行As→在硬件上启动(GDB)


9.庆祝!

现在ZYBO上的4个led会发出脉冲。靠在椅子上,感觉很有成就感,因为你刚刚创建了自己的定制IP核。