Tengo una placa DE1-SoC que contiene 1 MSPS ADC, estoy tratando de tomar muestras de ADC y procesarlas. El reloj del controlador ADC es de 20 MHz y los datos están disponibles cada 16 ciclos de reloj. El módulo que toma muestras funciona con un reloj de 100 MHz. El problema es ¿cómo puedo interconectar estos dos módulos?
Mi primer pensamiento fue usar un FIFO asíncrono, pero después de la búsqueda descubrí que ¡es imposible! El reloj de escritura es mucho más lento que el lado de lectura. Encontré una fórmula para calcular la profundidad del FIFO ( here ) pero falló, ¡dándome una respuesta negativa! No sabía cuál era mi "ráfaga", así que asumí que era 1 ya que el controlador da una muestra cada 16 ciclos de reloj.
Entonces, ¿tienes alguna idea de cómo resolver este problema?
Normalmente, los FIFO se autocontrolan para evitar desbordamientos y subdesbordamientos. Esto se hace implementando un control de flujo hacia adelante y hacia atrás. El control de flujo directo significa que las palabras de datos se marcan como válidas en FIFO para que el lado de lectura pueda distinguir las palabras válidas de las no válidas. El control de flujo hacia atrás se logra exportando el estado de llenado de un FIFO al lado de escritura. Si el FIFO está lleno, crea una señal de "lleno" que le indica al escritor que puede manejar más datos.
En su caso, el ADC está transmitiendo datos a una velocidad constante, por lo que debe dimensionar el FIFO correctamente para evitar un desbordamiento.
Debido a que la velocidad de lectura es más rápida que la velocidad de escritura y la longitud de la ráfaga de escritura es una, no necesita preocuparse por la profundidad FIFO o la longitud de la ráfaga y los desbordamientos. Tenga en cuenta que los FIFO de reloj cruzado tienen una profundidad mínima, por ejemplo, 3 palabras.
Echemos un vistazo a una interfaz FIFO común:
entity fifo_ic_got is
generic (
D_BITS : positive; -- Data Width
MIN_DEPTH : positive -- Minimum FIFO Depth
);
port (
-- Write Interface
clk_wr : in std_logic;
rst_wr : in std_logic;
put : in std_logic;
din : in std_logic_vector(D_BITS-1 downto 0);
full : out std_logic;
-- Read Interface
clk_rd : in std_logic;
rst_rd : in std_logic;
got : in std_logic;
valid : out std_logic;
dout : out std_logic_vector(D_BITS-1 downto 0)
);
end;
Este FIFO tiene 2 entradas de reloj, una para cada dominio de reloj (lectura (rd) y escritura (wr)), así como un reinicio para cada lado.
La ruta de datos de din a dout está rodeada por 4 señales:
Escribir en cada ciclo de reloj 16 significa asignar poner cada 16 ciclos a 1. La señal completa puede ignorarse, porque el lado de lectura siempre es más rápido que el lado de escritura.
Aquí hay una forma de onda para el FIFO:
Siraj Mahoma
Paebbels
valid
no es alto, no puede usar dout. Esto evita que el lector extraiga más palabras de las almacenadas en el FIFO. Todavía se necesita un FIFO porque está utilizando dos relojes diferentes no relacionados. Este límite de dominio de reloj solo puede cruzarse mediante un FIFO de reloj cruzado o un protocolo de protocolo de enlace complejo. Si no utiliza un FIFO de reloj cruzado o un circuito de cruce de dominio de reloj apropiado, leerá datos falsos de su ADC.Siraj Mahoma
Paebbels
Paebbels
Siraj Mahoma