本帖最后由 FPGA课程 于 2024-10-15 18:40 编辑
软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
1 概述本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO 写,实现将 PL 端数据 通过 DMA 发送给 PS 功能。 本文实验目的: 1:掌握编程 PL 代码,以 AXI-Stream 协议把数据通过 DMA 发送到 PS DDR 2:通过 VITIS-SDK 编程实现数据的接收 3:通过 VITIS-SDK 观察 PS 内存中接收到的数据是否正确。 2 搭建 SOC 系统工程新建一个名为为 zu_prj 的工程,之后创建一个 BD 文件,并命名为 system ,添加并且配置好 ZYNQ Ultrascale+ MPSOC IP 。读者需要根据自己的硬件类型配置好输入时钟频率、 内存型号、串 口,连接时钟等。新手不清楚这些 内容的,请参考“3-2-01_ex_soc_base .pdf” “01 HelloWold/DDR/网口测试 ”这篇文章。
2.1PS 部分设置
1:PS 复位设置
2:设置 PS GP 接口和 HP 接口
3:设置 PL 到 PS 的中断Interurpts-->勾选 Fabric Interrupt ,勾选 IRQ_F2P[15:0]。
4:设置 PL 的时钟勾选 PL0 ,设置为 100 ,即 PS 的 PLL 提供本系统的时钟 100MHZ。
2.2 添加 IP单击添加IP 按钮“
编辑” ,输入如下模块 IP 名字的关键词,并双击添加。
2.3IP 设置设置 Wideh of buffer length register :23 。(寄存器设置最大为 26,即 2 的 26 次方 64M 大小,这里设置 23bit 就 够用了,长度越大,需要的资源也就越多) 这里也只要使用DMA 写通道,
Data FIFO 设置 TDATA Width 为 4。
2.4PL 图形编程下图中可以看到 FIFO 的 S_AXIS 接口引出到了外部的FPGA 代码中,所以后面我们需要编写合适的 AXI-Stream FPGA 代码来写 FIFO。
2.5 地址空间分配
2.6 编写 AXI-Stream 写代码如下图中,system_dma_top.v 代码是可以实现对 FPGA 图形设计代码的调用。
现在我们看看 system_dma_top.v 中如何利用 axi-stream 协议完成对 fifo 的写操作。 - module system_wrapper
- (
- inout [14:0]DDR_addr,
- inout [2:0]DDR_ba,
- inout DDR_cas_n,
- inout DDR_ck_n,
- inout DDR_ck_p,
- inout DDR_cke,
- inout DDR_cs_n,
- inout [3:0]DDR_dm,
- inout [31:0]DDR_dq,
- inout [3:0]DDR_dqs_n,
- inout [3:0]DDR_dqs_p,
- inout DDR_odt,
- inout DDR_ras_n,
- inout DDR_reset_n,
- inout DDR_we_n,
- inout FIXED_IO_ddr_vrn,
- inout FIXED_IO_ddr_vrp,
- inout [53:0]FIXED_IO_mio,
- inout FIXED_IO_ps_clk,
- inout FIXED_IO_ps_porb,
- inout FIXED_IO_ps_srstb
- );
- reg [31:0]W_data_i_0;
- wire W_wren_i_0;
- wire [0:0]dma_rstn;
- wire [0:0]dma_start;
- wire pl_clk;
- assign W_wren_i_0 = dma_start;
- always @(posedge pl_clk)begin
- if(dma_rstn == 1'b0)
- W_data_i_0 <= 0;
- else if(dma_start )
- W_data_i_0 <= W_data_i_0 + 1'b1;
- end
- system system_i
- (
- .DDR_addr(DDR_addr),
- .DDR_ba(DDR_ba),
- .DDR_cas_n(DDR_cas_n),
- .DDR_ck_n(DDR_ck_n),
- .DDR_ck_p(DDR_ck_p),
- .DDR_cke(DDR_cke),
- .DDR_cs_n(DDR_cs_n),
- .DDR_dm(DDR_dm),
- .DDR_dq(DDR_dq),
- .DDR_dqs_n(DDR_dqs_n),
- .DDR_dqs_p(DDR_dqs_p),
- .DDR_odt(DDR_odt),
- .DDR_ras_n(DDR_ras_n),
- .DDR_reset_n(DDR_reset_n),
- .DDR_we_n(DDR_we_n),
- .FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
- .FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
- .FIXED_IO_mio(FIXED_IO_mio),
- .FIXED_IO_ps_clk(FIXED_IO_ps_clk),
- .FIXED_IO_ps_porb(FIXED_IO_ps_porb),
- .FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),
- .W_data_i_0(W_data_i_0),
- .W_wren_i_0(W_wren_i_0),
- .dma_rstn(dma_rstn),
- .dma_start(dma_start),
- .pl_clk(pl_clk)
- );
- endmodule
复制代码以上代码非常简洁,本身 axi-stream 协议就非常简洁。 以上代码中设置 S_AXIS_tvalid = 1'b1 始终为 1 代表,任何时候只要 S_AXIS_tready 有效,数据计数器 S_AXIS_tdata 就加 1,每次发送 512 个 32bit 数据,也就是 1024 个字节数据。每发送 1024 个数据产生一个中断。中断的产生是靠 axi-stream 协议的 S_AXIS_tlast 信号决定。S_AXIS_tlast = (S_AXIS_tdata == 511)&&S_AXIS_tready&&S_AXIS_tvalid。 2.7 编译并导出平台文件1:单击 Block 文件 --> 右键 --> Generate the Output Products --> Global --> Generate。 2: 单 击 Block 文 件 --> 右 键 --> Create a HDL wrapper( 生 成 HDL 顶 层 文 件 ) --> Let vivado manager wrapper andauto-update(自动更新)。 3:生成 Bit 文件。 4:导出到硬件: File --> Export Hardware --> Include bitstream 5:导出完成后,对应工程路径的 zu_hw 路径下有硬件平台文件:system_wrapper.xsa 的文件。根据硬件平台文件 system_wrapper.xsa 来创建需要 Platform 平台。
3 搭建 Vitis-sdk 工程创建 zu_base sdk platform 和 APP 工程的过程不再重复,可以阅读本章节 01~05 相关 demo 。 以下给出创建好 zu_base sdk platform 的截图和对应工程 APP 的截图。 3.1 创建 SDK Platform 工程
3.2 创建 axi_dma_pl2ps APP 工程
4 实验结果
Debug 程序,单程序停止 main 函数处,打开 VIVADO ,扫描芯片,这个时候会自动之前添加的在线逻辑分析仪 IP 核。如下红框的按键先不要单击。
具体步骤如下: 在 VIVADO 工程中点击 Open Target 然后点击 Auto Connect
连接成功后入下图 下图中,我们利用 axi-tlast 信号作为触发信号
下图中我们使用DMA 产生的中断信号作为触发信号
单击如下图片,让在线逻辑分析仪的 2 个窗口都处于等待触发状态
如下图所示是等待触发状态
回到 SDK,继续设置,打开 Memory:Window->Show View->Memory
点击添加接收内存部分地址用于观察内存中的数据 地址为 0x01300000
为了观察一次收发数据:设置断点,重新让收发程序跑一次。双击以下程序处可以设置断点。
设置完成后,单击如下可以单击如下红框的按键
串口打印结果,通过设置 TTC 定时器,每间隔 1S 打印一次计算的测速。实际上也就是计算单位时 间内,DMA 了多少次。可以通过增加数据位宽,以及增加 PL 时钟的频率,提高速度。读者可以去 尝试下。
内存中观察到的数据,可以看到地址 0x01300000 地址的开始并不是 00 而是 AB 和我们的预期有些差 异,不过数据是非常有规律的,说明DMA 是正常工作的,但是我们的用户逻辑实际上没有能够确保 发送数据的时候第一数据是 00 ,这个大家可以思考下为什么,有什么办法可以改进。我们后面 lwip的 demo 就对此问题必须做改进。
在线逻辑分析仪
|