我正在使用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页,寄存器空间显示我在上面的代码中使用的寄存器的基地址和偏移地址。
我真的很感谢你的帮助。
从我的代码中,我可以看到FIFO正在工作并传输我在代码中输入的顺序随机数据,但是这个过程不是连续的,它在传输数据后停止,它应该重复这个过程并继续它应该永远不会停止,就像一个循环。
Kinly打开下面的链接,查看模拟的波形结果。您将看到fifo工作,它传输完整的随机序列,然后停止,我期望重复传输随机序列。
https://www.dropbox.com/sh/nydws0v5yjyphj3/AAAg_l7aEvUG3gEzhYedwgWra?dl=0
答案 0 :(得分: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