Cypress FIFOs have two pointers that internally increment after each read or write operation. There is a write pointer that points to the next memory location to write data into and a read pointer that points to the memory location of the next word to be read. Whenever a read or write occurs, the respective pointer increments. When a pointer reaches the last memory location in the memory array, it loops back to the first location as long as the FIFO is not full. The flag logic is calculated using the relative positions between the read and write pointers. Full flag will be asserted when the difference between the read and write pointer is the maximum depth of the FIFO. Empty flag is asserted when the difference is zero. For example, if we start with a 1K x 8 FIFO, after a proper reset, both pointers will be aligned at the first memory location. If we write 1023 words into this FIFO with no reads, the read pointer will still be at the first location. If we were to write one more word, the FIFO would then be full. If we then read 1000 words out of the FIFO, the read pointer will be 4 spaces behind the write pointer and there would be room for another 1000 words. So on the next write operation, the write pointer will loop back to the first memory location. Needless to say, as long as you do not fill the FIFO to its depth (1024), you will be able to loop the pointers around endlessly.