¿Colocación no óptima de IOB/BUFGMUX de reloj corregible en software o hardware?

Recibo este desagradable error al sintetizar mi diseño usando ISE Studio para Spartan-6:

ERROR:Place:1108 - A clock IOB / BUFGMUX clock component pair have been found
   that are not placed at an optimal clock IOB / BUFGMUX site pair. The clock
   IOB component <PIN_ADC_CLKOUT_P> is placed at site <C17>. The corresponding
   BUFG component <adc_clkout_BUFG> is placed at site <BUFGMUX_X2Y10>. There is
   only a select set of IOBs that can use the fast path to the Clocker buffer,
   and they are not being used. You may want to analyze why this problem exists
   and correct it. If this sub optimal condition is acceptable for this design,
   you may use the CLOCK_DEDICATED_ROUTE constraint in the .ucf file to demote
   this message to a WARNING and allow your design to continue. However, the use
   of this override is highly discouraged as it may lead to very poor timing
   results. It is recommended that this error condition be corrected in the
   design. A list of all the COMP.PINs used in this clock placement rule is
   listed below. These examples can be used directly in the .ucf file to
   override this clock rule.
   < NET "PIN_ADC_CLKOUT_P" CLOCK_DEDICATED_ROUTE = FALSE; >

Esta entrada en particular es una entrada LVDS y tengo en mi código:

wire adc_clkout;
IBUFDS ibuf_adc_clkout(.I(PIN_ADC_CLKOUT_P), .IB(PIN_ADC_CLKOUT_N), .O(adc_clkout));

y el archivo ucf dice:

NET "PIN_ADC_CLKOUT_P"  LOC="C17" |IOSTANDARD=LVDS_25 |DIFF_TERM=true;
NET "PIN_ADC_CLKOUT_N"  LOC="A17" |IOSTANDARD=LVDS_25 |DIFF_TERM=true;

Hay otras señales LVDS con definiciones idénticas de las que no obtengo este error.

Intenté todo lo que imaginé para deshacerme de este error sin éxito. Al final solo usé CLOCK_DEDICATED_ROUTE = FALSEy lo llamé el día.

Sin embargo, ahora tengo problemas de temporización cuando cambio el código de Verilog que no tiene nada que ver con el lugar donde ocurre el error. Sin embargo, tiene que ver con esta línea CLKOUT. Así que me imagino que podría tener que ver con este error y me gustaría resolverlo.

Sin embargo, el hardware ya se ha construido, ¡ no puedo cambiar los pines de E/S !

¿Puedo de alguna manera deshacerme de este error en el software?

Algunas observaciones:

  • Esta no es una señal de reloj en el sentido de que se usa en varias ubicaciones, por lo que no necesitaría un árbol de reloj, etc. en el borde ascendente de este reloj.

  • El reloj ADC lo genero yo mismo dentro de la FPGA. La señal PIN_ADC_CLKOUT es simplemente una copia sesgada de eso, sesgada de acuerdo con las líneas de datos y la desviación se obtiene mediante el procesamiento del ADC y la traza de PCB de ida y vuelta.

  • Este reloj ADC tiene un "ciclo de trabajo". Como referencia, el ADC es el LTC2323 y el tiempo se ve así:

Este no es un ejemplo de trabajo mínimo reproducible. Ha conectado una señal de reloj a un par de pines FPGA que no está diseñado para usarse para señales de reloj. Como dijiste, el diseño es fijo, esto significa que la PCB tiene un error, tan simple como es.

Respuestas (2)

Hay algunos puntos que necesitan ser aclarados. La señal CLKOUT es lo que comúnmente se denomina "reloj de datos" . El reloj de datos es básicamente una copia de la referencia de reloj (SCK) alineada con los datos para que pueda usarse para muestrearlos.

Como se señaló correctamente antes, el problema principal es que el reloj de datos no estaba conectado a una entrada con capacidad de reloj en el dispositivo y, por lo tanto, no existe una forma óptima de enrutarlo a la red del reloj.

La razón por la que tiene problemas de tiempo es usar esta señal como un reloj: ¿la usa junto con la declaración @posedge (o rise_edge()) en alguna parte del código? (eventualmente revise su netlist de síntesis en PlanAhead para ver si hay flip flops registrados por esta señal).

Para responder a su pregunta, todo depende de lo que espera, por ejemplo, qué tasa está tratando de lograr. Hay varias opciones:

  • Puede volver a muestrear la señal CLKOUT con un reloj más rápido y usarla como luz estroboscópica de "datos válidos" para bloquear el SDO. Tenga en cuenta que incluso esto puede ser difícil si planea usar frecuencias de reloj de +100 MHz + recomendaría usar el sincronizador 2-DFF para minimizar la posibilidad de problemas de metaestabilidad.

  • Para velocidades más bajas, use el SCK para el muestreo de datos e ignore completamente el CLKOUT. Allí, muestrearía los datos en el flanco ascendente de SCK a medida que los datos se presentan en el flanco descendente (como en las aplicaciones SPI). Puede usar un osciloscopio para asegurarse de que las transiciones SDO no ocurran demasiado cerca del borde de SCK.

  • Si planea hacer una nueva revisión de PCB de todos modos, use las soluciones proporcionadas anteriormente como solución temporal y conecte el CLKOUT_P/N a los pines con capacidad de reloj en el mismo medio banco que el SDO

Conduce entradas de reloj de registro, es una señal de reloj, así de simple.

¿Tiene el reloj de fuente ADC también conectado a la FPGA en un par de entrada de reloj real? Si es así, podría (verifique la sincronización en el ADC con más cuidado) ignorar la salida del reloj del ADC y usar un MCMM o similar para producir un reloj interno que tenga el sesgo apropiado en comparación con su entrada de reloj real para bloquear los datos.

Tal vez podría salirse con la suya usando esta entrada SOLO para registrar un registro en los dolores de IO y luego usar un lío de flip-flops de sincronización para cruzar a un dominio de reloj impulsado por una entrada de reloj real a la misma velocidad, esto luego registraría todo el resto de tu lógica

De lo contrario, el tablero vuelve a girar.

El reloj ADC se genera en la FPGA y también una señal LVDS (en este caso uso OBUFDS). De alguna manera parece funcionar si uso este reloj directamente. Sin embargo, en la hoja de datos del ADC se recomienda encarecidamente utilizar la señal de coincidencia sesgada del ADC. Y lo encuentro más limpio. En cualquier caso, la respuesta es: No, ¿esto no se puede arreglar en el software ? ¿En serio? ¿Se necesitaría construir toda la implementación de Verilog?
Además, ¿podría dar más detalles sobre su segunda sugerencia? Como dije, el reloj ADC lo genero yo mismo dentro de la FPGA. ¿Quiere decir que podría tomar esta señal original y sincronizarla en fase con el reloj de salida del ADC? ¿Cómo? También vale la pena decir que no es un reloj real, tiene un ciclo de trabajo.
¿No se pueden relajar los requisitos de estas líneas de 3 líneas para que CLKOUT y las líneas de datos tengan un retraso arbitrario pero solo coincidan? (Nuevamente, estas líneas se usan en una sola ubicación). ¿No puedo usar el truco CLOCK_DEDICATED_ROUTE y aun así asegurarme de que se cumplan los requisitos de tiempo básicos? ¿No puedo forzar esto como una línea que no es de reloj? (¿Por qué piensa que es un reloj en primer lugar?) Mi código es tan pequeño, dado lo que se podría hacer con un Spartan6 enorme, es tan difícil de creer que alcanzaría los límites del hardware y no habría forma de solucionarlo. SUDOESTE