1. 软件平台
vivado2019.1
2. 硬件平台
PYNQ_Z2
3. 具体实现流程
首先先建立一个vivado工程如下(参考https://blog.csdn.net/qq_42263796/article/details/101828046)
点击Tools,选择create and pakage new IP,再点击Next
按下图方式选择,点击Next,其他选项自行百度。
这里可选择修改名字,这里命名为myip_test,点击Next
这里按下图选择即可,Next
选择Edit IP , Finish
可以看到如下界面。
在sources一栏目,可以看到顶层文件和底层模块。打开下列所选文件。
打开后。。。。
我们需要做功能是自定义一个led的IP核,需要添加led输出端口
// Users to add ports here
// User ports ends // Do not modify the ports beyond this line
添加后结果如下
// Users to add ports here output wire [3:0]led, // User ports ends // Do not modify the ports beyond this line拉到400多行左右找到下面的语句
添加如下代码
点击保存(有错误会提示)
打开top level
在17到20行左右添加输出端口,如下
在50行左右添加如下代码
点击保存,有错误会提示。
(在这里添加约束文件,我尝试了几次,没有成功,编译不通过)
然后点击source->design sources->IP-XACT,打开component.xml
点击file group,点击merge change from file groups Wizard
同样,使得左侧都打勾,
点击Review and pakage
如果不需要设置,点击Re-pakage IP
点击Yes,IP核就封装完成了。
点击 create block design
然后添加IP核,如下。
点击run block automation,再点击OK,然后手动连接CLK,结果如下。
添加刚刚生成的IP核。如果不是在这个工程下建立的,需要自行添加IP核的路径。
方式:window->IP Catalog ->右击打开的界面的空白处,选择add repository->选择IP核的路劲即可。
在这里不做详细介绍
同样,run connection automation,点击OK
然后右击添加的IP核的led[3:0]的输出端口,
点击 make External
结果如下,
单击该端口,在左边,将名字改为,led
特别提示:如果不将端口名字修改,会造成约束失败(管脚的配置)。
点击验证(validate design),结果如下,
打开source栏目,右击test_ip...文件,选择,create HDL wrapper
然后点击,constraints
右击constrs_1
选择,Add sources
选择 add 偶然create constraints
点击Next
点击create file,输入名字,点击OK
然后点击finish
结果如下,在约束文件输入以下内容
#LEDs set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { led[0] }];#IO_L6N_T0_VREF_34 Sch=led[0] set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { led[1] }];#IO_L6P_T0_34 Sch=led[1] set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led[2] }];#IO_L21N_T3_DQS_AD14N_35 Sch=led[2] set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }];#IO_L23P_T3_35 Sch=led[3]点击保存
然后,在Flow navigator 栏目
点击generate Bistream,选择Yes,再点击OK,等待完成即可。
接下来主要是SDK部分(参考https://blog.csdn.net/qq_42263796/article/details/101828046)
代码如下
#include <stdio.h> #include "platform.h" #include "xil_printf.h" /* Include Files */ #include "xparameters.h" #include "xil_io.h" #include "xstatus.h" /* Definitions */ #define led_delay 10000000 /* Software delay length */ #define led_channel 1 /* GPIO port for LEDs */ #define printf xil_printf /* smaller, optimised printf */ unsigned int mled = 0x01; /* first led*/ #define my_IP_led 0x43c00000 /* GPIO Device driver instance */ void LEDOutputExample(void) { volatile int delay; /* Loop forever blinking the LED. */ while (1) { /* Write output to the LEDs. */ Xil_Out32(my_IP_led,mled); mled = mled<<1; if(mled>0x8) mled = 1; /* Wait a small amount of time so that the LED blinking is visible. */ for (delay = 0; delay < led_delay; delay++); } } int main() { init_platform(); print("Hello World\n\r"); cleanup_platform(); /* Execute the LED output. */ LEDOutputExample(); return 0; }其中my_IP_led的地址可以查看vivado,Address Editor
运行结果如图所示: