Electronic – A simple FIFO buffer in verilog

bufferfpgahardwareverilog

I have decided to implement a FIFO buffer in verilog (for fun). Here is my primary prototype you can say :

  • It will consist of a register bank or memory.
  • Each register will be of size N and there will be M such registers / shift registers.
  • The registers support serial write and serial read only ie serial-in serial-out topology.
  • Two registers 'read' and 'write' will be used which act as enable signals.
  • A register 'writeLoc' is used which tells where data was last written to. Its size should be M. It is decremented with each write.
  • A register 'readLoc' is used which tells where data was last read from. Its size should be M. It is incremented with each read.

  • If readloc = writeloc,

    • if last operation was read, then buffer is empty.
    • if last operation was write, then buffer is full.
  • A register 'lastOp' is used to signify last operation. It is set whenever last write was sucessful. It is reset whenever last read was sucessful.

  • A register 'isEmpty' is used to signify that buffer is empty. It is set whenever buffer is empty.
  • A register 'isFull' is used to signify that buffer is full. It is set whenever buffer is full.

  • Experimental feature 1 : A register 'lock' can be used to prevent reading data while writing and vice versa. 'lock' is set whenever 'write' is set ie whenever data is being written. 'lock' is reset whenever no data is being written. The reader can read from buffer when 'lock' is reset. Likewise, the writer can write to buffer whenever lock is set.

However I have a few concerns :

1) Firstly, have I left out some critical component ? And is there some flaw so far ? Keep in mind it is meant to be a simple design, with 'essential' functionality.

2) My first concern is whether buffer full and empty conditions are correct or not. I have tried my best, but I'm not sure.

3) Can isEmpty and isFull registers be dispensed with ?

4) At the receiver end, the data can come any time. I feel that if I implement the lock feature, then if at the time when data is coming and lock is held by reader, data will be lost. On the other hand, lock is also necessary to prevent reading while writing and vice versa. Can you point me in the right direction as to how to overcome this problem ?

(Apologies if this question does not belong here. Please be kind enough to suggest appropriate place).

Best Answer

Your read pointer and write pointer both need to travel in the same direction. Generally they are incremented, but decrementing also works, so long as you do the same for both. One method for full/empty detection is to use M+1 bit registers for the read and write pointer. If all M+1 bits match, then the FIFO is empty. However, if all bits match except the MSB, then the FIFO is full. Presuming you use a true dual port memory for storage (i.e. an FPGA block RAM), no locking is necessary as dual port RAM supports simultaneous reading and writing. No need for any isEmpty and isFull registers or a lastOp register if you can glean all of that information from the read and write pointers with simple combinatorial logic. However, you will need logic to prevent the write pointer from being changed when the FIFO is full or the read pointer from being changed when the FIFO is empty.