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中的数据写入情况来查看。

相关推荐
步达硬件1 天前
【FPGA】DP、HDMI、USB4、GPMI、eDP、LVDS等音视频协议及性能对比
fpga开发
-木槿昔年-2 天前
【米尔-安路MYD-YM90X创意秀】飞龙派学习和PS串口实践
学习·fpga开发
Aaron15882 天前
基于RFSOC+VU13P+GPU架构在雷达电子战的技术
人工智能·算法·fpga开发·架构·硬件工程·信号处理·基带工程
jifengzhiling2 天前
伺服驱动器中DSP与FPGA高效协同架构解析
fpga开发·foc电机控制
太爱学习了2 天前
FPGA图像处理之:图像畸变矫正原理及matlab与fpga实现
图像处理·matlab·fpga开发
技术性摸鱼3 天前
FPGA选型参数
fpga开发
FPGA_小田老师3 天前
ibert 7 Series GT:IBERT远近端(内外)环回测试
fpga开发·ibert·gt测试·近端pcs环回·近端pma环回·远端pcs环回·远端pma环回
尤老师FPGA3 天前
【无标题】
fpga开发
175063319453 天前
VIVADO VLA VIO 硬件调试 降采样
fpga开发
FPGA小迷弟3 天前
基于FPGA开发高速ADC/DAC芯片笔记
图像处理·fpga开发·数据采集·fpga·adc