AXI_DMA IP核实战:24路并行数据高速存储方案

本文是AXI Direct Memory Access IP核在Direct Register模式下的实战例程,参考文档:

AXI Direct Memory Access IP核(1):AXI DMA深度解析_xilinx axi-dma-CSDN博客

AXI Direct Memory Access IP核(2):AXI DMA --Direct Register模式仿真例程(xilinx example)_xilinx axi direct memory access-CSDN博客

源代码:

【免费】AXI-DMAIP核实战:24路并行数据高速存储实战程序资源-CSDN下载


1 概述

在FPGA开发中,经常需要处理多路并行数据的采集与存储。本文将分享一个实际项目案例:将24路24位并行数据通过AXI_DMA高效地存入BRAM中。这个设计方案已经在我们的项目中稳定运行,希望能为有类似需求的开发者提供参考。

2 系统架构

整个系统由以下几个关键模块组成:

  • 数据产生模块:定时产生24路24位测试数据

  • 并行数据转AXIS模块:核心数据转换逻辑

  • AXI_DMA IP核:实现AXIS到AXI4总线的转换

  • AXI_VIP:用于配置和控制AXI_DMA

  • BRAM控制器:管理BRAM存储空间

3 详细设计说明

3.1 数据产生模块

数据产生模块以50MHz时钟运行,每1us(50个时钟周期)产生一组完整的24路24位数据,主状态机控制流程如下,详细设计可以参考资源【免费】AXI-DMAIP核实战:24路并行数据高速存储实战程序资源-CSDN下载

复制代码
// 数据生成组合逻辑
always @(*) begin
    data_in_0 = {(24'h300000 + base_value[23:0]), (24'h200000 + base_value[23:0]), (24'h100000 + base_value[23:0]), (24'h000000 + base_value[23:0])};
    data_in_1 = {(24'h700000 + base_value[23:0]), (24'h600000 + base_value[23:0]), (24'h500000 + base_value[23:0]), (24'h400000 + base_value[23:0])};
    data_in_2 = {(24'hB00000 + base_value[23:0]), (24'hA00000 + base_value[23:0]), (24'h900000 + base_value[23:0]), (24'h800000 + base_value[23:0])};
    data_in_3 = {(24'hF00000 + base_value[23:0]), (24'hE00000 + base_value[23:0]), (24'hD00000 + base_value[23:0]), (24'hC00000 + base_value[23:0])};
    data_in_4 = {(24'h130000 + base_value[23:0]), (24'h120000 + base_value[23:0]), (24'h110000 + base_value[23:0]), (24'h100000 + base_value[23:0])};
    data_in_5 = {(24'h170000 + base_value[23:0]), (24'h160000 + base_value[23:0]), (24'h150000 + base_value[23:0]), (24'h140000 + base_value[23:0])};
end

// -------------- 控制状态机
reg [2:0] current_state,next_state;
always @(posedge data_clk or negedge data_rstn) begin
    if (!data_rstn) begin
        current_state <= IDLE;
    end else begin
        current_state <= next_state;
    end
end
// -------------- 主状态机
always @ (*) begin
    next_state = current_state;
    case(current_state)
    IDLE:begin
        next_state <= DATA_GEN;
    end
    DATA_GEN:begin
        next_state <= DATA_VALID;
    end
    DATA_VALID:begin
        next_state <= DATA_WAIT;
    end
    DATA_WAIT:begin
        if (cycle_counter == DATA_FRE-1) begin
            next_state <= DATA_GEN;
        end
        else begin
            next_state = current_state;
        end
    end
    default:begin
        next_state = IDLE;
    end
    endcase

3.2 并行数据转AXIS模块

这是整个设计的核心,内部主要包含两个状态机。

3.2.1 状态机1:接收并行数据并按通道写入FIFO

状态机设计:

  • IDLE状态:等待传输使能信号

  • COLLECT_V状态:等待数据valid信号

  • COLLECT_D状态:根据计数器将数据依次存入FIFO,如果存储的数据已经足够gpio_package_length,就返回IDEL状态,等待下一次传输。

关键逻辑实现:

复制代码
/ -------------- 控制状态机
reg [2:0] current_state,next_state;
always @(posedge data_clk or negedge data_rstn) begin
    if (!data_rstn) begin
        current_state <= IDLE;
    end else begin
        current_state <= next_state;
    end
end
// ------------ 主状态机 
always @ (*) begin
    next_state = current_state;
    case(current_state)
    IDLE:begin
        if (data_wr_en_d0 & !data_wr_en_d1) begin
            next_state = COLLECT_V;
        end
    end
    COLLECT_V:begin
        if (word_valid_d0 & !word_valid_d1) begin  //全为1,上升沿检测
            next_state = COLLECT_D;
        end
        else begin
            next_state = current_state;
        end
    end
    COLLECT_D:begin
        if (Rec_count == gpio_packet_length_reg-1 ) begin
            next_state = IDLE;
        end
        else if (ch_count == CH_NUM-1) begin //共24个通道
            next_state = COLLECT_V;
        end
        else begin
            next_state = current_state;
        end
    end
    default:begin
        next_state = IDLE;
    end
    endcase
end

3.2.2 状态机2:从FIFO中取数据并转为AXIS

状态机设计:

  • IDLE状态:等待传输使能信号

  • UPDATE_LENGTH状态:取本次应该传输的数据量。

  • PREPARE_DATA状态:从FIFO中取数据

  • TRANSFER状态:转为AXIS总线形式,如果取数据量不足gpio_package_length,就返回PREPARE_DATA状态继续取数据,如果数据已经足够gpio_package_length,就返回IDEL状态,等待下一次传输使能。

关键逻辑实现:

复制代码
// 状态寄存器
always @(posedge m_axis_clk or negedge m_axis_rstn) begin
    if (!m_axis_rstn) begin
        current_state_r <= IDLE;
    end else begin
        current_state_r <= next_state_r;
    end
end
// 状态转移逻辑
always @(*) begin
    next_state_r = current_state_r;
    case(current_state_r)
    IDLE:begin
        if (start_en_d0 & !start_en_d1) begin  // recieve start flag
            next_state_r = UPDATE_LENGTH;
        end
    end
    UPDATE_LENGTH:begin
        if (!fifo_rd_empty) begin  // 当有数据需要传输时,先更新数据量
            next_state_r = PREPARE_DATA;
        end
    end
    PREPARE_DATA:begin
        if (!fifo_rd_empty) begin // 
            next_state_r = TRANSFER;
        end
    end
    TRANSFER:begin
        if (axis_tready && axis_tvalid ) begin  
            if (trans_count == gpio_packet_length_reg - 1) begin  // data trans finish
                next_state_r = IDLE;
            end
            else begin
                next_state_r = PREPARE_DATA;
            end
        end
    end
    endcase
end

3.3 AXI_VIP模块配置AXI_DMA模块

3.3.1 AXI_DMA的GUI配置

其使用的是通用DMA模式,只使能了S2MM通道。

3.3.2 AXI_VIP仿真激励

配置AXI_DMA的传输使能、中断、目的地址、数据长度。详细可查看AXI Direct Memory Access IP核(1):AXI DMA深度解析_xilinx axi-dma-CSDN博客

AXI Direct Memory Access IP核(2):AXI DMA --Direct Register模式仿真例程(xilinx example)_xilinx axi direct memory access-CSDN博客

之后拉起start_en,即告诉系统可以开始传输数据了。

当接收到AXI_DMA传输完成的中断的时候,清中断,之后重新配置AXI_DMA,使能start_en,发起下一次传输。

4 仿真结果

从下图可以看出,每隔一段时间,就会收到来资源前端的有效数据。

4.1 关于写FIFO:

当ADMA配置完成之后,会拉起start_en;

当 数据转换模块检测到 start_en之后,开始检测有效数据

当 检测到有效数据valid之后,将数据写入fifo

当写入数据量,足够我们要求的数据量时(本次是1024个32bit),停止写入

以上为写FIFO的工作流程

4.2 关于读FIFO:

当ADMA配置完成之后,会拉起start_en;

当 数据转换模块检测到 start_en之后,开始等待FIFO有数据

当 检测到FIFO有数据之后,从FIFO中取数据

取够我们所需要的数据量之后,tlast拉起,停止取数

因为我们写入的数据量 和 取走的数据量是一致的,故我们可以看到到最后一拍的时候我们的fifo是empty的状态

4.3 仿真结论:

通过trans count我们也可以看出,我们的parallel_to_axis_converter,每次发出的数据均是1024个32bit,一个tlast信号。

我们再来看看ADMA端

ADMA端,1024个数据一个Tlast信号,之后数据转为AXI4存入ram,然后拉起adma的中断。

最后再来看看存入RAM的数据,因为我每次都是从0x000地址开始的,然后递增的方式存进去。

所以可以根据BRAM中的数据写入情况来查看。

相关推荐
崇子嵘2 小时前
为什么需要“输出锁存”
fpga开发
szxinmai主板定制专家17 小时前
柔宇柔性显示屏+x86、arm显示解决方案,还有库存
arm开发·人工智能·fpga开发
CHY_12818 小时前
JESD204B 协议解析(5)ILA序列
fpga开发·jesd204
yang)21 小时前
PLL之鉴相器PFD
fpga开发
FPGA_无线通信1 天前
RRU CFR算法
fpga开发
国科安芯1 天前
AS32系列MCU芯片TIM模块的捕获和比较
单片机·嵌入式硬件·fpga开发·架构·risc-v
kk哥88991 天前
高性能计算 FPGA 开发:Quartus Prime 18.0 下载安装教程 高带宽内存(HBM2)支持
fpga开发
FPGA_无线通信1 天前
RRU 1588同步
fpga开发
燎原星火*2 天前
FMC接口定义
fpga开发