在Vivado中创建计数器IP核

简介
在 Vivado 软件中,我们可以很方便的通过创建和封装 IP 向导的方式来自定义 IP 核。
自定义 IP 核可以定制化系统设计,以达到设计重用的目的,可以很大程度上简化系统设计和缩短产品上市的时间。
本实验中可以创建一个带有 AXI4 接口的 IP 核,用于 PS 和 PL 的数据通信。本次实验选择常用的方式,即创建一个带有 AXI 接口的 IP 核,该 IP 核通过 AXI 协议实现 PS 和 PL 的数据通信。AXI 协议是一种高性能、高带宽、低延迟的片内总线。

实验任务
本章的实验任务是通过自定义一个 COUNT IP 核,使其间隔1s计数1次,并切CPU可以实时读取计数结果。

硬件设计
step1:创建一个新的 IP 核

1-1 打开 Vivado,进入 Vivado 界面后,点击“Tasks”栏中的“Manage IP”。在弹出的选项中选择“New
IP Location…”。如下图所示:
在Vivado中创建计数器IP核_第1张图片

1-2 在弹出的界面中选择“Next”,然后设置 Manage IP 核的属性,在“IP Location:”一栏指定工程的
路径,路径为:F:/ZYNQ/ Embedded_System/custom_ip,其它保持默认即可。点击“Finish”完成 Manage IP工程的创建,如图 所示。注意,Part 一栏中设置开发板的型号,在后面的工程中会重新指定,这里直接保持默认。
在Vivado中创建计数器IP核_第2张图片在Vivado中创建计数器IP核_第3张图片
此时弹出确认工程路径的界面,点击“OK”按钮完成工程的创建。如下图所示:在Vivado中创建计数器IP核_第4张图片

1-3 工程创建完成后,运行创建和封装 IP 向导。点击菜单栏的“Tools”,选择“Create and Package New
IP”,在弹出的界面中,点击“NEXT”。如图 所示:
在Vivado中创建计数器IP核_第5张图片
在Vivado中创建计数器IP核_第6张图片

1-4 接下来选择封装 IP 或者创建一个带 AXI4 接口的 IP 核,我们这里选择创建一个带 AXI 接口的 IP
核,选中“Creat a new AXI4 peripheral”,并点击“NEXT”按钮。如下图所示:
在Vivado中创建计数器IP核_第7张图片

1-5 接下来分别设置 IP 核名称(Name)、版本号(Version)、显示名(Display name)、描述(Description)
和路径(IP location)。在 Name 一栏设置 IP 核的名称,本次实验的功能是控制 PL LED 呈现呼吸灯的效果,
因此这里在 Name 一栏 ,将 名称 改为 “ count_ip ”, 此时 Display name 一 栏会 自动 更改 为
“count_ip_v1.0”。其它的设置直接保持默认即可,点击“NEXT”按钮,如下图所示:
在Vivado中创建计数器IP核_第8张图片

1-6 接下来对 AXI 接口进行设置。
在Vivado中创建计数器IP核_第9张图片
Name(名称):这里修改成 S00_AXI。
Interface Tpye(接口类型):共三种接口类型可选,分别是 Lite、Full 和 Stream。
①AXI4-Lite 接口是简化版的 AXI4 接口,用于较少数据量的存储映射通信;
②AXI4-Full 接口是高性能存储映射接口,用于较多数据量的存储映射通信;
③AXI4-Stream 用于高速数据流传输,非存储映射接口。本次实验只需少量数据的通信,因此接口类型选择默认的 Lite 接口。
Interface Mode(接口模式):接口模式有 Slave(从机)和 Master(主机)两种模式可选,AXI 协议是主机和从机通过“握手”的 方式 建立连接,这里选择默认的 Slave 接口模式。
Data Width(数据宽度):数据位宽保持默认,即 32 位位宽
Memory Size(存储器大小): 在 AXI4-Lite 接口模式下,该选项不可设置。
Number of Registers(寄存器数量):用于配置 PL LED 呼吸灯寄存器的数量,这里保持默认。
点击“Next”按钮。

1-7 最后弹出封装接口的总结描述和下一步操作选项的界面。这里保持默认,即将 IP 添加至 IP 库中,
点击“Finish”按钮完成 IP 核的创建和封装。如下图所示:
在Vivado中创建计数器IP核_第10张图片
在 IP Catalog 界面中可以看到刚刚添加的 IP 核,位于 User Repository 一栏中的 AXI Peripheral 下,名称为“count_ip_v1.0”,如图 所示:
在Vivado中创建计数器IP核_第11张图片

1-8 创建好 IP 核后,我们接下来对 count_ip_v1.0 IP 核进行编辑。右击 count_ip_v1.0 IP 核,选择“Edit in IP Packager”,在弹出的界面中点击“OK”,如图所示:
在Vivado中创建计数器IP核_第12张图片

在Vivado中创建计数器IP核_第13张图片

此时会打开一个新的工程,如图 所示:
在Vivado中创建计数器IP核_第14张图片
1-9 此时工程中缺失 count.v 文件,count.v 文件用于实现计数的功能。
右击“Design Sources”,选择“Add Sources…”,在弹出的界面中选择“Add or Create design source”,点击“NEXT”,如图 所示:
在Vivado中创建计数器IP核_第15张图片
点 击 “ Create File ” 创 建 一 个 新 的 文 件 , 在 弹 出 的 界 面 输 入 名 称 count ,路径
为…/ip_repo/count_ip_1.0/hdl,点击“OK”按钮,如图所示:
在Vivado中创建计数器IP核_第16张图片
在Vivado中创建计数器IP核_第17张图片
点击“Finish”按钮完成创建,如下图所示:
在Vivado中创建计数器IP核_第18张图片
在弹出的模块定义界面中点击“OK”按钮,接下来在弹出的确认按钮中点击“YES”。
在Vivado中创建计数器IP核_第19张图片
双击新创建的文件,进入编辑:
在Vivado中创建计数器IP核_第20张图片
在新创建的文件count.v中敲入以下代码:

module counter(
    input  wire        sys_clk , 
    input  wire        sys_rst_n ,
    
    output reg [10:0]  cnt         //和系统中的寄存器0例化在一起
    );
    
reg [25:0] period_cnt ;

//周期计数:1s记一次
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        period_cnt <= 26'd0;
    else if(period_cnt==26'd50_000_000)
        period_cnt <= 26'd0;
    else
        period_cnt <= period_cnt+1'b1;
end

//计数范围:0-100
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)begin            
        cnt<=8'd0;   
    end
    else begin
        if(period_cnt == 26'd50_000_000)begin
            if(cnt==8'd100)begin
                cnt<=8'd0;
                
             end   
            else
                 cnt<=cnt+1'b1;   
           end
        else begin
            cnt<=cnt;
         
        end
     end

end

endmodule

双击 count_ip_v1_0 下的 count_ip_v1_0_S00_AXI_inst,(注:count_ip_v1_0 中的程序为系统默认生成,不做修改),如下图所示:
count_ip_v1_0_S00_AXI 模块实现了 AXI4 协议下的读写寄存器的功能,我们只需要对该模块稍作
修改,即可实现计数器输出的功能。
代码分析:
向寄存器中写入数据的部分代码:
在Vivado中创建计数器IP核_第21张图片
从寄存器中读出数据的部分代码:
在Vivado中创建计数器IP核_第22张图片
注意:在本次的计数器IP核创建例程中,我们需要在这里把slv_reg0作为PL到PS传输时的寄存器,即仅从寄存器中读出数据,而不需要向寄存器中写入数据,因此需要将它的赋值屏蔽掉,即直接注释掉即可,如下图所示。
在Vivado中创建计数器IP核_第23张图片
并在该文件中加入下列代码:
将计数值存放在reg0中,并对系统输入输出参数进行例化:
在Vivado中创建计数器IP核_第24张图片

完成上述步骤后即可,点击Run Synthesis进行编译。
在Vivado中创建计数器IP核_第25张图片
编译完成后,可通过IP-XACT 界面下的 component.xml 打开Package IP界面,开始设置IP的封装。依次按照下图步骤进行操作:
在Vivado中创建计数器IP核_第26张图片
在Vivado中创建计数器IP核_第27张图片
在Vivado中创建计数器IP核_第28张图片
在Vivado中创建计数器IP核_第29张图片

在Vivado中创建计数器IP核_第30张图片
至此,自定义IP就配置完成了,需要使用计数器ip可直接调用。
可在SDk中使用COUNT_IP_mReadReg(COUNT_IP_BASEADDR,COUNT_IP_REG0);对计数结果进行读取。
#define COUNT_IP_BASEADDR XPAR_COUNT_IP_0_S00_AXI_BASEADDR //IP的基地址
#define COUNT_IP_REG0 COUNT_IP_s0_AXI_SLV_REGG_OFFSET //REG0地址

SDK中编写如下代码即可实现,计数器读取:

#include "stdio.h"
#include "xparameters.h"
#include "count_ip.h"
#include "xil_io.h"
#include "sleep.h"
#include "stdlib.h"
#include "sleep.h"


#define COUNT_IP_BASEADDR		XPAR_COUNT_IP_0_S00_AXI_BASEADDR  //IP的基地址
#define COUNT_IP_REG0			COUNT_IP_S00_AXI_SLV_REG0_OFFSET //REG0地址

int main(){
	int result = 0;

	printf("test\n");
	while(1)
	{

			//读取结果
			result = COUNT_IP_mReadReg(COUNT_IP_BASEADDR,COUNT_IP_REG0);
			printf("CPU0 count: %d\n",result);
			sleep(1);
	}
	return 0;
}

你可能感兴趣的:(FPGA,SDK,fpga)