【ZYNQ入门】第七篇、AXI Lite协议使用方法

目录

第一部分、参考文章

1、PL端读取   

2、PL端写入 

第二部分、AXI Lite IP封装

1、封装步骤

2、 AXI Lite寄存器的地址

第三部分、SDK的调用方法

1、调用方法

2、 AXI_Lite.c代码      

3、仿真测试

3.1、main.c文件

3.2、仿真的结果 

第四部分、总结


第一部分、参考文章

        关于AXI总线的相关知识,大家可以参考我之前写的这篇文章:【ZYNQ入门】第五篇、AXI HP口读写数据原理-CSDN博客。

        AXI Lite总线内部协议就是AXI Lite协议,与FPGA之间通过GP口相连接。这里我就不过多去介绍它的基本知识,我只简单说一下我在使用过程中对AXI Lite IP的一些思考。

        AXI Lite IP可以看作是PS端与PL端中间的一块寄存器列表,这个寄存器列表可以PS端做主机,PL端做从机;也可以PL端做主机,PS段做从机。

        但是我目前遇到的情况如下图,都是:PS端做主机,PL端做从机。PS端对寄存器列表是可读可写,然后PL端去读取写入的值。

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第1张图片

1、PL端读取   

        PL去读取AXI Lite寄存器列表的值还是非常简单的,将想要读取的值进行导出和赋值就可以了。这里采用always语句块,保证时序。

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第2张图片

2、PL端写入 

        当然,PL端也是可以去修改AXI Lite寄存器列表内的值。通过修改下面这段源码就可以实现。具体细节请参考《米联客 ZYNQ 修炼秘籍裸机篇 2019 版》第248页(关于这本实验手册大家可以去官网下载,没有的可以在评论区留下邮箱,我发给你。)

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第3张图片

第二部分、AXI Lite IP封装

1、封装步骤

第一步、Tools下Creat and Package New IP。

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第4张图片

第二步、修改名称,描述文件等

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第5张图片

第三步、选择协议为Lite,接口模式为Slave(因为ZYNQ做主机),数据位宽默认32位,寄存器的个数:按需填写

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第6张图片

 第四步、根据硬件需求适当修改内部代码,导出某些端口等

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第7张图片

 第五步、我在设计时把前六个寄存器的值都导出到了ila

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第8张图片

2、 AXI Lite寄存器的地址

        AXI Lite寄存器的首地址,可以在Address Editer中查看和

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第9张图片

第三部分、SDK的调用方法

1、调用方法

        如果调用了AXI Lite的IP,那么生成platform里面就会自动生成寄存器列表对应的.c和.h文件。如下图:只需将platform中的文件复制到主文件夹得src文件夹内部,修改代码,便可。

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第10张图片

2、 AXI_Lite.c代码      

        在AXI_Lite.c文件中增加如下代码。然后去AXI_Lite.h文件中申明函数。注意:记得添加"xil_io.h"文件,不然会报错。

        这里函数这么封装,填写RedAddr的时候就可以从0,1,2,3........,一直往后。而不是0,4,8,12......。这是因为寄存器列表每一个数据的大小都是32位,占用4个字节,因此地址偏移量为4。

/***************************** Include Files *******************************/
#include "AXI_Lite.h"
#include "xil_io.h"//防止报错

/************************** Function Definitions ***************************/
void write_conf_list(u32 BaseAddr,u32 RegAddr,u32 data){
	AXI_LITE_mWriteReg(BaseAddr, RegAddr<<2, data);
}

u32 read_conf_list(u32 BaseAddr,u32 RegAddr){
	return AXI_LITE_mReadReg(BaseAddr, RegAddr<<2);
}

3、仿真测试

3.1、main.c文件

        定义了一个结构体,然后往寄存器列表写数据,最后在从PL端读取写入的数据。

#include "xil_printf.h"
#include "AXI_Lite.h"
#include "sleep.h"

//AXI Lite寄存器列表的首地址
#define REGBASEADDR 0x43C00000
typedef struct {
	u8  name;
	u8  sex;
	u32 phone_num;
	u32 class_a;
	u32 math_scores;
	u32 English_scores;
}regdata;

int main(){
	regdata data = {
		.name = 'A',
		.sex = 'm',
		.phone_num = 110,
		.class_a = 3,
		.math_scores = 99,
		.English_scores = 60
	};

	write_conf_list(REGBASEADDR,0,data.name);
	write_conf_list(REGBASEADDR,1,data.sex);
	write_conf_list(REGBASEADDR,2,data.phone_num);
	write_conf_list(REGBASEADDR,3,data.class_a);
	write_conf_list(REGBASEADDR,4,data.math_scores);
	write_conf_list(REGBASEADDR,5,data.English_scores);

	return 0;
}

3.2、仿真的结果 

        仿真结果与写入的一致(这里的Name和Sex都是以ascII码的方式显示)。

        从仿真的结果:我个人觉得AXI Lite这块寄存器列表,很像ZYNQ内部两颗ARM的共享内存。只不过这里是ARM和FPGA之间的共享内存。

【ZYNQ入门】第七篇、AXI Lite协议使用方法_第11张图片

第四部分、总结

        这部分内容比较简单,相较于AXI HP口的使用,AXI GP口的使用就简单很多。这里做下记录,防止后面使用的时候忘记了流程。

        对了,群聊号码1020775171,有疑问的小伙伴可以加入哦,但是我不太爱在群聊里说话,我觉得在群聊里说话有好多人看,有点抗拒,不太喜欢这种感觉,等我有时间了我再尝试尝试

        最后也希望我的笔记能够给你提供思路,当然个人的笔记难免会存在一些错误,若读者发现了,还忘指出

你可能感兴趣的:(FPGA的学习之旅,fpga开发,zynq,AXI)