Zynq开发实践(SDK之自定义IP3 - 软件IP联调)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面我们写了verilog、做了verilog的仿真,以及fpga的验证,其实就是为了今天的这一步,即ip的使用。也就是说,可以通过ps可以访问pl,即用ps来访问和控制fpga,这是效率最高的一个方式。很多的功能芯片都是这么来做的,比如说usb camera,整个芯片里面的cpu是很弱的,有的时候就是51或者arm芯片,这种情况下,cpu做不了什么事情,就只能做控制处理。因此,zynq里面也有这样的类似通信总线形式,axi lite总线。
1、先创建一个IP管理工程
这一点有点像c/c++里面的静态库、动态库。默认情况下库代码是单独放在一个地方的,这样它就可以被多个项目所使用。所以打开vivado,选择“Manage IP”,单击下一步,注意在“Manage IP Settings”的时候,part部分选择当前使用的芯片类型,比如020clg400-1,这样后面省去很多的麻烦。并且一直这样单击下去,就可以创建一个ip管理工程。
2、添加ip工程
在ip管理工程里面,接下来需要的就是添加新的ip。我们选择“Tools”-》“Create and package new IP”,单击下一步,注意在提示“Create AXI4 peripheral”的时候,选择axi总线。最后就是,一路单击下去即可。这里只是生成一个ip,后面其他类似的ip也可以这样生成。
3、修改ip代码
在IP Catalog中找到刚才生成的ip,一般就是“myip_v1.0”,右击选择“Edit in IP Packager”。这里,vivado会单独创建一个verilog工程,我们在这个工程修改verilog代码即可。通常会看到两个文件,一个是myip_v1_0.v,这个是top文件。还有一个是myip_v1_0_S00_AXI.v,在前一个文件被实例化了。因为我们的代码比较简单,所以可以直接修改,其中第一个文件myio_v1_0.v中添加led即可,
// Users to add ports hereoutput led,// User ports ends// Do not modify the ports beyond this line
同时塞到myip_v1_0_S00_AXI的实例化对象当中,
.S_AXI_RDATA(s00_axi_rdata),.S_AXI_RRESP(s00_axi_rresp),.S_AXI_RVALID(s00_axi_rvalid),.S_AXI_RREADY(s00_axi_rready),.led(led)
在后一个文件myip_v1_0_S00_AXI.v中,首先把led接过来,
// Users to add ports hereoutput reg led,// User ports ends// Do not modify the ports beyond this line
接着就把逻辑补上,可以放到文件的最后面,
// Add user logic herereg[31:0] counter;always@(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)if(!S_AXI_ARESETN)counter <= 32'd0;else if(!slv_reg1[0])counter <= 32'd0;else beginif(counter == 32'd50000000)counter <= 32'd0;elsecounter <= counter +1;endalways@(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)if(!S_AXI_ARESETN)led <= 1'b1;else if(!slv_reg1[0])led <= 1'b1;else if(counter == 32'd50000000)led <= ~led;// User logic ends
一切都ok之后,需要综合一下,但是不需要布局布线。最后就是设置一下ip的基本信息,找到左侧IP-XACT,选择打开component.xml。依次确定选项,保证每个选项前面都是勾上了,单击一下package ip按钮即可,
4、创建新工程,添加block design
ip准备好了之后,就可以重新创建工程开始验证了。创建工新vivado工程,以及block design的方法和之前是一样的,注意soc也是020clg400-1。注意,因为需要外接自定义的ip,所以不需要删除额外的三条线,即clk、reset和gp0。同时还需要设置下uart和ddr3属性。
5、添加ip源和ip
在准备添加之前写好的ip之前,首先需要设置一下ip源。因为默认ip源,都是xilinx官方提供的ip,而准备添加的ip,则是我们自己的ip,所以需要添加一下ip源。选择“Tools”,然后是“Settings”,单击左侧的“IP”,然后是“Repository”,把刚才的ip源地址填上,单击Apply和ok即可。
只有设置好了ip源之后,才可以在搜索的时候看到自己写的ip,
接下来要做的就是把myip添加上去,自动布线即可。当然myip的led信号,要make extern一下,为后续约束做准备,
6、编译、导出到sdk
因为涉及到新的ip,而且涉及到新的external接口,所以这里要添加一下约束文件,
set_property PACKAGE_PIN P15 [get_ports led_0]
set_property IOSTANDARD LVCMOS33 [get_ports led_0]
接下来就是“Create output products”和“Create wrapper”。结束之后,可以直接单击“Gnerate bitstream file”。中间的时间可能有点长。bitfile生成了之后,可以导出硬件,注意include bitfile。然后就是导出sdk,准备sdk开发。
7、添加hello工程,修改hello代码
打开sdk功成之后,就可以修改hello代码。这里我们需要知道新ip寄存器地址是多少,这一点可以在vivado工程的Address Editor窗口查到,
查到之后就可以编写代码了,比较简单,就是判断开关打开的时候,灯是不是闪烁的。关闭的时候,是不是就不闪烁了。可以通过不同的编译,下载到板子测试,
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_io.h"
#include "myip.h"#define MY_IP_BASEADDR 0x43c00000
#define MY_IP_REG0 0x0
#define MY_IP_REG1 0x4int main()
{init_platform();//MYIP_mWriteReg(MY_IP_BASEADDR,MY_IP_REG1,0x0); // closeMYIP_mWriteReg(MY_IP_BASEADDR,MY_IP_REG1,0x1); // openwhile(1);print("Hello World\n\r");cleanup_platform();return 0;
}
8、编译、调试
因为开发的过程当中涉及到了新ip导入,所以debug之前同样需要先program fpga。然后再去用debug调试,或者启动sdk程序。这里为了简单方便,直接使用了点灯的verilog代码,大家有兴趣的话,可以把之前的呼吸灯程序拿过来,仔细观察一下,其实流程是差不多的。
9、其他
很多zynq的教程都是把重点放在fpga开发、ps开发和linux开发上面,其实这些都不是重点。重点应该是找到设计业务逻辑,找出硬件瓶颈点,实现软硬结合,这才是重点。