Microblaze 使用AXI Stream interface

FPGA连接如图所示

在这里插入图片描述

官方源代码

/* 
 * Example of using AXI-Stream instructions efficiently in MicroBlaze.
 *
 * See "Pipeline Architecture - Avoiding Data Hazards" in Chapter 2 of the
 * MicroBlaze Processor Reference Guide (UG984) for details.
 */
#include <stdio.h>
#include <xtmrctr.h>
#include "mb_interface.h"

#define MAX_COUNT 1000
#define BUFFER_SIZE 16

/*
 * Write 16 32-bit words as efficiently as possible.
 */
static void inline write_axis(volatile unsigned int *a)
{
    register int a0,  a1,  a2,  a3;
    register int a4,  a5,  a6,  a7;
    register int a8,  a9,  a10, a11;
    register int a12, a13, a14, a15;

    a3  = a[3];  a1  = a[1];  a2  = a[2];  a0  = a[0];
    a7  = a[7];  a5  = a[5];  a6  = a[6];  a4  = a[4];
    a11 = a[11]; a9  = a[9];  a10 = a[10]; a8  = a[8];
    a15 = a[15]; a13 = a[13]; a14 = a[14]; a12 = a[12];

    putfsl(a0,  0); putfsl(a1,  0); putfsl(a2,  0); putfsl(a3,  0);
    putfsl(a4,  0); putfsl(a5,  0); putfsl(a6,  0); putfsl(a7,  0);
    putfsl(a8,  0); putfsl(a9,  0); putfsl(a10, 0); putfsl(a11, 0);
    putfsl(a12, 0); putfsl(a13, 0); putfsl(a14, 0); putfsl(a15, 0);
}

/*
 * Read 16 32-bit words as efficiently as possible.
 */
static void inline read_axis(volatile unsigned int *a)
{
    register int a0,  a1,  a2,  a3;
    register int a4,  a5,  a6,  a7;
    register int a8,  a9,  a10, a11;
    register int a12, a13, a14, a15;

    getfsl(a0,  0); getfsl(a1,  0); getfsl(a2,  0); getfsl(a3,  0);
    getfsl(a4,  0); getfsl(a5,  0); getfsl(a6,  0); getfsl(a7,  0);
    getfsl(a8,  0); getfsl(a9,  0); getfsl(a10, 0); getfsl(a11, 0);
    getfsl(a12, 0); getfsl(a13, 0); getfsl(a14, 0); getfsl(a15, 0);

    a[3]  = a3;  a[1]  = a1;  a[2]  = a2;  a[0]  = a0;
    a[7]  = a7;  a[5]  = a5;  a[6]  = a6;  a[4]  = a4;
    a[11] = a11; a[9]  = a9;  a[10] = a10; a[8]  = a8;
    a[15] = a15; a[13] = a13; a[14] = a14; a[12] = a12;
}

int main()
{
    volatile unsigned int outbuffer[BUFFER_SIZE] = {
       0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
    };
    volatile unsigned int inbuffer[BUFFER_SIZE];
    int count = 0;

    XTmrCtr TmrCtr;
    int Status;
    unsigned int start_cycles, stop_cycles, total_cycles;

    /* Set up and start timer */
    Status = XTmrCtr_Initialize(&TmrCtr, XPAR_TMRCTR_0_DEVICE_ID);
    if (Status != XST_SUCCESS)
        return XST_FAILURE;
    start_cycles = XTmrCtr_GetValue(&TmrCtr, 0);
    XTmrCtr_Start(&TmrCtr, 0);

    /* Perform transfers */
    while (count++ < MAX_COUNT) {
        write_axis(outbuffer);
        read_axis(inbuffer);
    }

    /* Stop and read timer */
    XTmrCtr_Stop(&TmrCtr, 0);
    stop_cycles = XTmrCtr_GetValue(&TmrCtr, 0);
    total_cycles = stop_cycles - start_cycles;

    /* Report bandwidth */
    xil_printf("AXI-Stream bandwidth: %d Mbps\r\n",
      (MAX_COUNT * BUFFER_SIZE * 2 * 32) / total_cycles * (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 1000000));

    return 0;
}

### MicroBlazeAXI4-Stream FIFO 的配置与编程 #### 配置 AXI Stream FIFO 为了使输出路径正常工作,AXI Stream FIFO 必须断言 `TREADY` 信号。这可以通过在 MicroBlaze 上运行的软件来完成配置[^1]。 对于 AXI Stream FIFO 来说,其接口特性决定了它适用于高速流传输数据场景。具体来说,写入端作为 AXI-stream 从接口而读取端则充当 AXI-stream 主接口的角色[^2]。 当涉及到具体的硬件描述语言(HDL)层面时,在 Vivado 或其他 FPGA 开发环境中创建项目之后,应当通过 IP Integrator 添加 AXI Stream FIFO 组件并将其连接至相应的模块上。随后利用 Tcl 脚本或者图形界面调整参数设定如深度等属性以适应实际应用场景的需求。 ```tcl set_property CONFIG.Fifo_Depth {1024} [get_ips axi_stream_fifo_0] ``` #### 编程 AXI Stream FIFO 针对基于 MicroBlaze 处理器的操作而言,通常会采用 C/C++ 程序来进行控制逻辑编写: 1. 初始化阶段需确保正确加载驱动程序以及初始化必要的外设资源; 2. 数据发送过程中要遵循 AXI 协议规定的数据包格式构建有效载荷并通过特定函数调用来触发传输动作;接收方同样依据接收到的信息按照既定规则解析处理。 3. 对于错误检测机制部分,则可以考虑加入超时判断等功能增强系统的鲁棒性和可靠性。 下面给出一段简化后的伪代码示例用于说明上述过程中的某些要点: ```c #include "xaxistreamfifo.h" XAxiStreamFifo Fifo; // Initialization routine for the AXI Stream FIFO. void init_axi_stream_fifo() { XAxiStreamFifo_Config *Config; Config = XAxiStreamFifo_LookupConfig(XPAR_AXISTREAM_FIFO_0_DEVICE_ID); if (!Config) { // Handle error... } XAxiStreamFifo_CfgInitialize(&Fifo, Config, XPAR_AXISTREAM_FIFO_0_BASEADDR); } // Function to send data through the AXI Stream FIFO. void send_data(const uint8_t* buffer, size_t length) { while (length--) { XAxiStreamFifo_WriteByte(&Fifo, *buffer++); } } ``` 以上仅展示了基础框架下的实现方式,更复杂的应用可能还需要深入研究官方文档获取更多细节指导。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值