目录
1. 1 创建AXI slave IP
1.2 修改AXI slave IP的2个文件
1.3 重新封装IP
1.4 新建BD添加IP(PS core IP+AXI slave IP)
1.5 修改PS core IP
1.5.1 引出DDR端口
1.5.2 引出FIXED_IO端口
1.5.3 DDR配置
1.6 引出myip_v1_0_0的GPIO_LED端口
1.7 更新BD
1.7.1 Generate the Output Products
1.7.2 Create a HDL wrapper
1.8 添加4个PL pin的约束
1.9 生成bitstream
1.10 导出硬件
1.11 打开SDK
1.12 新建应用项目
1.12.1 添加源文件main.c
1.12.2 调试设置
1.13 总结
我们从PL侧开始倒推PS控制PL的流程:
1) PL侧的引脚需要1个AXI设备来控制,因此需要我们创建1个AXI IP,因为我们要通过PS来控制PL,所以这个AXI设备必须是AXI slave设备,与之对应,PS侧应包含1个AXI master接口,即是说我们首先要创建1个AXI slave IP。
2)这个AXI slave设备最终是要连接至PS的AXI master接口,其实是通过AXI Interconnect设备将两者连接在一起,AXI Interconnect设备无需我们添加或实现,只要知道有这么个东西负责联系和管理AXI slave设备和AXI master设备就可以了。
因此关键是如何创建AXI slave IP,以下是步骤,参考了米联ZynQ7010开发板的CH10_AXI_User_GPIO例程,但减少了一些非必要的配置项。
新建Vivado工程,Tools -> Create and Package NEW IP -> Next -> Create a new AXI4 peripheral,单击Next -> 修改IP Name(此处未改,默认为myip)和IP location(这一步最好修改成绝对路径) -> 设置AXI4接口,如下:
图1.1 AXI4 interface设置
上图Number of Registers设置为4,其实只用到了1个。
单击next -> Edit IP,此时会产生2个文件,见下图。
图1.2 Edit IP产生的2个文件
修改AXI slave IP的目的是引出4个PL pin以控制4个LED引脚,并将slv_reg0寄存器与4个pin关联起来,即修改myip_v1_0.v和myip_v1_0_S00_AXI.v这两个文件,需要添加这4个pin的定义。
slv_reg0(slave register 0)的定义和使用出现在myip_v1_0_S00_AXI.v中,所以需在此文件中使用output wire [3:0] GPIO_LED定义4个寄存器,并在文件的最后添加assign GPIO_LED[3:0]=slv_reg0,见下图。
图1.3 myip_v1_0_S00_AXI.v中添加GPIO_LED的定义
图1.4 myip_v1_0_S00_AXI.v中将slv_reg0赋值给GPIO_LED
由图1.4的Hierarchy页面可以看出,myip_v1_0模块将myip_v1_0_S00_AXI模块例化为myip_v1_0_S00_AXI_inst了,所以myip_v1_0模块的定义也要修改,即修改myip_v1_0.v文件,见下图。
图1.5 myip_v1_0.v中添加GPIO_LED的定义
图1.6 myip_v1_0.v中的例化myip_v1_0_S00_AXI_inst中添加GPIO_LED的调用
以上就改完了,因为两个文件有变动,接下来是要重新封装IP。
选择 Tools -> Creat and Pakage New IP,单击Next -> 选择Package your current project,单击Next,路径选择原来IP所在的位置,OverWrite原来的文件 -> Finish,见到下图。
图1.7 重新封装IP后的界面
依次点击上图左侧的Package IP、中间的Review and Package,再点击Package IP,这样1个IP就做好了,可以关闭Edit IP的界面了。
此时注意要新开一个工程,不要在建IP的界面添加BD,执行IP INTEGRATOR -> Create Block Design,添加2个IP,见下面的2个图。
图1.8 添加ZynQ7 Processing System IP
图1.9 添加 myip_v1.0 IP
图1.10 完成添加2个IP后的框图
上图中myip_v1.0 IP的GPIO_LED[3:0]就是我们修改2个IP内容后出现的。
包括:
1. 使用Ctrl+T快捷键引出DDR端口+FIXED_IO端口,你忘了也不要紧,后面会提示你把这两个引出。
2. DDR的配置(仅是指选择DDR内存颗粒型号)。
图1.11 引出DDR端口
这个DDR_0可以改为DDR,也可以不改,此处不改了。
图1.12 引出FIXED_IO端口
这个FIXED_IO_0可以改为FIXED_IO,也可以不改,此处不改了。
双击上图的PS core IP框图,弹出配置界面,设置DDR颗粒型号的界面如下:
图1.13 DDR配置界面
上图已经选择好了DDR颗粒型号,点OK就可以了。
图1.14 引出GPIO_LED端口
上图的GPIO_LED_0[3:0]必须改为GPIO_LED[3:0],不然与我们上面建立的IP里面的GPIO_LED定义就对应不上了。
之后执行Run connection automation,让Vivado自动将上图的IP与PS的AXI接口连接起来,见下图。
图1.15 自动连接后的界面
上图的AXI Interconnect就是Vivado自动添加的,无需我们手动添加。
因为BD的内容有改动,所以接下来要更新BD了。
单击BD文件右键 -> Generate the Output Products -> Global -> Generate。为便于理解Generate the Output Products的作用,在执行前和后分别截图如下。
图1.16 执行Generate the Output Products之前的Hierarchy界面
图1.17 执行Generate the Output Products之后的Hierarchy界面
可以看出,Generate the Output Products就是vivado用IP的形式(.v)实现bd框图。
单击BD文件右键 -> Create a HDL wrapper(生成HDL顶层文件*_wrapper.v),并选择Let vivado manager wrapper and auto-update(自动更新)。
为便于理解Create a HDL wrapper的作用,在执行前和后分别截图如下。
图1.18 执行Create a HDL wrapper之前的Hierarchy界面
图1.19 执行Create a HDL wrapper之后的Hierarchy界面
可以看出,Create a HDL wrapper就是产生1个*_wrapper.v的顶层文件。
选中PROJECT MANAGER -> Add Sources -> Add or create Constraints Sources
图1.20 4个PL pin的约束
上图约束了4个pin的电平和引脚。
点击Generate bitstream,烧壶水,等着吧~,执行完毕,提示是否Open Implemented Design,这个打不打开都可以。
File->Export->Export Hardware,勾选 Include bitstream ,直接单击 OK。此步骤实际是产生system_wrapper.hdf文件(PL逻辑工程师交给PS驱动工程师的最重要的文件)。
File->Launch SDK 加载到 SDK。
图1.21 SDK界面
SDK界面里面只有一些驱动,没有工程,所以要新建1个应用项目。
File->New->Application Project -> 设置项目名 -> Next -> Empty Application -> Finish。
这个main.c不是我写的,直接把米联的main.c拷贝粘贴过来了,见下图。
图1.22 添加main.c文件
实际上在本地复制main.c,直接在src位置粘贴就可以添加了。
上图有个小红叉叉,报错的原因是XPAR_GPIO_LITE_ML_0_BASEADDR未定义。
图 1.23 main.c文件内容
这个将米联例程中ps7_cortexa9_0\include带的所有头文件拷贝到1_bsp\ps7_cortexa9_0\include下就可以了。
右击 1文件夹 -> Debug As -> Debug Configurations,双击Xilinx C/C++ application(System Debugger),勾选Reset Entire System和Program FPGA -> Debug.
图1.24 Debug跑起来后的界面
上图中的GPIO_LITE_ML_REG0就是slv_reg0,slv_reg0又可以控制4个PL引脚的电平。
你猜怎么着,4个灯就这么循环点亮了...
通过以上的步骤实现在SDK中通过代码来控制PL的引脚电平的目的,以上步骤属于基本配置的范畴,重要的是如何在完成这些基本配置后实现自己的目的,这时的工作量集中在PS上了。