FPGA makes simple FIFO
Luis Miguel Brugolaras, SIRE, Madrid, Spain -- EDN, 10/26/2000
The circuit in Figure 1 is an FPGA-based, synchronous FIFO that uses the same clock for read and write operations. The circuit can generate FIFO-occupancy flags with a minimum of logic. The boxed area in Figure 1 shows a more conventional occupancy meter. The circuit is implemented in a demultiplexer that writes data in the FIFO when the data arrives and reads data according to FIFO occupancy. The circuit uses a Xilinx Spartan (XC4000 equivalent) FPGA. The method uses three main blocks: a 16-bit dual-port RAM macro, read- and write-address counters, and the flag processor. In this design, the FIFO is 4 bits deep but can be as great as 16 bits deep using the RAM16X1D macro. Read and write counters can take the form of any cyclic counter, a conventional binary counter, a Gray-code counter, or a linear-feedback shift register. FIFOs commonly use Gray-code counters. These counters have the property that only one bit changes from state to state. Thus, they have the advantage of not providing intermediate false states when the counter advances. For example, a binary counter moving from 0111 to 1000 changes all its bits but with different delays and thus can fool asynchronous comparison logic. Linear-feedback shift registers have the advantage of requiring modest logic resources and can work at high clock rates. They pose one small inconvenience, however: For an n-stage shift register, only 2n–1 states exist.You can read FIFO occupancy in an orthodox way, by using an up/down counter controlled by read- and write-enabled clocks (Figure 2). This method makes the counter advance up when the FIFO is written to but not read, advance down when the FIFO is read but not written to, and remain unchanged otherwise. Such an arrangement leads to full knowledge of FIFO occupancy, a valuable asset during debugging. For example, you can use a DAC to convert the occupancy data and monitor it with an oscilloscope. In this application (Figure 1), it was necessary to keep logic to a minimum. We simply needed to know whether the FIFO was full (to avoid loss of data in a write attempt), or empty; hence, the application needed just Full and Empty flags. The addresses of the read and write pointers are equal only when the FIFO is either full or empty. These states are distinguishable because, before the FIFO became full, a write operation occurred after no previous read operation. A flip-flop qualifies this status by latching data only when a read or write attempt occurs. The flip-flop latches a high level when a write operation (but not a read operation) occurs, indicating an attempt to increment the FIFO's occupancy.
















