C语言 尝试使连续的FIFO数据流



我正在使用带有 Vivado 2014.3 的赛灵思 ZC702 FPGA 以及 SDK(软件开发套件(。

我想创建FIFO数据流,它不小于20,即流量不足,不高于500,即超流。为此,我使用了AXI4 Stream FIFO IP,为了使代码正常工作,我必须使用寄存器,这些寄存器可以在下面粘贴的axi流FIFO的数据表中找到。

如果FIFO数据达到500,那么它应该停止加载新数据,

如果FIFO数据达到20,那么它应该填充新数据,直到达到500。此过程应一直重复。

我在FIFO软件开发工具包中制作了一个测试程序,以便通过硬件查看模拟波形结果。我观察到的是FIFO数据不是连续的。我需要让它处于连续模式,它不应该停止,它应该像一个循环。

请在下面找到 c 代码

#include <stdio.h>
#include <xil_types.h>
#include <xil_cache.h>
#include "platform.h"
#include "xil_io.h"
//#include "usb20_per.h"
int main()
{
#define SLCR_UNLOCK     0xF8000008
#define SLCR_UNLOCK_VAL 0xDF0D
#define SLCR_LOCK       0xF8000004
#define SLCR_LOCK_VAL   0x767B
#define XSLCR_FPGA_RST_CTRL 0xF8000240

    uint32_t baseaddr_ber=0x43c00000;
    uint32_t baseaddr_fifo=0x43c10000;
    Xil_Out32(SLCR_UNLOCK, SLCR_UNLOCK_VAL); //
    Xil_Out32(XSLCR_FPGA_RST_CTRL, 0x0000000F);    //Reset FPGAx_OUT_RST
    Xil_Out32(XSLCR_FPGA_RST_CTRL, 0x00000000);    //Deassert the FPGAx_OUT_RST
    Xil_Out32(SLCR_LOCK, SLCR_LOCK_VAL);     //
    Xil_ICacheEnable();
    Xil_DCacheEnable();
    print("---Entering main---nr");
    init_platform();
    //  Xil_Out32 & Xil_In32
    Xil_Out32(baseaddr_fifo+0x4, 0x0C0001FC); //IER //interrupt enable register
    Xil_Out32(baseaddr_fifo+0x2C,0x00000002); //TDR //transmit data register
    uint32_t word_cnt;
    uint32_t idx;
    uint32_t state;
    uint32_t i,val;
    #define ARRAY_LENGTH 16
    uint32_t array_fifo_data[ARRAY_LENGTH] = { 0x0100, 0x0302, 0x0504, 0x0706, 0x0908, 0x0B0A, 0x0D0C, 0x0F0E, 0x0100, 0x0302, 0x0504, 0x0706, 0x0908, 0x0B0A, 0x0D0C, 0x0F0E }; //random sequence
    state=0;
    word_cnt=0;
    idx=0;
    while(1)
    {
        switch (state)
        {
            case 0:
                val = Xil_In32(baseaddr_fifo + 0x0c);
                if(val > 0x1A0) //check TDFV register value //transmit data fifo vacancy
                {
                    state++;
                } 
                else 
                {
                    val=0;
                }
                break;
            case 1:
                word_cnt=0;
                        for(i=0;i<16;i++)
                        {
                            Xil_Out32(baseaddr_fifo + 0x10, array_fifo_data[idx]); //Fill TXFIFO_DATA if TDFV falls below 20 and above 500
                            word_cnt++;
                            idx++;
                            if (idx>(ARRAY_LENGTH-1))
                                idx=0;
                        }
                        Xil_Out32(baseaddr_fifo+0x14,word_cnt*4); //TLR (transmit length register)
                        state=0;
                break;
        }
    }
}

下面有一个链接,用于 axi strem fifo IP 的数据表。页面 # 7,传输数据包,页面 # 23,寄存器空间显示我在上面的代码中使用的寄存器的基址和偏移地址。

http://www.xilinx.com/support/documentation/ip_documentation/axi_fifo_mm_s/v4_0/pg080-axi-fifo-mm-s.pdf

我真的很感激你的帮助。

从我制作的代码中,我

可以看到FIFO在工作并传输我放入代码中的顺序随机数据,但是该过程不是连续的,它在传输数据后停止,它应该重复该过程并继续它,它不应该停止,就像循环一样。

打开下面的链接以查看模拟波形结果。您将看到 fifo 工作,它传输完整的随机频率,然后停止,我希望重复传输随机序列。

https://www.dropbox.com/sh/nydws0v5yjyphj3/AAAg_l7aEvUG3gEzhYedwgWra?dl=0

EDIT: some comments about read/write only may be incorrect
// I commented out certain #include statements and added certain
// prototype statements, just for the ability to compile.

// The coding sequences in the OP posted software do not
// match the coding sequences given in the referenced PDF file.
// suggest OP correct those coding sequences.

#include <stdio.h>
//#include <xil_types.h>
//#include <xil_cache.h>
//#include "platform.h"
//#include "xil_io.h"
void Xil_ICacheEnable( void );
void Xil_DCacheEnable( void );
void Xil_Out32( unsigned int registerAddress, int register value );
unsigned int  Xil_In32 ( unsigned int registerAddress );
//#include "usb20_per.h"
#include <stdint.h>  // uint32_t defined
unsigned int print( char *);
void init_platform( void );
// the set of struct definitions that follow
// are for the purpose of clearly defining
// the AIL4 programming interface.
// For the structs that are a series of bit fields,
// especially those that are write only, I strongly suggest
// keeping an image of the register in memory
// 1) update the image in memory
// 2) write the whole register at once to the device.
// interrupt control register
struct ICR_REG
{
    unsigned int RPURE:1;
    unsigned int RPORE:1;
    unsigned int RPUE :1;
    unsigned int TOPE :1;
    unsigned int TC   :1;
    unsigned int RC   :1;
    unsigned int TSE  :1;
    unsigned int TRC  :1;
    unsigned int RPC  :1;
    unsigned int TFPF :1;
    unsigned int TFPE :1;
    unsigned int RFPF :1;
    unsigned int RFPE :1;
    unsigned int ICR_Reserved:19;
};
// interrupt status register, write 1 to clear bit
struct ISR_REG
{
    unsigned int RPURE:1;
    unsigned int RPORE:1;
    unsigned int RPUE :1;
    unsigned int TOPE :1;
    unsigned int TC   :1;
    unsigned int RC   :1;
    unsigned int TSE  :1;
    unsigned int TRC  :1;
    unsigned int RPC  :1;
    unsigned int TFPF :1;
    unsigned int TFPE :1;
    unsigned int RFPF :1;
    unsigned int RFPE :1;
    unsigned int ISR_Reserved:19;
};
// interrupt enable register
struct IER_REG
{
    unsigned int RPUREE:1;
    unsigned int RPOREE:1;
    unsigned int RPUEE :1;
    unsigned int TOPEE :1;
    unsigned int TCE   :1;
    unsigned int RCE   :1;
    unsigned int TSEE  :1;
    unsigned int TRCE  :1;
    unsigned int RPCE  :1;
    unsigned int TFPFE :1;
    unsigned int TFPEE :1;
    unsigned int RFPFE :1;
    unsigned int RFPEE :1;
    unsigned int IER_Reserved:19;
};
// Transmit Data FIFO Reset Register write only with key 0x000000A5
struct TDFR_REG
{
    uint32_t tdfr;
};
// Transmit Dat FIFO Vacancy Register, read only, 0x1A5 means xmit fifo empty
struct TDFV_REG
{
    unsigned int TDFV_reserved :20;
    unsigned int TDFV_count    :12;
};
// Receive Data FIFO Reset Register, write only with key 0x000000A5
struct RDFR_REG
{
    uint32_t rdfr;
};
// Receive Data FIFO Occupancy Register, read only
struct RDFO_REG
{
    unsigned int RDFO_reserved :20;
    unsigned int RDFO_count    :12;
};
// Receive Data FIFO Data Read Port, read only
struct RDFD_REG
{
    uint32_t rdfd;
};
// Transmit Length Register -- starts the actual xmit operation
struct TLR_REG
{
    unsigned int TLR_reserved :24;
    unsigned int TLR_byteCount:15;
};
// Receive Length Register, read only
// note diagram and text in AXI4 pdf conflict for field sizes
//      for store and forward mode
struct RLR_REG
{
    unsigned int RLR_reserved :24;
    unsigned int RLR_byteCount:15;
};
// AXIR Stream Reset Register, write only key= 0x000000A5
struct SSR_REG
{
    uint32_t ssr;
};
// Transmit Destination Register, write only
struct TDR_REG
{
    unsigned int TDR_reserved    :28;
    unsigned int TDR_destination :4;
};
// Receive Destination Register write only
struct RDR_REG
{
    unsigned int RDR_reserved   :28;
    unsigned int RDR_destination:4;
};
// TX ID Register, read only
struct TX_ID_REG
{
    uint32_t tx_id_reg;
};
// TX USER Register, read only
struct TX_USER_REG
{
    uint32_t tx_user_reg;
};
// RX_ID_Register, read only
struct RX_ID_REG
{
    uint32_t rx_id_reg;
};
// RX_USER_Register, read only
struct RX_USER_REG
{
    uint32_t rx_user_reg;
};
// Write Port Register, write only
struct WR_PORT_REG
{
    uint32_t wr_port_reg;
};
struct AXI4
{
    struct ISR_REG      isr;
    struct IER_REG      ier;
    struct TDFR_REG     tdfr;
    struct TDFV_REG     tdfv;
    struct WR_PORT_REG  tx_buf;
    struct TLR_REG      tlr;
    struct RDFR_REG     rdfr;
    struct RDFO_REG     rdfo;
    struct RLR_REG      rlr;
    struct SSR_REG      ssr;
    struct TDR_REG      tdr;
    struct RDR_REG      rdr;
    struct TX_ID_REG    tx_id;
    struct TX_USER_REG  tx_user;
    struct RX_ID_REG    rx_id;
    struct RX_USER_REG  rx_user;
    uint32_t            reserved[0x38];
};

#define SLCR_UNLOCK     (0xF8000008)
#define SLCR_UNLOCK_VAL (0xDF0D)
#define SLCR_LOCK       (0xF8000004)
#define SLCR_LOCK_VAL   (0x767B)
#define XSLCR_FPGA_RST_CTRL (0xF8000240)
#define ARRAY_LENGTH (16)
static uint32_t array_fifo_data[ARRAY_LENGTH] =
{
    0x0100,
    0x0302,
    0x0504,
    0x0706,
    0x0908,
    0x0B0A,
    0x0D0C,
    0x0F0E,
    0x0100,
    0x0302,
    0x0504,
    0x0706,
    0x0908,
    0x0B0A,
    0x0D0C,
    0x0F0E
}; //random sequence
struct AXI4_REG * pAXI4 = (struct AXI4_REG*)(0x43C00000);
int main()
{

    //uint32_t baseaddr_ber=0x43c00000;
    uint32_t baseaddr_fifo=0x43c10000;
    Xil_Out32(SLCR_UNLOCK, SLCR_UNLOCK_VAL); //
    Xil_Out32(XSLCR_FPGA_RST_CTRL, 0x0000000F);    //Reset FPGAx_OUT_RST
    Xil_Out32(XSLCR_FPGA_RST_CTRL, 0x00000000);    //Deassert the FPGAx_OUT_RST
    Xil_Out32(SLCR_LOCK, SLCR_LOCK_VAL);     //
    Xil_ICacheEnable();
    Xil_DCacheEnable();
    print("---Entering main---nr");
    init_platform();
    // what is the '1FC' ? there are no interrupt enable bits that low
    // why enable the receive interrupt? this code is not receiving anything
    //  Xil_Out32 & Xil_In32 (TOPEE, TCE)
    Xil_Out32(baseaddr_fifo+0x4, 0x0C0001FC); //IER //interrupt enable register
    Xil_Out32(baseaddr_fifo+0x2C,0x00000002); //TDR //transmit destination register

    uint32_t state;
    uint32_t i,val;

    state=0;
    while(1)
    { // note write FIFO contains room for 512 4byte entries
        switch (state)
        {
            case 0: // waiting for AXI4 to have < 20 entries in write FIFO
                val = Xil_In32(baseaddr_fifo + 0x0c);
                if(val > 482) //check TDFV register value //transmit data fifo vacancy
                { // then less than 20 entries in write FIFO
                    state = 1;
                }
                break;
            case 1:
                // fill write FIFO buffer 
                do
                {
                    for(i=0;i<16;i++)
                    {
                        Xil_Out32(baseaddr_fifo + 0x10, array_fifo_data[i]); 
                    }
                    Xil_Out32(baseaddr_fifo+0x14, i*4); //TLR (transmit length register)
                    val = Xil_In32(baseaddr_fifo + 0x0c);
                } while (val > 16 ); // assure room for another 16 entries to write FIFO
                state=0; // indicate now waiting for transmit buffer to contain < 20 bytes
                break;
        } // end switch
    }  // end while
} // end function: main

最新更新