Estoy tratando de usar Spartan 6 (TQG144) PLL para generar un reloj de alta velocidad. Usé el generador de núcleo IP para configurar el PLL. Aquí está el código VHDL simple que tengo para usar el componente generado:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity clk_test is
Port (
clk_o1: out STD_LOGIC;
clk: in STD_LOGIC
);
end clk_test;
architecture Behavioral of clk_test is
component clock_gen
port
(
CLK_IN1 : in std_logic;
CLK_OUT1 : out std_logic
);
end component;
begin
clock: clock_gen port map(
CLK_IN1 => clk,
CLK_OUT1 => clk_o1);
end Behavioral;
y aquí está el archivo UCF:
NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50%;
NET "clk" LOC = P56 | IOSTANDARD = LVTTL;
NET "clk_o1" LOC = P85 | IOSTANDARD = LVTTL;
cuando compilo el código me sale este error:
Phase 2.7 Design Feasibility Check
ERROR:Place:1205 - This design contains a global buffer instance,
<clock/clkout1_buf>, driving the net, <clk_o1_OBUF>, that is driving the
following (first 30) non-clock load pins off chip.
< PIN: clk_o1.O; >
This design practice, in Spartan-6, can lead to an unroutable situation due
to limitations in the global routing. If the design does route there may be
excessive delay or skew on this net. It is recommended to use a Clock
Forwarding technique to create a reliable and repeatable low skew solution:
instantiate an ODDR2 component; tie the .D0 pin to Logic1; tie the .D1 pin to
Logic0; tie the clock net to be forwarded to .C0; tie the inverted clock to
.C1. If you wish to override this recommendation, you may use the
CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote
this message to a WARNING and allow your design to continue. Although the net
may still not route, you will be able to analyze the failure in FPGA_Editor.
< PIN "clock/clkout1_buf.O" CLOCK_DEDICATED_ROUTE = FALSE; >
ERROR:Place:1136 - This design contains a global buffer instance,
<clock/clkout1_buf>, driving the net, <clk_o1_OBUF>, that is driving the
following (first 30) non-clock load pins.
< PIN: clk_o1.O; >
This is not a recommended design practice in Spartan-6 due to limitations in
the global routing that may cause excessive delay, skew or unroutable
situations. It is recommended to only use a BUFG resource to drive clock
loads. If you wish to override this recommendation, you may use the
CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote
this message to a WARNING and allow your design to continue.
< PIN "clock/clkout1_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;
El error dice que estoy usando un PIN que no es de reloj para el clk_o1 y no funciona, sin embargo, según los recursos de reloj de Spartan 6 [1], el PIN 85 es un pin GCLK (probé con diferentes PIN). Me pregunto qué tiene de malo que me salga este error.
[1] https://www.xilinx.com/support/documentation/user_guides/ug382.pdf#page=25
La señal del reloj va a todas partes en el FPGA, por lo que requiere consideraciones especiales de fanout y debe llegar a todos sus destinos con un sesgo mínimo. Eso significa que no puede enrutar relojes a través de un tejido lógico regular o a través de cualquier pin en el FPGA. El reloj solo puede entrar en pines dedicados a él y solo puede enrutarse en el FPGA en redes de distribución de reloj especiales.
El problema con su código es que solo está tratando el reloj como cualquier señal normal anterior en cualquier pin normal anterior. No puedes hacer eso. No puede leer la señal del reloj y escribirla directamente en un pin. El software quiere mantener las señales del reloj aisladas en la red de distribución del reloj y leer el reloj en un pin rompe eso.
Si desea generar la señal del reloj en un pin normal, deberá hacer algo como
if arista_borde(Reloj) entonces SomePin <=no SomePin;
Pero esto no será muy bueno por las razones que mencioné anteriormente. Aunque puedes intentarlo. Pero puede obtener mejores resultados escribiendo un contador que cuente con el reloj y solo emita o cambie cada n ciclos de reloj. Sin embargo, solo haga esto para verificar que el PLL esté funcionando. No intentes esto para registrar algo externamente.
El mensaje de error es en realidad mucho más explícito que la mayoría. Incluso te dice cómo anularlo. Pero la parte importante es la recomendación justo antes de la anulación que le indica cómo obtener una señal de reloj fuera del chip. Parece decir que debe crear una instancia de un componente ODDR2 y usar su objeto Clock Forwarding en el configurador de IP y usarlo para sacar la señal del reloj del chip. Probablemente esté destinado a sincronizar la SDRAM externa. Esa parece ser la forma correcta de hacerlo si realmente desea proporcionar una señal de reloj externa en lugar de simplemente verificar que el PLL esté funcionando.
Los pines de reloj en el FPGA son para entradas de reloj , no para salidas. Tienen rutas bien caracterizadas a recursos de reloj interno, como PLL, DCM y los búferes para árboles de reloj.
Los árboles de reloj en sí mismos se enrutan a la mayoría de los dispositivos con reloj en el chip, principalmente los FF en la estructura y en las IOB. En general, NO hay ninguna forma de conectar un árbol de reloj directamente a ningún otro tipo de red dentro del chip, incluidas las entradas a los controladores de pines. Esto es a propósito: mantiene equilibrada la carga en el árbol del reloj para que todos los dispositivos dentro del chip obtengan el reloj con la misma cantidad de retraso (desviación mínima del reloj).
Es por eso que le dicen que use la técnica ODDR2: la ruta desde el árbol del reloj hasta los FF de IOB está bien caracterizada, al igual que la ruta desde esos FF hasta el pin mismo. De hecho, está sintetizando una copia del reloj que sacará del chip, y el retraso entre el original y la copia está estrictamente controlado.
Gracias por toda tu ayuda. ¡Así que la técnica ODDR2 era el camino a seguir! Aquí [1] puede encontrar cómo usar este componente para reenviar la señal del reloj.
DKNguyen
Siná
rdtsc
FPGA metastability
.