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.
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
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
User contributions licensed under CC BY-SA 3.0