存储映射:如果一个协议是存储映射的,那么主机所发出的会话(无论读或写)就会标明一个地址。这个地址对应于系统存储空间中的一个地址,表明是针对该存储空间的读写操作。
AXI4 接口,由五个独立的通道构成: 1、 读地址 2、 读数据 3、 写地址 4、 写数据 5、 写响应
在 PL 端自定义一个 AXI4 接口的 IP 核,通过 AXI_HP 接口对 PS 端 DDR3 进行读写测试,读写的内存大小是 4K 字节。
(按下按键时,PL对PS端的ddr写入4kb数据,每个数据为32位整数,即1-1024)
S_AXI_HP0 是 PS 端的 AXI 高性能接口,它是一个从接口,连接到 PS 内的存储器互联,用于 PL 访问 PS 内的存储设备,包括 OCM 和 DDR
创建完后会打开一个新工程,可以在这个工程中对创建的AXI4 MASTER IP核进行编辑修改
创建 AXI4 接口的 IP 时,Vivado 提供的 IP 封装工具已经自动帮我们实现了这样一个接口,并提供了一个示例程序
这个程序的部分代码如下
//写地址,从基址开始,不断加4个字节
// Next address after AWREADY indicates previous address acceptance
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
begin
axi_awaddr <= 'b0;
end
else if (M_AXI_AWREADY && axi_awvalid)
begin
axi_awaddr <= axi_awaddr + burst_size_bytes;
end
else
axi_awaddr <= axi_awaddr;
end
//写数据,从1开始,不断加1
/* Write Data Generator
Data pattern is only a simple incrementing count from 0 for each burst */
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
axi_wdata <= 'b1;
//else if (wnext && axi_wlast)
// axi_wdata <= 'b0;
else if (wnext)
axi_wdata <= axi_wdata + 1;
else
axi_wdata <= axi_wdata;
end
实现了一个状态机,其状态转换图如下所示
系统复位后,状态机处于初始状态,在该状态下等待外部输入的启动传输脉冲 init_txn_pulse。一旦检 测到 init_txn_pulse 为高电平,状态机跳转到 INIT_WRITE 状态。
在 INIT_WRITE 状态下,状态机拉高 start_single_burst_write 信号,来不断地启动 AXI4 Master 接口对Slave 端大小为 4KB 的存储空间进行突发写操作。写操作完成后,write_done 信号会拉高,状态机进入INIT_READ 状态。
在 INIT_READ 状态下,状态机拉高 start_single_burst_read 信号,不断地启动 AXI4 Master 接口对 Slave端同一存储空间进行突发读操作,同时将读出的数据与写入的数据进行对比。读操作完成后,read_done 信号拉高,状态机进入 INIT_COMPARE 状态。
在 INIT_COMPARE 状态下,判断 AXI4 接口在读写过程中的是否发生错误,并将错误状态赋值给ERROR 信号,然后将 compare_done 信号拉高,表示一次读写测试完成。最后跳转到 IDLE 状态,等待下一次读写操作的启动信号。
不需要再对 IP 作任何修改,直接关闭新打开的工程,回到主工程打开IP Catalog
加进去block design
双击编辑axi4_rw_test_0 IP核,修改基址
接下来为添加按键消抖模块(将.v文件添加进block design内)
添加完后block design如图所示
点击自动连线,如下图所示
从上图中可以看到,在执行了自动连接之后,工具自动添加了两个 IP 核,分别是 AXI 智能互联(AXI Smartconnect)和处理器系统复位(Processor System Reseet)
最后需要手动布线和添加external引脚,添加完验证无误后依次执行“Generate Output Products”和“Create HDL Wrapper”
最终的bd设计如图所示
根据原理图和引脚分配IO管脚,然后就可以综合,生成比特流了
生成比特流后,导出xsa文件,打开vitis
新建一个空的应用工程,新建main.c,代码如下
#include "stdio.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "xil_io.h"
int main()
{
int i;
char c;
Xil_DCacheDisable();
printf("AXI4 PL DDR TEST!\n\r");
while(1)
{
scanf("%c",&c);
if(c == 'c'){
printf("start\r\n");
for(i=0;i<4096;i=i+4)
{
printf("%d is %d\n",i,(int)(Xil_In32(0x10000000+i)));
}
}
}
return 0;
}
该程序的功能是将ps端ddr在地址从0x10000000开始以32位整数(int)的形式打印(串口发送),一共打印4kb的数据用作测试
最后先下载pl部分的bitstream,然后下载ps部分的elf文件
未进行ddr读写时打开串口调试助手,然后发送一个字符'c',根据main.c的功能,将打印4kb数据,由于未向ddr读写数据,此时能看到打印的数据都是随机的
对ddr进行读写后再在串口调试助手发送字符'c',打印4kb数据,可以看到此时ddr已写入数据,4kb的内容为从1至1024
本文章使用limfx的vscode插件快速发布