Pulso en el borde de un reloj diferente

Tengo un reloj proveniente de un pin (GMI_CLK). Pasa por un PLL y se genera un nuevo reloj con 4 veces la frecuencia (Sys_CLK). Ahora necesito un pulso cada vez que se detecta un flanco ascendente del reloj original (Sys_valid).ingrese la descripción de la imagen aquí

Esto funciona perfecto en la simulación. Se ha codificado de la siguiente manera, pero ambas formas generan errores durante la síntesis:

make_clkvalid: process(sys_clk)
    variable GMI_CLK_alt : std_logic;
begin
    if rising_edge(sys_clk) then
        if GMI_CLK = '1' and GMI_CLK_alt = '0' then
            Sys_valid <= '1';
        else
            Sys_valid <= '0';
        end if;

        GMI_CLK_alt := GMI_CLK;

    end if;
end process make_clkvalid;

El puerto [Synth 8-5535] tiene conexiones ilegales. Es ilegal tener un puerto conectado a un búfer de entrada y otros componentes. Las siguientes son las conexiones del puerto: Búfer de entrada: Puerto I de la instancia clkin1_ibufg(IBUF) en el módulo Otros componentes: Puerto I1 de la instancia i_43(LUT2) en el módulo GMI_IO Puerto I1 de la instancia i_42(LUT2) en el módulo GMI_IO Puerto D de la instancia GMI_CLK_alt_reg__0 (FD) en el módulo GMI_IO Puerto D de la instancia GMI_CLK_alt_reg(FD_1) en el módulo GMI_IO


o así:

make_clkvalid: process(GMI_CLK, Sys_clk)
begin
    if rising_edge(GMI_CLK) then
        Sys_valid <= '1';
    elsif falling_edge(Sys_clk) then 
        Sys_valid <= '0';
    end if;
end process make_clkvalid;

[Synth 8-27] cláusula else después de comprobar el reloj no compatible [GMI_IO.vhd":183]


¿Cómo puedo implementarlo para la síntesis?

Deberá incluir más código para diagnosticar el primer error, que no está directamente relacionado con el código que publicó.
Bien, creo que sé por qué recibiste el primer mensaje. Espero que mi respuesta actualizada lo resuelva por ti.

Respuestas (1)

Su segunda implementación falla debido a lo que es un error común. El patrón de código:

if rising_edge(clk_a) then
    signal_a <= '1';
elsif falling_edge(clk_b) then 
    signal_a <= '0';
end if;

No se puede realizar en hardware, porque describe un registro de 1 bit con dos entradas de reloj diferentes. Tal registro no existe en el tejido FPGA; el más cercano es un registro de salida DDR que puede estar presente, pero incluso este está diseñado para usarse con un reloj y su inverso, no con dos relojes totalmente separados.

El primer intento parece más sensato. Si pudiera incluir el mensaje de error que genera, actualizaré mi respuesta.


Ahora que agregó el mensaje de error, puedo ver que esto no tiene nada que ver con el fragmento de código que publicó. Aunque no se ha proporcionado el código relevante, creo que el error aquí es que tiene la entrada de reloj GMI conectada a un IBUFG y también a la lógica en este módulo.

La causa más probable de esto es que haya creado su código PLL usando CoreGen. CoreGen colocará innecesariamente un búfer de reloj global entre un pin de entrada de reloj y una instancia de PLL/DCM. El resultado es que cuando conecta este mismo pin a otra cosa (es decir, su circuito de detección de bordes), el diseño no se puede enrutar debido a la estructura de la FPGA.

Para resolver esto, todo lo que tiene que hacer es eliminar la instanciación de BUFG del archivo .VHD que creó CoreGen y luego conectar lo que fue la entrada al BUFG, a la entrada de la instancia de PLL/DCM. Synthesis insertará un búfer de reloj en el lugar apropiado para permitir que su diseño funcione.

Según el comentario de @TomCarpenter, si lo anterior resuelve su problema, hay una opción en CoreGen para configurar el búfer de entrada en "Ninguno". Esto evita modificar la salida de CoreGen, lo que podría atrapar a alguien más adelante.

Aún mejor sería no usar CoreGen para algo tan simple como instanciar un PLL; Si va a Edición > Plantillas de idioma > VHDL > Creación de instancias primitivas de dispositivo > Spartan 6 (o lo que sea) > Componentes de reloj en ISE (está en Ventana > Plantillas de idioma > etc. en Vivado), puede encontrar plantillas simples para instanciar su PLL, sin la molestia / problemas de CoreGen (como el problema que ha visto).

Estoy bastante seguro de que CoreGen para el PLL tiene opciones para conectar las salidas, el valor predeterminado es, creo, BUFG. Debería ser posible cambiar esto para eliminar el BUFG en lugar de editar el HDL directamente.
@TomCarpenter Nunca ejecuté el CoreGen en cuestión, pero el problema es que, al menos de forma predeterminada, inserta un BUFG en la señal de entrada al PLL.
Recién marcado, puede seleccionar los tipos de búfer de entrada y salida. Para las entradas, las opciones son: "entrada de extremo único", "entrada diferencial", "búfer global (BUFG)" y "Sin búfer". La última opción debería eliminar la instancia de BUFG.
Es bueno saberlo para la próxima vez. Ahora funciona con la plantilla.