Cruce de dominio de reloj entre la interfaz OV7670 y AXI4-Stream

Actualización 1:

Mi primer enfoque es usar la xpm_cdc_handshakemacro de la siguiente manera:

xpm_cdc_handshake_inst : xpm_cdc_handshake
   generic map (
      DEST_EXT_HSK => 0,            -- DECIMAL; 0=internal handshake, 1=external handshake
      DEST_SYNC_FF => 4,            -- DECIMAL; range: 2-10
      INIT_SYNC_FF => 0,            -- DECIMAL; 0=disable simulation init values, 1=enable simulation init values
      SIM_ASSERT_CHK => 0,          -- DECIMAL; 0=disable simulation messages, 1=enable simulation messages
      SRC_SYNC_FF => 4,             -- DECIMAL; range: 2-10
      WIDTH => 32                   -- DECIMAL; range: 1-1024
   )
   port map (
      dest_clk => M_AXIS_ACLK,      -- 1-bit input: Destination clock.
      dest_req => AXIS_DestReq,     -- 1-bit output: Assertion of this signal indicates that new dest_out data has been
                                    -- received and is ready to be used or captured by the destination logic. When
                                    -- DEST_EXT_HSK = 1, this signal will deassert once the source handshake
                                    -- acknowledges that the destination clock domain has received the transferred
                                    -- data. When DEST_EXT_HSK = 0, this signal asserts for one clock period when
                                    -- dest_out bus is valid. This output is registered.
      dest_ack => AXIS_DestAck,     -- 1-bit input: optional; required when DEST_EXT_HSK = 1
      dest_out => AXIS_SyncData,    -- WIDTH-bit output: Input bus (src_in) synchronized to destination clock domain. This output is registered.
      src_clk => Clock,             -- 1-bit input: Source clock.
      src_rcv => OV7670_SrcRcv,     -- 1-bit output: Acknowledgement from destination logic that src_in has been
                                    -- received. This signal will be deasserted once destination handshake has fully
                                    -- completed, thus completing a full data transfer. This output is registered.
      src_send => OV7670_SrcSend,   -- 1-bit input: Assertion of this signal allows the src_in bus to be synchronized
                                    -- to the destination clock domain. This signal should only be asserted when
                                    -- src_rcv is deasserted, indicating that the previous data transfer is complete.
                                    -- This signal should only be deasserted once src_rcv is asserted, acknowledging
                                    -- that the src_in has been received by the destination logic.
       src_in => OV7670_SyncData    -- WIDTH-bit input: Input bus that will be synchronized to the destination clock domain.
);

La idea es diseñar alguna lógica que llene el búfer de recepción OV7670 ( OV7670_SyncData) e inicie el cruce de dominio afirmando la OV7670_SrcSendseñal. La lógica de transmisión de AXI4-Stream espera la señal AXIS_DestAcky, cuando se confirma esta señal, los datos se sincronizan y luego se transmiten a través de la interfaz de AXI4-Stream.


Estoy tratando de implementar una interfaz de cámara OV7670 con una interfaz AXI4-Stream para la transmisión de datos. Mi idea actual es implementar algún tipo de FIFO o búfer de anillo para almacenar los datos de la cámara (es decir, una línea) y cuando el FIFO está lleno, se inicia una transmisión de los datos a través de la interfaz AXI4-Stream.

Pero no estoy seguro de si este es el enfoque ideal, porque cruzaré dos dominios de reloj (el reloj para el módulo de la cámara y el reloj AXI) o ¿hay un mejor enfoque?

Respuestas (1)

FIFO asíncrono

FIFO asíncrono es un enfoque ideal para considerar la implementación entre para cruzar datos de forma segura en los dos dominios de reloj.

Si está haciendo esto en Vivado, le sugiero que use la IP de Vivado dedicada en lugar de diseñar una.

Si está interesado en diseñar uno, sería útil consultar este documento:

Documento de Cummings sobre FIFO

Elegir la profundidad del FIFO

Tienes que elegir la profundidad del FIFO en base a:

  1. ¿Cuáles son las frecuencias de las operaciones de escritura y lectura en los lados de encolado y desencolado respectivamente?
  2. Cuántas ráfagas de datos va a poner en cola en el FIFO.

Aquí hay una guía simple que usé en el pasado para el cálculo de profundidad

EDITAR:

El sincronizador de bus de protocolo de enlace completo que está tratando de usar tiene menos rendimiento, pero sirve para su propósito y consume menos recursos; especialmente si no necesita enviar muchas ráfagas de datos de una sola vez. Si no recuerdo mal, el generador FIFO exige un minm. profundidad y, por lo tanto, puede ser una exageración cuando se trata de la utilización de recursos.

Gracias Mitu Raj. He actualizado mi pregunta con mi primer acercamiento con el xpm_cdc_handshakemakro. ¿Puedo usar esto también o cuál es la diferencia entre esto y el generador FIFO en Vivado?
He editado la respuesta.