
FIFO (Primero en Entrar, Primero en Salir) es un método de almacenamiento de datos en el que el primer dato escrito en un búfer es también el primer dato leído. El principio de funcionamiento es similar a una cola. Los datos ingresan al búfer en un orden específico y permanecen almacenados hasta que son leídos. Los datos más antiguos siempre salen del búfer primero, mientras que los datos más nuevos esperan detrás de ellos.
En los sistemas FPGA y ASIC, FIFO se utiliza comúnmente como un área de almacenamiento temporal entre circuitos que producen datos y circuitos que consumen datos. En lugar de enviar datos directamente de un bloque a otro, los datos entrantes se almacenan primero en el FIFO. El circuito receptor luego lee los datos almacenados cuando está listo. Este enfoque ayuda a mantener un flujo de datos continuo y confiable.
A diferencia de la memoria ordinaria, FIFO no requiere líneas de dirección externas para seleccionar ubicaciones de almacenamiento. Durante una operación de escritura, los datos entrantes se colocan automáticamente en la siguiente ubicación disponible en el búfer. Durante una operación de lectura, los datos almacenados más antiguos se recuperan automáticamente y se envían a la salida.
Este proceso es gestionado por punteros de escritura y punteros de lectura internos. Cuando se escriben nuevos datos, el puntero de escritura se mueve a la siguiente ubicación de almacenamiento. Cuando se leen datos, el puntero de lectura avanza al siguiente elemento disponible. Debido a que estos punteros operan automáticamente, FIFO requiere menos lógica de control que la memoria convencional.
La desventaja es que los datos solo se pueden acceder de forma secuencial. A diferencia de la RAM, FIFO no puede acceder directamente a una ubicación de almacenamiento específica. Cada operación de lectura sigue el orden exacto en el que los datos fueron escritos originalmente.
FIFO se utiliza ampliamente cuando diferentes partes de un sistema operan a diferentes velocidades. En muchas aplicaciones, un dispositivo genera datos continuamente mientras que otro dispositivo procesa o transmite esos datos a una velocidad más lenta. Sin almacenamiento temporal, los datos entrantes pueden llegar más rápido de lo que se pueden manejar, lo que provoca la pérdida de información.
Por ejemplo, un convertidor analógico a digital (ADC) puede generar continuamente muestras digitales mientras que un procesador, bus PCI o interfaz de comunicación procesa esas muestras a una velocidad diferente. Un FIFO actúa como un búfer intermedio que almacena los datos entrantes y los libera cuando el circuito receptor está listo. Esto permite que ambos lados del sistema operen de manera independiente sin perder información.
FIFO también puede resolver desajustes en el ancho de datos entre dispositivos. En algunos sistemas, un dispositivo puede emitir datos de 8 bits mientras que otro espera datos de 16 bits. La comunicación directa puede requerir lógica de conversión adicional para reorganizar los datos.
Un FIFO puede simplificar este proceso almacenando temporalmente los datos entrantes y presentándolos en un formato que coincida con el dispositivo receptor. Esta capacidad ayuda a diferentes bloques de hardware a intercambiar datos de manera eficiente mientras reduce la complejidad de la interfaz.
Las estructuras FIFO se dividen generalmente en FIFO síncrono y FIFO asíncrono.
Un FIFO síncrono utiliza una única señal de reloj para las operaciones de lectura y escritura. Debido a que todas las actividades ocurren bajo la misma fuente de reloj, las relaciones de temporización son más fáciles de gestionar y verificar. Los FIFOs síncronos se utilizan comúnmente cuando los datos permanecen dentro de un único dominio de reloj.
Un FIFO asíncrono utiliza relojes separados para la escritura y la lectura. Los datos pueden entrar en el FIFO utilizando una frecuencia de reloj y salir utilizando otra. Dado que los dos relojes operan de manera independiente, los FIFOs asíncronos se utilizan ampliamente para transferir datos entre diferentes dominios de reloj.
Esta capacidad es especialmente importante en sistemas FPGA donde los procesadores, interfaces de comunicación, controladores de memoria y dispositivos periféricos a menudo operan a diferentes frecuencias.
El funcionamiento fiable del FIFO depende de conocer cuántos datos se almacenan actualmente en el buffer. Si nuevos datos siguen llegando después de que el FIFO alcance su capacidad, la información válida puede ser sobrescrita. Del mismo modo, intentar leer datos de un FIFO vacío produce resultados no válidos.
Para prevenir estas condiciones, los diseños de FIFO utilizan varias señales de estado.
La señal de lleno indica que todas las ubicaciones de almacenamiento disponibles están ocupadas y no se pueden escribir datos adicionales. La señal de vacío indica que no quedan datos válidos disponibles para la lectura.
Muchas implementaciones de FIFO también proporcionan indicadores de casi lleno y casi vacío. Estas señales actúan como advertencias tempranas antes de que el FIFO alcance una condición completamente llena o completamente vacía. La lógica de control puede utilizar estas señales para ralentizar, detener o ajustar las transferencias de datos antes de que ocurra un desbordamiento o una subcarga.
Debido a que estos indicadores de estado afectan directamente la integridad de los datos y la fiabilidad del sistema, son una parte esencial del diseño de FIFO.
Las estructuras FIFO se dividen generalmente en FIFO de Reloj Único (SCFIFO) y FIFO de Reloj Doble (DCFIFO). Estas estructuras están diseñadas para soportar diferentes relaciones de reloj y requisitos de transferencia de datos.
Las estructuras FIFO más comunes incluyen:
• SCFIFO (FIFO de Reloj Único)
• DCFIFO (FIFO de Reloj Doble)
• DCFIFO de Anchos Mezclados (FIFO de Reloj Doble con diferentes anchos de datos de lectura y escritura)
En la mayoría de la documentación de FPGA, los FIFOs de reloj doble estándar y los FIFOs de reloj doble de anchos mezclados se categorizan como FIFOs de reloj doble a menos que se requiera una distinción.

La selección de una estructura FIFO depende principalmente de cómo entran y salen los datos del buffer. La relación entre el reloj de escritura y el reloj de lectura suele ser el factor más importante al elegir la arquitectura FIFO adecuada.
Un FIFO de Reloj Único utiliza una señal de reloj para controlar tanto las operaciones de escritura como de lectura. Debido a que ambos procesos operan dentro del mismo dominio de reloj, el control de temporización es relativamente sencillo y se minimizan los problemas de sincronización.
Cuando llegan datos válidos a la entrada del FIFO y se afirma una solicitud de escritura, los datos se almacenan en la siguiente ubicación de memoria disponible en el flanco activo del reloj. A medida que llegan más datos, el puntero de escritura sigue avanzando a través del área de almacenamiento del FIFO.
Cuando se afirma una solicitud de lectura, el FIFO recupera los datos almacenados más antiguos y los coloca en la salida. El puntero de lectura avanza entonces a la siguiente ubicación almacenada. Este movimiento continuo de los punteros de lectura y escritura permite que los datos fluyan a través del FIFO en el orden correcto.
Los FIFOs de reloj único también proporcionan varias señales de estado que ayudan a monitorear las condiciones del buffer. La señal de lleno indica que todas las ubicaciones de almacenamiento están ocupadas y deben detenerse las escrituras adicionales. La señal de casi lleno advierte que el FIFO se está acercando a su capacidad.
La señal de vacío indica que no quedan datos válidos en el buffer, mientras que la señal de casi vacío advierte que solo queda una pequeña cantidad de datos. Muchas implementaciones también incluyen un contador de palabras utilizadas, que informa cuántos datos se almacenan actualmente en el FIFO.
Estos indicadores permiten que la lógica circundante tome decisiones seguras de lectura y escritura mientras se mantiene un funcionamiento fiable del FIFO.
Un FIFO de Reloj Doble utiliza relojes separados para las operaciones de escritura y lectura. El lado de escritura opera dentro de un dominio de reloj, mientras que el lado de lectura opera dentro de otro.
Los datos entrantes se escriben en el FIFO utilizando el reloj de escritura. Una vez almacenados, los datos permanecen dentro del buffer hasta que el lado de lectura los recupera utilizando el reloj de lectura. Dado que los dos relojes son independientes, el FIFO puede transferir datos de manera segura entre diferentes dominios de reloj.
Esta capacidad convierte a los FIFOs de reloj doble en una de las soluciones más comunes para el cruce de dominios de reloj en sistemas FPGA.
Para soportar un funcionamiento fiable, los FIFOs de doble reloj proporcionan señales de estado para ambos lados de la interfaz. El lado de escritura comúnmente utiliza señales como wrfull y wrempty para indicar las condiciones del búfer del lado de escritura. El lado de lectura comúnmente utiliza rdfull y rdempty para indicar la disponibilidad de datos para la lectura.
También se suelen proporcionar contadores separados para que cada dominio de reloj pueda monitorear la cantidad de datos almacenados de manera independiente. Estos indicadores permiten que ambos lados del FIFO tomen decisiones sin interferir entre sí.
Algunas aplicaciones requieren diferentes anchos de datos en el lado de escritura y en el lado de lectura del FIFO. En estas situaciones, se puede utilizar un FIFO de Doble Reloj de Ancho Mixto.
Por ejemplo, los datos pueden escribirse en el FIFO como palabras de 16 bits pero leerse como palabras de 8 bits. El FIFO reorganiza automáticamente la información almacenada y realiza la conversión de ancho requerida mientras preserva la secuencia de datos original.
Esta característica es útil al conectar dispositivos que utilizan diferentes anchos de bus. En lugar de agregar circuitos de conversión separados, el FIFO maneja la adaptación de ancho internamente.
Un FIFO de Reloj Único se utiliza generalmente cuando tanto la lectura como la escritura ocurren dentro del mismo dominio de reloj. Su arquitectura más simple facilita el análisis de temporización y la implementación.
Un FIFO de Doble Reloj es preferido cuando los datos deben moverse entre dominios de reloj independientes. Proporciona un cruce de dominio de reloj fiable y ayuda a eliminar problemas de sincronización.
Cuando se requieren tanto el cruce de dominio de reloj como la conversión de ancho de datos, un FIFO de Doble Reloj de Ancho Mixto proporciona una solución eficiente al combinar ambas funciones dentro de una única estructura FIFO.
FIFO actúa como un área de almacenamiento temporal entre diferentes partes de un sistema digital. En muchas aplicaciones, los datos no llegan y salen a la misma velocidad. Un dispositivo puede generar datos continuamente, mientras que otro dispositivo puede procesar o transmitir esos datos a un ritmo más lento. Sin un búfer entre ellos, los datos entrantes pueden acumularse más rápido de lo que se pueden manejar, lo que lleva a la pérdida de datos.
Un FIFO resuelve este problema almacenando datos a medida que llegan y liberándolos cuando el circuito receptor está listo. Esto crea un flujo de información más suave y permite que diferentes partes del sistema operen de manera más eficiente sin requerir una coordinación de temporización perfecta.
Más allá del simple almacenamiento en búfer, FIFO también ayuda a mejorar el rendimiento general del sistema. Al colectar datos temporalmente antes de la transferencia, FIFO reduce el número de operaciones de acceso al bus y minimiza la sobrecarga de comunicación innecesaria. Esto permite que los recursos del sistema se utilicen de manera más eficiente.
FIFO también puede reducir la carga de trabajo del procesador. En lugar de forzar a la CPU a manejar cada transferencia de datos individualmente, los datos pueden acumularse en el FIFO y procesarse en bloques más grandes. Este enfoque mejora la eficiencia y libera recursos del procesador para otras tareas.
Otro beneficio importante es el soporte para operaciones de Acceso Directo a Memoria (DMA). En sistemas de alta velocidad, DMA permite que los datos se muevan directamente entre periféricos y memoria sin la constante participación de la CPU. FIFO proporciona el almacenamiento temporal necesario para soportar estas transferencias y mantener un flujo de datos continuo.
Sin el almacenamiento en búfer FIFO y el soporte DMA, el procesador puede dedicar una cantidad significativa de tiempo a gestionar el movimiento de datos, lo que puede reducir el rendimiento general del sistema e incrementar el riesgo de cuellos de botella en la transmisión.
Un FIFO de Reloj Único se utiliza típicamente cuando tanto la operación de escritura como la operación de lectura están controladas por la misma señal de reloj. Debido a que ambos lados del FIFO operan dentro del mismo dominio de reloj, la gestión del tiempo es más sencilla y los problemas de sincronización son más fáciles de evitar.
Una aplicación común es la adquisición de datos de sensores. En muchos sistemas, un sensor puede generar datos mucho más rápido que la interfaz de comunicación responsable de transmitir esos datos a otro dispositivo.
Por ejemplo, un FPGA puede recopilar datos de un sensor a través de una interfaz SPI de alta velocidad. Cada muestra de sensor llega rápidamente y debe almacenarse de inmediato para evitar la pérdida de información. Al mismo tiempo, los datos recopilados pueden necesitar ser transmitidos a través de una interfaz UART que opera a una velocidad de baudios mucho más baja.
A medida que los datos del sensor ingresan al FPGA, se escriben directamente en el FIFO. Los datos almacenados luego esperan dentro del búfer mientras la UART los transmite gradualmente a su propia velocidad. A medida que los datos salen del FIFO, nuevas muestras de sensor continúan entrando en el búfer. Este proceso continuo de escritura y lectura permite que ambos lados del sistema operen a diferentes tasas de datos mientras permanecen sincronizados por la misma fuente de reloj.
Al absorber las diferencias temporales de velocidad entre la recolección de datos y la transmisión de datos, un FIFO de un solo reloj ayuda a mantener un flujo de datos estable y previene la pérdida de datos.
Un FIFO de Doble Reloj está diseñado para sistemas en los que el lado de escritura y el lado de lectura operan con diferentes señales de reloj. Esta situación es común en los diseños de FPGA porque muchos bloques funcionales funcionan a diferentes frecuencias y requisitos de temporización.
Cuando los datos se mueven de un dominio de reloj a otro, las conexiones directas pueden crear problemas de sincronización. Los datos pueden llegar demasiado pronto, demasiado tarde o durante ventanas de temporización inestables, lo que lleva a un funcionamiento poco confiable.
Un FIFO de doble reloj proporciona un límite seguro entre los dos dominios de reloj. Los datos entrantes se escriben en el FIFO utilizando el reloj de origen. Una vez almacenados, los datos permanecen en el búfer hasta que el lado de destino los lee utilizando su propio reloj. El FIFO gestiona internamente el proceso de transferencia para que ambos dominios de reloj puedan operar de forma independiente.
Un sistema de procesamiento de video proporciona un buen ejemplo. Una cámara puede capturar datos de imagen utilizando una frecuencia de reloj, mientras que un controlador VGA emite datos de imagen utilizando una frecuencia de reloj diferente. A medida que la cámara genera datos de imagen, se escriben continuamente en el FIFO. El controlador VGA luego lee los datos de imagen almacenados a la tasa requerida para la salida de visualización.
Debido a que el reloj de escritura y el reloj de lectura son completamente independientes, el FIFO actúa como un puente entre los dos sistemas de temporización. Esto permite que los datos de imagen se muevan de manera confiable desde la interfaz de la cámara hasta la interfaz de visualización sin errores de sincronización.
Por esta razón, los FIFOs de doble reloj se utilizan ampliamente para el cruce de dominios de reloj, la transferencia de datos de alta velocidad, los sistemas de procesamiento de video, las interfaces de comunicación y otras aplicaciones donde los datos deben moverse entre entornos de temporización independientes.
Los dispositivos FPGA de Altera proporcionan varias formas de implementar la funcionalidad FIFO. El mejor método depende de los requisitos de diseño, el cronograma de desarrollo y el nivel de personalización necesario.
En la mayoría de los proyectos, el objetivo es el mismo. Se debe agregar un FIFO entre dos bloques funcionales para que los datos puedan ser almacenados temporalmente, transferidos de manera confiable y procesados a la velocidad requerida. La diferencia radica en cómo se crea e integra el FIFO en el diseño de la FPGA.
Tres métodos de implementación comunes se utilizan ampliamente en el desarrollo de FPGA de Altera.
El primer método es construir un FIFO directamente utilizando código RTL (Nivel de Transferencia de Registro).
En este enfoque, el diseñador crea la estructura completa del FIFO, incluyendo la matriz de memoria, el puntero de lectura, el puntero de escritura, la lógica de detección de lleno, la lógica de detección de vacío y los circuitos de control. Cada parte de la operación del FIFO se define manualmente dentro del código HDL.
Este método proporciona el mayor nivel de flexibilidad. La profundidad del FIFO, el ancho de los datos, las banderas de estado y el comportamiento de control se pueden personalizar para coincidir con los requisitos específicos de la aplicación. También se pueden agregar características adicionales si las implementaciones estándar de FIFO no proporcionan la funcionalidad requerida.
Sin embargo, desarrollar un FIFO desde cero requiere un sólido entendimiento de la arquitectura del FIFO, el análisis de temporización y las técnicas de diseño de FPGA. También se necesita más verificación y pruebas para asegurar un funcionamiento confiable bajo todas las condiciones.
Por esta razón, el desarrollo de FIFO personalizado suele reservarse para aplicaciones que requieren características especializadas o requisitos de rendimiento únicos.
El segundo método es utilizar un núcleo IP FIFO de código abierto o de terceros.
En lugar de diseñar el FIFO desde el principio, un módulo FIFO existente se importa al proyecto y se conecta a la lógica circundante. Dado que el código fuente a menudo está disponible, el diseño aún se puede modificar cuando se necesitan características o ajustes adicionales.
Este enfoque puede reducir significativamente el tiempo de desarrollo. Gran parte de la arquitectura del FIFO ya ha sido creada, probada y validada, lo que permite a los diseñadores centrarse en la integración del sistema en lugar de en el desarrollo de FIFO de bajo nivel.
Cuando los requisitos del proyecto difieren ligeramente del comportamiento estándar del FIFO, se puede editar el código fuente para admitir la funcionalidad deseada, evitando así el esfuerzo requerido para crear un diseño completamente nuevo de FIFO.
El método más común es usar los núcleos IP FIFO proporcionados por el software Quartus II.
Quartus II incluye generadores de FIFO integrados que permiten crear estructuras FIFO a través de una interfaz de configuración gráfica. En lugar de escribir manualmente la lógica FIFO, el diseñador selecciona los parámetros requeridos y deja que el software genere automáticamente la implementación.
Durante la configuración, se pueden definir varios ajustes importantes. Estos incluyen:
• Tipo FIFO (de reloj único o de doble reloj)
• Ancho de datos
• Profundidad FIFO
• Opciones de implementación de memoria
• Señales de estado de lleno y vacío
• Umbrales de casi lleno y casi vacío
• Configuraciones de reloj de lectura y escritura
Después de seleccionar los parámetros, Quartus II genera los archivos FIFO y la lógica de soporte necesaria para el diseño de FPGA.
Una vez que la configuración FIFO está completa, Quartus II crea automáticamente una implementación optimizada para el dispositivo Altera FPGA seleccionado.
El FIFO generado puede conectarse directamente a la lógica circundante. Los datos entrantes se conectan a la interfaz de escritura, los datos salientes se conectan a la interfaz de lectura, y las señales de estado se utilizan para controlar el flujo de datos en todo el sistema.
Dado que el diseño generado está optimizado para la arquitectura FPGA objetivo, la utilización de recursos es típicamente más eficiente que muchas implementaciones desarrolladas manualmente. El tiempo de desarrollo también se reduce porque gran parte del trabajo de diseño, verificación y optimización es manejado automáticamente por el software.
Para la mayoría de los proyectos de FPGA, el núcleo IP FIFO de Quartus II proporciona el camino más rápido y simple para implementar funcionalidad FIFO fiable, manteniendo un uso eficiente de los recursos de FPGA.
FIFO proporciona una forma sencilla y fiable de almacenar datos en búfer, igualar las tasas de transferencia y soportar la comunicación entre diferentes componentes del sistema. Al entender las arquitecturas FIFO, las señales de estado, la operación síncrona y asíncrona, y los métodos de implementación, los diseñadores pueden mejorar la integridad de los datos, prevenir condiciones de desbordamiento y subdesbordamiento, y construir sistemas digitales más eficientes.
Los búferes FIFO actúan como almacenamiento temporal entre circuitos que producen datos y circuitos que consumen datos. Cuando un dispositivo genera datos más rápido de lo que otro puede procesarlos, el FIFO almacena la información entrante y la libera cuando el dispositivo receptor está listo. Esto previene la pérdida de datos, mejora la fiabilidad del sistema y permite que ambos circuitos operen de manera independiente sin requerir una coincidencia perfecta de velocidad.
Los FIFOs asíncronos utilizan relojes separados para las operaciones de escritura y lectura, permitiendo que los datos se muevan de forma segura entre dominios de reloj independientes. Esto previene problemas de temporización y sincronización que pueden ocurrir cuando las señales se transfieren directamente entre circuitos que funcionan a diferentes frecuencias. Como resultado, los FIFOs asíncronos se utilizan comúnmente en interfaces de comunicación, sistemas de video, procesadores y controladores de memoria.
Las señales de estado FIFO proporcionan información en tiempo real sobre el uso del búfer. Las señales de lleno y casi lleno advierten cuando el espacio de almacenamiento se está agotando, mientras que las señales de vacío y casi vacío indican cuando queda poco o ningún dato disponible. Estas señales permiten que la lógica de control ajuste las transferencias de datos antes de que ocurran errores, ayudando a mantener la integridad de los datos y un funcionamiento estable del sistema.
Los sistemas de video a menudo involucran dispositivos que operan a diferentes frecuencias de reloj, como cámaras y controladores de pantalla. Un FIFO de doble reloj almacena los datos de imagen entrantes utilizando un reloj y permite que se lean utilizando otro reloj. Esto crea un puente fiable entre los dos dominios de temporización y asegura la transferencia continua de imágenes sin errores de sincronización o corrupción de datos.
Los núcleos IP FIFO de Quartus II simplifican el desarrollo generando automáticamente lógica FIFO optimizada basada en configuraciones definidas por el usuario, como profundidad, ancho, tipo de reloj y señales de estado. Esto reduce el tiempo de diseño, minimiza el esfuerzo de verificación y a menudo proporciona una mejor utilización de recursos que las implementaciones codificadas manualmente, convirtiéndolo en la solución preferida para la mayoría de los proyectos de FPGA.
29/07/2024
28/08/2024
06/10/2024
04/07/2024
20/09/2025
22/04/2024
15/07/2024
28/12/2023
15/11/2024
15/09/2025









