PS-PL InterConnect_2_hp

AXI4回顾

存储映射:如果一个协议是存储映射的,那么主机所发出的会话(无论读或写)就会标明一个地址。这个地址对应于系统存储空间中的一个地址,表明是针对该存储空间的读写操作。

AXI4 接口,由五个独立的通道构成: 1、 读地址 2、 读数据 3、 写地址 4、 写数据 5、 写响应

1

PS-PL端DDR3内存读写测试

需求描述

在 PL 端自定义一个 AXI4 接口的 IP 核,通过 AXI_HP 接口对 PS 端 DDR3 进行读写测试,读写的内存大小是 4K 字节。

(按下按键时,PL对PS端的ddr写入4kb数据,每个数据为32位整数,即1-1024)

实验流程

创建ZYNQ PS IP核

2

3

S_AXI_HP0 是 PS 端的 AXI 高性能接口,它是一个从接口,连接到 PS 内的存储器互联,用于 PL 访问 PS 内的存储设备,包括 OCM 和 DDR

定义AXI4 MASTER IP核

4

5

创建完后会打开一个新工程,可以在这个工程中对创建的AXI4 MASTER IP核进行编辑修改 6

创建 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          

实现了一个状态机,其状态转换图如下所示 7

系统复位后,状态机处于初始状态,在该状态下等待外部输入的启动传输脉冲 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 8

加进去block design 9

双击编辑axi4_rw_test_0 IP核,修改基址 10

block design设计

接下来为添加按键消抖模块(将.v文件添加进block design内)

11

12 13

添加完后block design如图所示 14

点击自动连线,如下图所示 15

从上图中可以看到,在执行了自动连接之后,工具自动添加了两个 IP 核,分别是 AXI 智能互联(AXI Smartconnect)和处理器系统复位(Processor System Reseet)

最后需要手动布线和添加external引脚,添加完验证无误后依次执行“Generate Output Products”和“Create HDL Wrapper”

最终的bd设计如图所示 15.5 根据原理图和引脚分配IO管脚,然后就可以综合,生成比特流了 16

生成比特流后,导出xsa文件,打开vitis

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的数据用作测试 17

最后先下载pl部分的bitstream,然后下载ps部分的elf文件

结果测试

未进行ddr读写时打开串口调试助手,然后发送一个字符'c',根据main.c的功能,将打印4kb数据,由于未向ddr读写数据,此时能看到打印的数据都是随机的 18

对ddr进行读写后再在串口调试助手发送字符'c',打印4kb数据,可以看到此时ddr已写入数据,4kb的内容为从1至1024 19

20


本文章使用limfx的vscode插件快速发布