从 IP 开始,学习数字逻辑:DataMover 基础篇

何为 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 总线。

从 IP 开始,学习数字逻辑:DataMover 基础篇 第1张



AXI DataMover 读通道


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

深入 AXI4总线 (四):RAM 读取实战


从 IP 开始,学习数字逻辑:DataMover 基础篇 第2张

连接DDR示意图


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

(我们实验室就是这么有钱...有幸有很多板子,包括 Xilinx ZCU102/VCU709/ KCU116 等等,如果对 FPGA 开发有兴趣,欢迎在今年以及未来的考/保研中加入我们实验室,我们有不错的硬件条件和项目。PS:坐标东部沿海211,省部共建国家重点实验室 )


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

从 IP 开始,学习数字逻辑:DataMover 基础篇 第3张

盗图自 xilinx PPT


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

深入 AXI4总线 (五):AXI4 的兄弟协议


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


从 IP 开始,学习数字逻辑:DataMover 基础篇 第4张

简单的AXIS时序


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

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


DataMover 命令

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


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

从 IP 开始,学习数字逻辑:DataMover 基础篇 第5张

命令格式


    一般只需要关注三个字段,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

从 IP 开始,学习数字逻辑:DataMover 基础篇 第6张


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


仿真

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


读操作

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

//task: read channeltask mm2s_cmd;    input logic[22:0] btt;    input logic[31:0] saddr;    logic [71:0] cmd = {                            4'b0000,                            4'b0000,                            saddr,                            1'b0,//DRR                            1'b1,//EOF                            6'b000000,//DSA                            1'b1,//type 1:incr 0:fixed                            btt        };    begin    S_AXIS_MM2S_CMD_0_tdata=cmd;    S_AXIS_MM2S_CMD_0_tvalid=1;    #UI_CLK_PERIOD;    S_AXIS_MM2S_CMD_0_tdata=0;    S_AXIS_MM2S_CMD_0_tvalid=0;    end endtask
 

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

mm2s_cmd(23'd64,32'h00000000);

从 IP 开始,学习数字逻辑:DataMover 基础篇 第7张

读数据时序


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


写操作

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

//task:write data task s2mm_data; input logic [31:0] data_num; begin        S_AXIS_S2MM_1_tvalid=1;        S_AXIS_S2MM_1_tdata=256'h12345678123456781234567812345678;        S_AXIS_S2MM_1_tkeep=32'hfffffffff;        S_AXIS_S2MM_1_tlast=0;        repeat(data_num-1)begin        #UI_CLK_PERIOD;        end        S_AXIS_S2MM_1_tlast=1;        #UI_CLK_PERIOD;        S_AXIS_S2MM_1_tdata=0;        S_AXIS_S2MM_1_tkeep=0;        S_AXIS_S2MM_1_tlast=0;        S_AXIS_S2MM_1_tvalid=0; endendtask

从 IP 开始,学习数字逻辑:DataMover 基础篇 第8张

写命令与写数据时序


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

结语

    本文是 DataMover 的基础篇,初步介绍了 IP 核的用途和用法,并通过 testbench 调用 IP 实现了读写操作。但没有涉及比较复杂的部分,比如未对齐传输等。如何使用这些更复杂的应用,以及如何将 DataMover 使用在实际项目中,我们将在后续的文章中进行讨论。


添加回复:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。