ZedBoard+Vivado(三)——自定义AXI外设IP核实现流水灯
硬件:Zedboard
软件:Vivado2018.2 + Win10
1 设计
功能:流水灯
语言:Verilog + C
流程:创建工程->创建AXI外设IP核->IP Integrator->综合、实现、生成Bitstream->SDK
功能图如下,图中的GPIO IP使用自定义的AXI外设,而不使用AXI_GPIO
2 流程
2.1 创建工程
参考ZedBoard+Vivado(一)
2.2 创建AXI外设IP核
点击Tools->Create and Package New IP
点击Next
选择Create a new AXI4 peripheral
默认或者手动输入相关描述
使用AXI-Lite,Slave模式
选Add IP to the repository,以便我们后续添加该IP核,点Finish
2.2 IP Integrator
IP INTEGRATOR->Create Block Design,在add IP中输入myip和ZYNQ7 Processing System,并其加入到Diagram中
对ZYNQ7 Processing System进行Run Block Automation(在ZedBoard+Vivado(二)中介绍过)
右键自定义的IP核myip_0,选择Edit in IP Packager
为该次编辑指定name和存储location,直接OK就行
现在在Source->Design Sources下能看到myip_v1_0和myip_v1_0_S00_AXI_inst:myip_v1_0_S00_AXI,其中myip_v1_0是该IP核的顶层模块,myip_v1_0_S00_AXI是实际内在逻辑
首先修改顶层模块,双击myip_v1_0,在红框位置添加以下代码(注意最后的逗号)output wire [7:0] LED,
继续在红框位置添加以下代码(注意最后的逗号)
.LED(LED),
接下来修改内部逻辑,双击myip_v1_0_S00_AXI_inst:myip_v1_0_S00_AXI,同上,添加
output wire [7:0] LED,
继续在红框位置添加
reg [7:0] led;
always @(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN == 1'b0)
begin
led <= 8'b0;
end
else
begin
led <= S_AXI_WDATA[7:0];
end
end
assign LED = led;
修改完成后保存,然后点击Package IP
除最后的Review and Package外,在没有打勾的位置,点右边的Merge changes from XXX
最后点Review and Package->Re-Package IP
Yes即可
现在发现在Diagram里myip_0没有我们手动添加的LED端口,把它删了,重新添加
新添加的myip_0,就有输出端口LED[7:0]了
接下来添加外接端口,右键LED[7:0]->Make External(注意不要右键整个模块选择Make External,那样会为所有端口添加外接端口)
这样就出现了与LED[7:0]相连的端口LED_0[7:0],为方便写constraint文件,我们手动将名字由LED_0改为LED
不必担心它与已有的LED重名,然后点击Run Connection Automation
OK就行
这样就自动完成了连线
现在还没有为创建的外部端口LED[7:0] (原本叫LED_0[7:0])指定constraint,点Add Sources->Add or create constraints。在ZedBoard+Vivado(一)中有介绍,不赘述
在constraint文件中添加如下代码
set_property PACKAGE_PIN T22 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]
#NET LD0 LOC = T22 | IOSTANDARD=LVCMOS33; # "LD0"
set_property PACKAGE_PIN T21 [get_ports {LED[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[1]}]
#NET LD1 LOC = T21 | IOSTANDARD=LVCMOS33; # "LD1"
set_property PACKAGE_PIN U22 [get_ports {LED[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[2]}]
#NET LD2 LOC = U22 | IOSTANDARD=LVCMOS33; # "LD2"
set_property PACKAGE_PIN U21 [get_ports {LED[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[3]}]
#NET LD3 LOC = U21 | IOSTANDARD=LVCMOS33; # "LD3"
set_property PACKAGE_PIN V22 [get_ports {LED[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[4]}]
#NET LD4 LOC = V22 | IOSTANDARD=LVCMOS33; # "LD4"
set_property IOSTANDARD LVCMOS33 [get_ports {LED[5]}]
set_property PACKAGE_PIN W22 [get_ports {LED[5]}]
#NET LD5 LOC = W22 | IOSTANDARD=LVCMOS33; # "LD5"
set_property PACKAGE_PIN U19 [get_ports {LED[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[6]}]
#NET LD6 LOC = U19 | IOSTANDARD=LVCMOS33; # "LD6"
set_property IOSTANDARD LVCMOS33 [get_ports {LED[7]}]
set_property PACKAGE_PIN U14 [get_ports {LED[7]}]
#NET LD7 LOC = U14 | IOSTANDARD=LVCMOS33; # "LD7"
最后,创建顶层文件Create HDL Wrapper
至此,IP Integrator里需要完成的操作就全部结束了。顺便一提,如果我们下次还想用这个创建的AXI外设IP,应在Settings->Project Settings->IP->Repository->IP Repositories里添加IP核的路径
2.3 综合、实现、生成Bitstream
直接点Generate Bitstream
2.4 SDK
操作与ZedBoard+Vivado(二)相同,直接贴代码
#include <stdio.h>
#include "xparameters.h"
#include "sleep.h"
#include "xil_io.h"
int main()
{
/*
\ Loop forever run the LED
*/
while(1)
{
for(i=0;i<8;i++)
{
Xil_Out32(XPAR_MYIP_0_S00_AXI_BASEADDR, 1<<i);
sleep(1);
}
}
return 0;
}
注意先烧写FPGA再运行arm程序,详情见ZedBoard+Vivado(二),运行成功后便可看到流水灯现象。