Cruzando una señal de pico de un solo ciclo de un dominio de reloj rápido a uno más lento

2

Tengo una señal de 1 bit proveniente de una parte de mi circuito que se ejecuta en un reloj de 40 MHz. La señal es en su mayoría 0, excepto que es 1 para un solo ciclo de 40 MHz cada ~ millones de ciclos.

Otra parte de mi circuito se ejecuta en un reloj de 1 MHz. Me gustaría hacer un procesamiento síncrono en la señal descrita anteriormente en esta parte de mi circuito. ¿Cuál es la forma correcta de convertir la señal de 40 MHz de un solo ciclo en una señal de 1 MHz de un solo ciclo?

En caso de que sea importante, tanto el reloj de 40 MHz como el de 1 MHz se emiten desde el mismo administrador de reloj controlado por el reloj de 32 MHz en mi placa de desarrollo, por lo que deberían estar sincronizados.

    
pregunta Cactus

2 respuestas

3

Convierta ese pulso a un cambio de nivel (invierta la salida de un flip flop cada vez que se genere un pulso), transmítalo con un par de flip flops para la sincronización, y convierta el cambio de nivel a un pulso con un flip flop y la puerta XOR. Esto se denomina sincronización de pulsos con un sincronizador de palanca, y es una técnica muy común. Consulte: enlace .

    
respondido por el alex.forencich
2

Editar: esta solución supone que no tiene acceso al reloj de 40 MHz. Si lo haces, entonces la respuesta de @ alex.forencich es mejor.

¿Por qué no usa el pulso de 40 MHz como un conjunto asíncrono para un registro en el dominio de 1 MHz? Si luego tiene un sincronizador de registro doble seguido de un detector de flanco ascendente, puede utilizar la salida de pulso de 1 MHz del detector de flanco ascendente para activar cualquier otra lógica que tenga, y actuar como un borrado sincrónico en el primer registro. (el que tiene un conjunto asíncrono).

signal async_reg : std_logic := '0';
signal synchroniser : std_logic_vector (2 downto 0) := (others => '0');
signal rising_edge_detected : std_logic;

...

process (clk1MHz)
begin
  if (pulse40MHz = '1') then
    async_reg <= '1';
  elsif (rising_edge(clk1MHz)) then
    if (rising_edge_detected = '1') then
      async_reg <= '0';
    end if;
  end if;
end process;

process (clk1MHz)
begin
  if (rising_edge(clk1MHz)) then
    synchroniser <= synchroniser(1 downto 0) & async_reg;
  end if;
end process;

rising_edge_detected <= synchroniser(1) and not synchroniser(2);
    
respondido por el scary_jeff

Lea otras preguntas en las etiquetas