trying to make continuous FIFO data stream

0

I am using XILINX ZC702 FPGA with Vivado 2014.3 along with SDK (software development kit).

I want to create FIFO data stream, which is not less than 20 i.e. under flow and not higher than 500 i.e. over flow. I have used AXI4 Stream FIFO IP for this purpose, in order to make the code work, I have to use registers which can be find in the datasheet for the axi stream fifo pasted below.

If the FIFO data reaches 500, then it should stop loading new data, If the FIFO data reaches 20, then it should fill new data until it gets to 500. This process should repeat all the time.

I made a test procedural in software development kit for fifo, in order to see the simulated waveform results through hardware. What I observe is that the FIFO data is not continuous. I need to have it in continuous mode, it should never stop, It should be like a loop.

Below please find the c code

#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---\n\r");
    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;
        }
    }
}

Below, there is a link for the datasheet of axi strem fifo IP. Page # 7, trasnmit a packet and Page # 23, register space shows the baseaddress and offset address of the registers I have been using in the code above.

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

I would really appreciate your help.

From the code I made, I can see the FIFO working and transmitting the sequential random data I put in the code, but the process is not continuous, it stops after transfering the data, it should repeat the process and keep on continuing it, it should never stop, like a loop.

Kinly open the link below to see the simulated waveform results. You will see that the fifo works, it transmits the complete random requence and after that it stops, I am expecting to repeatedly transmit the random sequence.

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

c
sdk
fpga
xilinx
fifo
asked on Stack Overflow Dec 17, 2014 by Sultan • edited Jan 2, 2015 by Sultan

1 Answer

1
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---\n\r");
    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
answered on Stack Overflow Dec 18, 2014 by user3629249 • edited Dec 18, 2014 by user3629249

User contributions licensed under CC BY-SA 3.0