目录
第一部分、参考文章
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端去读取写入的值。
PL去读取AXI Lite寄存器列表的值还是非常简单的,将想要读取的值进行导出和赋值就可以了。这里采用always语句块,保证时序。
当然,PL端也是可以去修改AXI Lite寄存器列表内的值。通过修改下面这段源码就可以实现。具体细节请参考《米联客 ZYNQ 修炼秘籍裸机篇 2019 版》第248页。(关于这本实验手册大家可以去官网下载,没有的可以在评论区留下邮箱,我发给你。)
第一步、Tools下Creat and Package New IP。
第二步、修改名称,描述文件等
第三步、选择协议为Lite,接口模式为Slave(因为ZYNQ做主机),数据位宽默认32位,寄存器的个数:按需填写
第四步、根据硬件需求适当修改内部代码,导出某些端口等
第五步、我在设计时把前六个寄存器的值都导出到了ila
AXI Lite寄存器的首地址,可以在Address Editer中查看和
如果调用了AXI Lite的IP,那么生成platform里面就会自动生成寄存器列表对应的.c和.h文件。如下图:只需将platform中的文件复制到主文件夹得src文件夹内部,修改代码,便可。
在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);
}
定义了一个结构体,然后往寄存器列表写数据,最后在从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;
}
仿真结果与写入的一致(这里的Name和Sex都是以ascII码的方式显示)。
从仿真的结果:我个人觉得AXI Lite这块寄存器列表,很像ZYNQ内部两颗ARM的共享内存。只不过这里是ARM和FPGA之间的共享内存。
这部分内容比较简单,相较于AXI HP口的使用,AXI GP口的使用就简单很多。这里做下记录,防止后面使用的时候忘记了流程。
对了,群聊号码1020775171,有疑问的小伙伴可以加入哦,但是我不太爱在群聊里说话,我觉得在群聊里说话有好多人看,有点抗拒,不太喜欢这种感觉,等我有时间了我再尝试尝试
最后也希望我的笔记能够给你提供思路,当然个人的笔记难免会存在一些错误,若读者发现了,还忘指出。