La FIFO circular es una estructura de datos basada en la cinta circular, es decir, un arreglo en el que al último elemento listado le sigue el primer elemento.

En la FIFO circular se considera que el primer elemento listado es el frente ó HEAD de la fila. En tanto que el último elemento ingresado en la fila se encuentra en la cola ó TAIL.
Head Tail



contenido

  1. ...


El módulo FIFO, descrito a continuación, tiene dos propiedades que implican el ancho de palabra DATA_WIDTH y la profundidad FIFO_DEPTH. La variable DATA_WIDTH define el tamaño de la palabra que almacenará la FIFO así como el ancho del bus de entrada DataIn y el ancho del bus de salida DataOut. La variable FIFO_DEPTH determina la cantidad de palabras almacenables en la FIFO.

La variable índice Head es usada para indicar el frente de la fila (el primer elemento ingresado) y la variable índice Tail es usada para indicar la cola de la fila (el último elemento ingresado).

La señal empty se enciende cuando la cinta está vacía. Esto es, cuando la pila arranca y cuando los índices Head y Tail coincíden.



Formalmente, la FIFO circular se define como la 10-tupla

AFD = { QT , ΣIT , ΓT , δ , {q0} , Χ , Head , Tail }

donde:

QT = { q0 } Estados. La fila solamente tiene un estado.
ΣIT Alfabeto de símbolos contables.
ΓT Reglas de acceso.
q0 ∈ QT Estado único de la cinta.
Χ ∈ Σ*IT Contenido inicial de la cinta.
Tail ∈ ΣIT Cabezal de escritura.
Head ∈ ΣIT Cabezal de lectura.



El hecho de tener dos cabezales implica que dos aplicaciones independientes pueden mover los cabezales al mismo tiempo. Mediante un bloque process se puede secuenciar los accesos.

Las reglas de acceso son únicamente dos:

Write & move to left WL Toma un dato colocado en el bus DataIn,
escribe en la cinta de la FIFO y
mueve el cabezal Tail un lugar
Read & move to left RL Copia un dato de la cinta en el bus data Out
y mueve el cabezal Head un lugar.


Se debe tener cuidado de que este cabezal no rebace al cabezal de escritura.


Si ambos cabezales coinciden en posición se considera que la FIFO está vacía y la señal empty se enciende. En el caso de que los cabezales no coincidan en posición se considera que hay elementos escritos en la fila y por tanto la señal se apaga.

El algoritmo propuesto permite que el cabezal Head rebase al cabezal Tail .


Para escribir datos en la FIFO, primero se coloca un dato en el bus DataIn, luego se coloca un uno en el terminal WriteEn. Entonces, cuando llegue la transición positiva del pulso de reloj, se transferirá el dato a la FIFO. Luego el cabezal Tail se avanza un lugar.

Para realizar una escritura en ráfaga, se deja este terminal en alto, de tal forma que en cada transición positiva del reloj se realiza una escritura de un dato puesto en DataIn, en la FIFO.

Una vez que un dato es escrito en la FIFO, la terminal Empty es puesta en cero.

Se debe ener cuidado ya que la cinta circular no desborda, más se soreescribe su contenido.

Para una FIFO estándar, cuando se escribe el primer dato, éste no se ve en el bus de salida DataOut sino hasta que la señal ReadEn se habilita en alto y ocurre una transición positiva del reloj. Entonces el cabezal Head se avanza un lugar.

Si se desea leer datos en ráfaga, la terminal ReadEn se deja en alto y entonces, se verá un dato nuevo en el bus DataOut con cada transición positiva del reloj.

Una vez que el último dato ha salida de la FIFO, la terminal Empty se pone en alto: esto implica que el cabezal head ha lacanzado al cabezal Tail. Se debe tener cuidado ya que el cabezal Head puede rebasar al cabezal Tail.
.

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

--Circular FIFO

entity FIFO is
	Generic (
		constant DATA_WIDTH  : positive := 8;
		constant FIFO_DEPTH  : positive := 64
	);
	Port ( 
		clk50MHz	:  in STD_LOGIC;
		reset		:  in STD_LOGIC;
		WriteEn		:  in STD_LOGIC;
		DataIn		:  in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
		ReadEn		:  in STD_LOGIC;
		DataOut		: out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
		Empty		: out STD_LOGIC
	);
end entity FIFO;


Architecture Behavioral of FIFO is
begin
 
	-- Memory Pointer Process
	fifo_proc : process (CLK,reset)
		type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR ( DATA_WIDTH - 1 downto 0 );
		variable Memory : FIFO_Memory;
		
		variable Head : natural range 0 to FIFO_DEPTH - 1:=0;
		variable Tail : natural range 0 to FIFO_DEPTH - 1:=0;
		
		variable Looped : boolean;
	begin

		if reset='1' then
				Head := 0;
				Tail := 0;
				Empty <= '1';			
		elsif clk50MHz'event and clk50MHz='1' then

			if (WriteEn = '1') then
				-- Write Data to Memory
				Memory(Tail) := DataIn;
					
				-- Increment Head pointer as needed
				if (Tail = FIFO_DEPTH - 1) then
					Tail := 0;
				else
					Tail := Tail + 1;
				end if;
					
				-- Update Empty and Full flags
				Empty<='0';
			end if;

			if (ReadEn = '1' and Head /= Tail) then
				-- Update data output
				DataOut <= Memory(Head);
					
				-- Update Tail pointer as needed
				if (Head = FIFO_DEPTH - 1) then
					Head := 0;
				else
					Head := Head + 1;
				end if;
				
				-- Update Empty and Full flags
				if (Head = Tail) then
					Empty<='1';
				end if;	
			end if;
						
		end if;
	end process fifo_proc;
		
end architecture Behavioral;