我将XILINX ZC702 FPGA与Vivado 2014.3以及SDK(软件开发套件)一起使用。
我想创建FIFO数据流,该数据流不少于20,即流量不足,但不高于500,即流量超过。为此,我使用了AXI4流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---\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;
}
}
}
下面是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---\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