本次验证采用的基本思路为PL对PS端DDR进行读写验证(采用AXI协议),再PS端读取DDR数据存入数组,串口打印,参考黑金的教程
用到3个HDL代码(aq_axi_master.v mem_test.v top.v),aq_axi_master模块包括AXI协议主要的读写逻辑,mem_test模块用于控制产生测试数据进行循环读写,我对代码进行了详细的注释,有需要可以看看,AXI协议的简单原理跳转见[[5 PS与PL数据常用交互之DDR读写#AXI协议原理|AXI原理]]
注意:mem_test模块的数据读写和地址是以字(word)为单位,而AXI协议的地址是以字节(byte)为单位,1字的宽度和总线宽度相同,故1word=64bit,字节固定为8bit,DDR每个地址存储8位数据(1字节)
操作步骤为硬件环境搭建、PL端读写验证、PS读取验证
硬件环境搭建好后,进行一次综合,点击set up debug快速创建ILA(需要观察的信号已在代码中标记好)
导出xsa文件后,快速创建一个hello world工程,修改代码如下
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#define MEM_BASE_ADDR 0x10000000 // PL 写入数据的起始地址
#define DATA_SIZE 256 // 读取的数据量(128个64bit数据 == 256 个 32-bit 数据)
int main()
{
init_platform();
print("Hello Worldnr");
print("Successfully ran Hello World application");
//使用 volatile uint32_t * 指针 避免编译器优化,确保访问真实的硬件地址。
volatile uint32_t *mem_ptr = (uint32_t *)MEM_BASE_ADDR; // 直接映射到 PL 的存储地址
uint32_t data_array[DATA_SIZE];
// 读取数据并存入数组
for (int i = 0; i < DATA_SIZE; i++) {
data_array[i] = mem_ptr[i]; // 逐个读取数据
}
// 打印部分数据以验证
for (int i = 0; i < 10; i++) {
printf("Data[%d] = 0x%08Xn", i, data_array[i]);
}
cleanup_platform();
return 0;
}
结果验证
PL端读写验证
写入数据如下
读出数据如下
整体读写循环,error信号一直拉低,并无报错
PS端读取验证
ps端串口打印数据如下
硬件环境搭建
- 创建zynq核,配置好串口(或者其他基本工程另存为)
- 基于“ps_hello”工程,在 vivado 的界面中 HP 的配置如下图(HP0~HP3),这里面有使能控制,数据位宽选择,可选择 32bit、64bit 或 128bit 的位宽。我们的实验启用 HP0 配置为 64bit 位 宽,使用的时钟是 150Mhz,HP 的带宽是 150Mhz * 64bit,对于视频处理,ADC 数据采集等 应用都有足够的带宽。不需要 AXI HPM0 LPD,取消选择。
- 添加复位模块,用于复位
- 在空白处右键选择”Creat Port”,创建时钟端口并进行约束
配置如图
- 选中引脚,点击 Make External,将信号导出
修改引脚名称如下图,其中pl_clk0引脚输出150M时钟,在顶层文件中将其与axi_hp_clk相连
选择总线同步时钟为 axi_hp_clk
- 点开 Address Editor,如果发现地址没有分配,点击自动分配地址按钮
分配后的结果,可以看到访问 DDR, QSPI, OCM 的地址空间
对比vitis中的结果
保存设计,重新 Generate Ouput Product
- 添加 hdl 文件
AXI协议原理
AXI4 相对复杂,但 SOC 开发者必须掌握,对于 zynq 的开发者,笔者建议能够在一些已 有的模板代码基础上修改。AXI 协议的具体内容可参考 Xilinx UG761 AXI Reference Guide。 在这里我们简单了解一下。
AXI4 所采用的是一种 READY,VALID 握手通信机制,即主从模块进行数据通信前,先根 据操作对各所用到的数据、地址通道进行握手。主要操作包括传输发送者 A 等到传输接受者 B 的 READY 信号后,A 将数据与 VALID 信号同时发送给 B,这是一种典型的握手机制。
AXI 总线分为五个通道:
读地址通道,包含 ARVALID, ARADDR, ARREADY 信号;
写地址通道,包含 AWVALID,AWADDR, AWREADY 信号;
读数据通道,包含 RVALID, RDATA, RREADY, RRESP 信号;
写数据通道,包含 WVALID, WDATA,WSTRB, WREADY 信号;
写应答通道,包含 BVALID, BRESP, BREADY 信号;
系统通道,包含:ACLK,ARESETN 信号;
其中 ACLK 为 axi 总线时钟,ARESETN 是 axi 总线复位信号,低电平有效;读写数据与读 写地址类信号宽度都为 32bit;READY 与 VALID 是对应的通道握手信号;WSTRB 信号为 1 的 bit 对应 WDATA 有效数据字节,WSTRB 宽度是 32bit/8=4bit;BRESP 与 RRESP 分别为写回 应信号,读回应信号,宽度都为 2bit,‘h0 代表成功,其他为错误。
读操作顺序为主与从进行读地址通道握手并传输地址内容,然后在读数据通道握手并传输 所读内容以及读取操作的回应,时钟上升沿有效。如图所示:
写操作顺序为主与从进行写地址通道握手并传输地址内容,然后在写数据通道握手并传输 所读内容,最后再写回应通道握手,并传输写回应数据,时钟上升沿有效。如图所示:







配置如图
修改引脚名称如下图,其中pl_clk0引脚输出150M时钟,在顶层文件中将其与axi_hp_clk相连
选择总线同步时钟为 axi_hp_clk
分配后的结果,可以看到访问 DDR, QSPI, OCM 的地址空间
对比vitis中的结果
保存设计,重新 Generate Ouput Product



Comments 1 条评论
🤩🤩🤩🥰🥰🥰😋😋😋😘😘😘😃😃😃