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).
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?
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).
miedo_jeff
miedo_jeff