FIFO (for buffering input data) - Project-Bonfire/Bonfire GitHub Wiki
First-In-First-Out (FIFO)
Specifications
-
FIFO is part of the data-path of the router, but it also has a control part itself.
-
Used for storing flits, which is tied to the flow control mechanism (credit-based flow control).
-
DATA_WIDTH specifies the size of the flits.
-
Depth of the FIFO is fixed to 4 slots (each slot is able to store one flit), however only 3 slots are actually usable.
-
For each input port, a FIFO module exists in the router (in total 5 FIFO modules).
-
FIFO gets its data input from the RX input interface of the router, which is as wide as the DATA_WIDTH (customizable).
-
Each FIFO has read_en signals from all output ports (coming from the allocator unit), except for itself. This means that for example, for North FIFO, read_en_N is always connected to logic zero. The read_en is basically is fed from the Grant signals generated by allocator.
-
FIFO is in charge of part of the credit-based flow control, providing credit_out output signal which goes to the previous router/NI and receiving valid_in input signal, coming from previous router/NI, which shows the data sent to the router (and FIFO) is actually valid.
-
Reading from FIFO is done via a read pointer. Writing to FIFO is performed via a write pointer. Both pointers are one-hot.
-
Each time a data is read from FIFO (to be forwarded to the next router/NI), read pointer gets one bit rotated to left (gets updated). This occurs in a circular manner. The same principle applies to the write pointer, but that pointer gets updated whenever a data is written in FIFO.
-
Empty signal (one of the output signals of FIFO) goes high when read pointer and write pointer, point to the same location (they are equal). Therefore, initially, when the router is also reset, FIFO is empty.
-
FIFOβs reset is active low, that means, when reset is β0β, the reset action happens.
-
The sequential part of FIFO is sensitive to the positive edge of clock.
On reset (which can occur asynchronously from the clock):
- Read pointer gets initialized to β0001β (pointing to the first location slot of FIFO).
- Write pointer gets initialized to β0001β (pointing to the first location slot of FIFO).
- All FIFO slots (named as FIFO_MEM_i (I=1,2,3,4)) are initialized to zero value.
- credit_out signal is initialized to zero (initially no credit is given to previous router/NI).
In the clock process of FIFO (at rising edge of clock):
- Write pointer gets its new value (since it is a register).
- Read pointer gets its new value (since it is a register).
- credit_out signal gets βzeroβ value (no credit given to previous router/NI).
- if write_en is high (data can be written to FIFO), the input values of FIFO_MEM_i get written into the FIFO slots.
- If read_in is high (data can be read from FIFO), credit_out signal is set to β1β (credit is given to previous router/NI).
How read_en signal is generated : depends on the values of all read_en signals coming from the allocator unit (for different outputs) and also it depends on the value of empty signal. Read_en becomes activated (1) if there is a grant at least from one of the outputs and (2) if the FIFO is actually not empty.
If write_en is high, write pointer must get updated (rotated one bit to the left):
- write_pointer_in <= write_pointer(2 downto 0)&write_pointer(3);
Otherwise, it should preserve its previous value:
- write_pointer_in <= write_pointer;
If read_en is high and FIFO is not empty, read pointer must get updated (rotated one bit to the left):
-
read_pointer_in <= read_pointer(2 downto 0)&read_pointer(3);
Otherwise, it should preserve its previous value:
-
read_pointer_in <= read_pointer;
If the data on the input of FIFO (RX) is valid, which means that valid_in is high, and also if the FIFO is not full, write_en becomes β1β, otherwise, it must stay β0β.
Empty becomes one when :
- read_pointer = write_pointer Otherwise, it stays zero.
Full signal becomes one when :
- write_pointer = read_pointer(0)&read_pointer(3 downto 1) then (Write pointer is pointing to the one location slot after read pointer) Otherwise, it stays zero.
Based on the value of write pointer, RX gets stored in the FIFO slot that write pointer is pointing to (write pointer is always one-hot, therefore, one bit is only set to one).
Based on the value of read pointer, the value of the data stored in the location that write pointer is pointing to it is sent to the Data_out output of FIFO (which is of width DATA_WIDTH) (read pointer is always one-hot, therefore, one bit is only set to one). Data_out output of FIFO goes to the XBAR, which later would be connected to the output port of the router.