Introducción
Esta página trata sobre las entradas de datos síncronas de fuente (source-synchronous data inputs): esta técnica significa que las entradas de datos son síncronas con un reloj que el componente externo genera en paralelo con dichas entradas.
Este método se utiliza a menudo simplemente porque así es como funciona el componente externo. Otra buena razón es que la fuente de los datos está físicamente lejos de la FPGA. También es posible que haya un cable y un conector entre la FPGA y el otro lado. Por ejemplo, una cámara digital que envía datos de píxeles.
Una posible dificultad con un reloj síncrono de fuente (source synchronous clock) es que puede no estar activo todo el tiempo. La señal de reloj también puede verse afectada por una conexión física suelta o por un ruido excesivo. También es posible que el reloj no tenga un periodo estable, o que la fluctuación de fase (jitter) sea excesivamente alta. Esto ocurre a menudo cuando la fuente de los datos (y por tanto también el reloj) es un periférico de E/S de un microprocesador.
Nótese que hay una página aparte que analiza las relaciones entre el reloj y los datos en general.
Cómo afrontar un reloj inestable
La pauta más importante con las entradas síncronas de fuente es que el reloj no debe conectarse directamente a los elementos lógicos dentro de la FPGA. En lugar de ello, el reloj que se utiliza dentro de la FPGA debe ser un reloj limpio, generado por un PLL que esté dentro de la FPGA.
Si un reloj externo se conecta directamente a la lógica dentro de la FPGA, pueden aparecer problemas extraños: un reloj defectuoso crea comportamientos inesperados que no parecen un problema de reloj. Un exceso de fluctuación de fase (jitter) y los glitches pueden violar los requisitos de temporización que garantizan un funcionamiento fiable del diseño. La consecuencia es que prácticamente puede ocurrir cualquier cosa, incluidas situaciones imposibles según el código Verilog. Por tanto, es fácil pensar erróneamente que el problema es un bug en el diseño de la FPGA.
Es natural pensar (erróneamente) que los problemas con un reloj solo provocan una pérdida de ciclos de reloj y, en consecuencia, faltarán algunos datos. Cuando un reloj defectuoso causa otros problemas, los intentos de resolverlos suelen centrarse en las partes del diseño lógico que parecen más relacionadas. Eso puede hacer perder mucho tiempo.
La única situación en la que un reloj externo puede usarse directamente por el entramado lógico es cuando se garantiza que este reloj es estable y limpio. Si este reloj no es estable cuando la FPGA comienza a funcionar, este problema requiere tratamiento: mientras el reloj sea inestable, debe aplicarse un reset a la lógica que depende de este reloj.
Posibles estrategias
Hay principalmente cuatro estrategias posibles para sincronizar con el reloj externo. Estas estrategias se analizan a continuación, sin un orden particular.
Estrategia #1: Muestreo de señal 01
Esta estrategia es el método más robusto para las entradas síncronas de fuente. Cuando el reloj externo se comporta mal, el muestreo de señal 01 (01-signal sampling) tiene una clara ventaja sobre cualquier otro método. Sin embargo, este método solo es útil cuando la frecuencia del reloj de la fuente de datos es relativamente baja.
Este método se analiza por separado en una página dedicada.
Estrategia #2: Uso de un PLL
Con esta estrategia, el reloj externo se conecta a la entrada de un PLL de la FPGA. El reloj de salida de este PLL se utiliza para los elementos lógicos. Se aplica una señal de reset a estos elementos lógicos cuando el PLL no está enclavado. Esta solución garantiza que los elementos lógicos dependan de un reloj estable: cuando el reloj de salida del PLL no es estable, los elementos lógicos se desactivan mediante el reset.
El PLL también facilita el cumplimiento de las restricciones de temporización (timing constraints), en comparación con conectar el reloj externo directamente: el PLL compensa el retardo entre el pin de reloj y el reloj interno de la FPGA.
Sin embargo, nótese que las imperfecciones del reloj externo pueden causar una fluctuación de fase excesiva en la salida del PLL. El detector de enclavamiento del PLL puede seguir indicando que el PLL funciona correctamente, incluso aunque el reloj que produce sea inusualmente ruidoso. No hay una solución sencilla para esta situación. Una posibilidad es cambiar las restricciones de temporización para la lógica que depende de la salida del PLL. Por ejemplo, la fluctuación de fase del reloj en las restricciones de temporización puede aumentarse a un valor que el PLL probablemente no superará (porque se produciría una pérdida de enclavamiento).
Hay una similitud entre esta estrategia y la temporización con reloj síncrono de sistema (system synchronous clocking): en ambos escenarios, el reloj externo se conecta a un PLL, y la salida de este PLL se utiliza dentro de la FPGA. Por tanto, las restricciones de temporización se escriben de la misma manera que para un reloj síncrono de sistema (system synchronous clock).
Nótese que el PLL normalmente alinea su reloj de salida con el reloj externo de una manera óptima para un reloj síncrono de sistema. La alineación óptima para un reloj síncrono de fuente (source synchronous clock) puede ser ligeramente diferente. En ambos casos, los relojes no están perfectamente alineados. Más bien, hay una pequeña diferencia de tiempo intencionada entre los flancos de los relojes. Esta diferencia de tiempo facilita el cumplimiento de los requisitos de temporización de los registros de E/S. Algunos PLL pueden configurarse para alinear los relojes y obtener un rendimiento óptimo con un reloj síncrono de fuente.
Esta estrategia es la más fácil de implementar, en comparación con las demás estrategias enumeradas aquí. Es adecuada para frecuencias de reloj relativamente altas. Pero para frecuencias cercanas al máximo que la E/S puede soportar, esta estrategia probablemente no funcionará.
Estrategia #3: Desplazamiento de fase
Esta estrategia se suele elegir cuando la velocidad de datos está cerca del máximo que la FPGA puede soportar.
Las formas habituales de garantizar los requisitos de temporización no funcionan con velocidades de datos tan altas: será imposible cumplir las restricciones de temporización. Sin embargo, un muestreo (sampling) fiable de las señales de datos sigue siendo posible.
El problema con las restricciones de temporización es garantizar los requisitos de temporización mediante un cálculo: tal cálculo incluye varios parámetros inciertos, por ejemplo diferencias en el proceso de fabricación de la FPGA. Cuando se tienen en cuenta estos parámetros, los cálculos no ofrecerán una solución de temporización que garantice un muestreo fiable. Cuando la velocidad de datos es muy alta, no hay margen de temporización que desperdiciar en estas incertidumbres.
Pero para un chip FPGA concreto, estos parámetros son constantes. La solución es entonces buscar la temporización correcta mientras la FPGA está funcionando. En la práctica, esto significa que una máquina de estados (state machine) dentro de la FPGA ajusta el retardo entre el reloj de datos y el momento del muestreo. Así se emplea un mecanismo adaptativo para encontrar la temporización óptima, en lugar de depender de cálculos. Ese mecanismo se denomina desplazamiento de fase (phase shifting).
Esta estrategia se usa a menudo con las señales de datos de las memorias DDR SDRAM. En esta aplicación, el objetivo es siempre alcanzar una velocidad de datos lo más alta posible. Por tanto, las capacidades de los puertos de E/S se llevan al límite. En consecuencia, el desplazamiento de fase es la única manera de garantizar que las entradas de datos se muestreen de forma fiable: después de que la memoria DDR haya sido inicializada, se escribe una secuencia especial de datos en la memoria (las señales de datos hacia la memoria son salidas síncronas de fuente, así que no hay dificultad con la temporización). La FPGA lee entonces repetidamente la misma parte de la memoria DDR. Una máquina de estados encuentra la temporización óptima alterando gradualmente el retardo del muestreo. Los datos de entrada esperados se conocen, porque son la misma secuencia de datos que se escribió previamente. La máquina de estados puede por tanto evaluar fácilmente la fiabilidad de los datos y encontrar el retardo óptimo.
Una característica interesante de este mecanismo es que el reloj de datos suministrado por el chip DDR puede ignorarse: la memoria DDR está sincronizada con el reloj que genera la FPGA. Este reloj forma parte de las salidas síncronas de fuente que recibe la memoria DDR. Por tanto, está garantizado que el reloj de datos de las entradas síncronas de fuente tiene exactamente la misma frecuencia que el reloj generado por la FPGA. El mecanismo de desplazamiento de fase puede entonces basarse en el reloj interno en lugar del reloj que llega junto con los datos. No importa que haya un retardo desconocido entre estos dos relojes: la máquina de estados encuentra la temporización óptima independientemente de este retardo.
De hecho, así se implementa normalmente este mecanismo para las memorias DDR: aunque las memorias DDR tienen un reloj síncrono de fuente, denominado data strobe, la implementación habitual del mecanismo de desplazamiento de fase ignora esta señal. La razón es que es más importante garantizar que las señales de datos lleguen de forma fiable que estar alineados con el strobe.
Por tanto, usar el desplazamiento de fase puede eliminar la necesidad de un reloj de datos. Se puede confiar en un reloj interno en su lugar, si se garantiza que su frecuencia es exactamente la misma que la velocidad de datos.
Con esta estrategia, la finalidad de las restricciones de temporización es la misma que con los registros IOB normales.
Estrategia #4: Usar el reloj directamente
Esta estrategia es aparentemente la más directa: el reloj externo se conecta directamente a los biestables dentro de la FPGA. Algo como esto:
module top (
input data_clk,
input [7:0] data
);
reg [7:0] data_samp;
always @(posedge data_clk)
begin
data_samp <= data;
[ ... ]
end
Como se mencionó antes, esta estrategia normalmente no es una buena idea. La razón principal es que si @data_clk tiene un glitch, toda la lógica que depende de este reloj se vuelve impredecible.
Puede ser razonable usar un reloj externo de esta manera si se garantiza que es limpio y estable. Pero incluso si esto está garantizado, puede ser difícil cumplir los requisitos de temporización debido al retardo entre el pin de reloj y los biestables. Algunas FPGA tienen recursos de reloj especiales para reducir este retardo. Esto puede requerir usar un pin de entrada de reloj dedicado y restringir los puertos de E/S a regiones específicas de la FPGA.
Cuando el reloj se usa directamente, las restricciones de temporización se escriben de la misma manera que para un reloj síncrono de sistema.
La alternativa directa para esta estrategia es usar un PLL, como se sugirió antes. Si el reloj de datos no es estable, debería considerarse el muestreo de señal 01 (01-signal sampling).
Resumen
No es una coincidencia que el muestreo de señal 01 se mencionara primero en esta página, y que esta estrategia se describa en una página aparte: es el método más recomendado si la velocidad de datos no es superior a la que este método puede soportar.
Si se consideran otras estrategias, es importante prestar atención a la estabilidad del reloj de datos. Si un reloj se desvía de su comportamiento permitido (es decir, el periodo de reloj y la fluctuación de fase (jitter) máximos), esto puede provocar un mal funcionamiento permanente e irrecoverable de la lógica relacionada. Solo un reset devolverá la lógica a su funcionamiento normal.
Usar un PLL para generar un reloj fiable mejora considerablemente la situación: la salida del PLL es fiable siempre que su detector de enclavamiento lo indique. De lo contrario, debería aplicarse un reset a esta lógica.
