AXI DataMover ip 核 (一)

                       
                   

何为 DataMover

DataMover 很有趣的名字,他是谁,数据搬运工?那可得跟我们代码搬运工好生亲近下。-_-

DataMover 是 DMA 的一种形式。Direct Memory Access 对我们来说是一个更熟悉的名字。在不需要 CPU 干预的情况下,DMA 可以进行数据的搬运,包括但不仅限于将数据从外部存储,比如 DDR,搬运到内部寄存器,或者搬运到外部存储的另一个位置。这些都只需要 CPU 一句话的事:

 CPU:DMA, 帮我搬个数据!  
DMA:BOSS,你只需要告诉我从哪搬(   起始地址),搬多少(   字节长度),搬到哪!

然后 CPU 就可以爱干嘛干嘛,数据的搬运,和 DDR 打交道就全权由 DMA 负责了。

我们今天讨论的 DataMover 和上述典型的 DMA 的区别就在于,他不是由 CPU 来分配任务,而是由 FPGA 逻辑通过命令总线给出任务:从哪搬,搬到哪。

DataMover 的接口

那么 DataMover 是如何进行他的工作呢,我们可以从他的端口来了解。这里以 DM 的读通道为例。DataMover 共有三路接口(status 一般在调试中用于观察状态),一路 AXI 总线,两路 AXIS 总线。

AXI DataMover ip 核 (一)_第1张图片

AXI DataMover 读通道

读通道,将数据从如 DDR 这样的外部存储,搬运到 FPGA 的逻辑模块中。DDR 在 FPGA 上通过 MIG IP 访问,即 Memory 访问接口。MIG 提供了一个 AXI4 Slave 接口。DataMover 的 Master 接口连接到 MIG 的 Slave 接口,AXI4 协议提供了一种基于地址的访问 DDR 能力。关于 AXI4 对存储介质的地址访问,可以参考以下的文章,该文章中访问的是 BRAM ,但总线操作和访问 DDR 类似。

AXI DataMover ip 核 (一)_第2张图片

如何创建 DDR MIG 在各个开发板的教程中都有提及,Step by Step 设置自己的开发板上搭载的 DDR 芯片信息和引脚即可。如果你有钱....有幸能用 Xilinx 的评估板,那么 MIG 还可以一键建立,自动导入硬件和 DDR 信息。

无论是哪款开发板,都可以通过包含在 vivado 中的 MIG 中的示例工程对 MIG 进行仿真以及上板调试。

AXI DataMover ip 核 (一)_第3张图片

盗图自 xilinx PPT

从 MIG 中读取的 DDR 数据会以 AXI-Stream 总线的方式提供给逻辑部分。 AXI-S 总线相比 上述的 AXI4-Full 协议,信号更少,逻辑也比较简单。你可以从以下的文章中了解 AXI-S 的定义:

应用 AXI 协议没有定义说的那么复杂,以下是读取一段数据的示例。

AXI DataMover ip 核 (一)_第4张图片

简单的AXIS时序

tvalid 为高表示数据有效,tlast 置起表示当前是当次传输的最后一个数据,比如表示一次 DDR 读操作的结束。tkeep 表示数据中的有效字节,作用和 AXI4-Full 中的 strb 作用相同。

前文提到 DataMover 有两路 AXI-S 总线,一路总线是数据输出总线,将从 DDR 读取的数据输出。另一路为命令输入总线。

DataMover 命令

前文提到 DataMover 是由逻辑控制,控制的方式是通过命令输入 AXIS 总线输入 DataMover 命令。

DataMover 命令控制的就是读写操作的起始地址传输字节长度。命令有如下的格式,根据地址宽度的不同,命令长度不同,一般地址宽度,N,取 32 比特,命令长度 72 比特。

命令格式

一般只需要关注三个字段,EOF 字段设为 1 ,其他字段可以暂时填 0,这些填充固定值的字段将在后续的文章中进行分析。

  • BTT:Byte to Transfer  
    • 传输字节数
  • SADDR: start address  
    • 起始地址
  • Type:  
    • 突发传输类型,这个字段在过去的 IP 核版本中没有启用(ISE 时代),默认为 incr
    • 字段为 1 时:突发传输类型为 incr ,数据会保存在以起始地址开始递增的地址中
    • 字段为 0 时:突发传输类型为 fixed, 数据均保存在起始地址中,覆盖旧值

当地址为32bit宽时,cmd 为32(低32位)+32(地址)+4(TAG)+4(RSVD)=72 bit

AXI DataMover ip 核 (一)_第5张图片

AXI DataMover 写通道

写通道的逻辑与读通道相同,只是数据的方向相反。

仿真

这部分中将演示 DataMover 基本的读写方式,输入由 testbench 产生。后续的文章中会讨论一些更加实用的逻辑,应用于板级调试中。

读操作

通过 testbench 写入命令,这里定义了一个写入命令的 task,将起始地址和字节长度组装成一个命令。这里 #UI_CLK_PERIOD; 代表延时一个周期


       
       
         
         
         
         
  1. //task: read channel
  2. task mm2s_cmd;
  3.     input logic[ 22: 0] btt;
  4.     input logic[ 31: 0] saddr;
  5.     logic [ 71: 0] cmd = {
  6.                             4 'b0000,
  7.                             4 'b0000,
  8.                             saddr,
  9.                             1 'b0, //DRR
  10.                             1 'b1, //EOF
  11.                             6 'b000000, //DSA
  12.                             1 'b1, //type 1:incr 0:fixed
  13.                             btt
  14.         };
  15.     begin
  16.     S_AXIS_MM2S_CMD_0_tdata=cmd;
  17.     S_AXIS_MM2S_CMD_0_tvalid= 1;
  18.     # UI_CLK_PERIOD;
  19.     S_AXIS_MM2S_CMD_0_tdata= 0;
  20.     S_AXIS_MM2S_CMD_0_tvalid= 0;
  21.     end
  22. endtask

调用 task,指定传输的长度以及起始地址。

 mm2s_cmd(23'd64,32'h00000000);

AXI DataMover ip 核 (一)_第6张图片

读数据时序

读取到 64 字节数据,因为数据位宽 32 字节,所以读到两个有效信号脉冲。

写操作

写入命令和读命令类似,写命令可以在写数据之前或者之后,没有严格的对应关系。通过 AXIS 总线写入数据, DataMover 内部有一定缓存空间,相当于向一个 FIFO 写入数据。定义了一个写入指定长度的 task ,写入 data_num*32 bit 数据


       
       
         
         
         
         
  1. //task: write data
  2. task s2mm_data;
  3. input logic [31:0] data_num;
  4. begin
  5.         S_AXIS_S2MM_1_tvalid= 1;
  6.         S_AXIS_S2MM_1_tdata= 256'h12345678123456781234567812345678;
  7.         S_AXIS_S2MM_1_tkeep= 32'hfffffffff;
  8.         S_AXIS_S2MM_1_tlast= 0;
  9.         repeat(data_num-1)begin
  10.         #UI_CLK_PERIOD;
  11.         end
  12.         S_AXIS_S2MM_1_tlast= 1;
  13.         #UI_CLK_PERIOD;
  14.         S_AXIS_S2MM_1_tdata= 0;
  15.         S_AXIS_S2MM_1_tkeep= 0;
  16.         S_AXIS_S2MM_1_tlast= 0;
  17.         S_AXIS_S2MM_1_tvalid= 0;
  18. end
  19. endtask

AXI DataMover ip 核 (一)_第7张图片

写命令与写数据时序

这里写入了两个32位宽的数据,在第二个数据处, tlast 信号置起,表示传输的最后一个有效数据,tlast 清除表示此次传输结束。

结语

本文是 DataMover 的基础篇,初步介绍了 IP 核的用途和用法,并通过 testbench 调用 IP 实现了读写操作。但没有涉及比较复杂的部分,比如未对齐传输等。

转自:https://zhuanlan.zhihu.com/p/82129170

               
       

你可能感兴趣的:(FPGA,存储,xilinx)