Hace algún tiempo implementé una interfaz GMII para mi núcleo Gigabit Ethernet. Ahora estoy tratando de hacer lo mismo con el protocolo RGMII . La implementación de referencia de Xilinx usa las primitivas IDELAY[|E1|E2] para ajustar el retardo de entrada. Me gustaría hacer lo mismo con ODELAY...
La implementación de referencia utiliza dos relojes de transmisión: TX_Clock
y TX_Clock90
(desfase de 90°). El reloj normal se usa para los registros ODDR y el reloj desfasado se envía al dispositivo PHY.
Sé que podría generar ese reloj con un DCM/MMCM o PLL, pero no quiero rediseñar toda mi pila Gigabit Ethernet para proporcionar un nuevo reloj TX para mi capa de abstracción física.
Pensé que podría usar una primitiva ODELAY para cambiar el TX_Clock según lo desee. Pero, ¿cómo calculo el conteo de tap/delay?
DS182 - Guía de conmutación de CC Kintex-7 - página 28 define 'resolución de retardo de cadena ODELAY' de la siguiente manera:
Mi primitiva IDELAYCTRL se obtiene con un reloj de referencia de 200 MHz y TX_Clock funciona a 125 MHz (8 ns). Un cambio de fase de 90° significaría un retardo de 2 ns, lo que equivale a 25,6 derivaciones de retardo de 78,125 ps.
Entonces, ¿es correcto establecer el valor de ODELAY en 26?
Abreviaturas:
GMII: interfaz independiente de medios Gigabit
RGMII: GMII reducido (utilizando la técnica DDR)
ODDR: registro de salida DDR
Tal vez no sea una respuesta directa a su pregunta, pero quiero llamar su atención sobre las siguientes posibles soluciones:
la tasa de sesgo es controlable tanto en RGMII PHY como en FPGA IC
Por lo general, RGMII PHY implementa un mecanismo de eliminación de sesgos (por ejemplo, KSZ9021 puede absorber sesgos de hasta 1,8 ns, muy cerca de lo que necesita), por lo tanto (si su físico lo tiene, por supuesto) lo activa. Cambia (retrasa) el reloj en tu PHY manteniendo los datos iguales. Las áreas sombreadas en la imagen de abajo explican esto gráficamente.
Además, además de los cambios de PHY si no es suficiente, puede configurar correspondientemente la velocidad de respuesta en FPGA para ralentizar los datos mientras acelera el reloj.
el rastreo de pcb podría ser todavía flexible, no dogmático
(si, por causa) Puede (entonces) enrutar el seguimiento del reloj "proporcionalmente" más largo que los datos (o viceversa, dependiendo del reloj directo/invertido).
fpga conduce líneas tx
Puede usar sus controladores de salida normales (en lugar de DDR) y controlarlos mediante multiplexación como assign output[0:3] = (txclk) ? txdata[0:3] : txdata[4:7]
.
Su manera (no solo los cálculos) sobre ODELAY parece correcta, pero yo (y creo que nadie) no puedo confirmarlo/refutarlo porque esa corrección puede aprobarse finalmente solo en el diseño (tablero) donde varios efectos secundarios, como el jitter del reloj, que son difíciles de predecir y simular, se pueden observar y estimar.
Además, parece un poco extraño que use relojes no divisibles integralmente de 125 (= 25 * 5?) Y 200 (= 25 * 8?) MHz en lugar de que 125 y 250 sean divisibles integralmente (es decir, 250/125 = 2) . En el caso de un par de relojes divisibles de una sola fuente, alineados en fase, podría usar el más alto para cambiar las líneas en el reloj más bajo, también con salidas que no sean DDR.
EDITAR 1
si TX_Clock es el reloj de referencia de la lógica de transmisión (es decir, el bloque está construido alrededor de always @(posedge TX_Clock)
), entonces los ODDR (en el modo SAME_EDGE) deben usar su versión desplazada de 90 grados, es decir, TX_Clock90, y no viceversa. Pero escribiste:
El reloj normal se usa para los registros ODDR y el reloj desfasado se envía al dispositivo PHY.
¿Es correcto? ¿Podría proporcionar el enlace a "La implementación de referencia" que mencionó aquí?
Además, el reloj de transmisión a un RGMII PHY debe generarse como
ODDR otxclkbuf ( .D1(1), .D2(0), .C(TX_Clock90), .CE(1), .SR(0), Q(RGMII_TXCLK) )
ser síncrono fase a fase con las señales de datos, RGMII_TXDs y RGMII_TXCTRL, según lo requiera el protocolo RGMII.
Esto también se indica en la Guía SelectIO de la Serie 7:
Reenvío de reloj
Salida DDR puede reenviar una copia del reloj a la salida. Esto es útil para propagar un reloj y datos DDR con retrasos idénticos y para la generación de múltiples relojes, donde cada carga de reloj tiene un controlador de reloj único. Esto se logra vinculando la entrada D1 del primitivo ODDR Alto y la entrada D2 Bajo. Xilinx recomienda usar este esquema para enviar relojes desde la lógica FPGA a los pines de salida.
Nuevamente, si evita usar DCM, ¿cómo planea trabajar cuando su PHY estará en modo esclavo 1000BASE-T o en modo de recepción basado en DPLL 1000BASE-X/SGMII, para ambos donde GMII_RXCLK es uno basado en CDR de baja calidad? que no podría usarse directamente para sincronizar la lógica de recepción y también la lógica de transmisión en 1000BASE-T?
Editar 2
Primero, debe distinguir qué desea: RGMII "puro" (denominado GMII original en el documento que mencionó) o RGMII "con cambio de hora" (RGMII-ID en el documento). Su código rgmii.vhdl es sobre el "cambiado". Aquí, le recomiendo que vuelva a elegir RGMII "puro" porque (del documento RGMII con fecha de 2002 y de los circuitos integrados PHY/SERDES que usé) cualquier GbE PHY moderno admite cambio de reloj/datos y no tiene necesidad de sofisticar su código .
En segundo lugar, para cualquier valor que haya seleccionado para ODELAY, deberá aprobarlo y cien a uno para sintonizarlo en la placa en vivo con un osciloscopio en sus manos. 26 es normal, deja que sea tu toque inicial para iterar paso a paso.
Además, te recomiendo que hagas una nueva pregunta como
sin las etiquetas "ethernet" y "gigabit" porque, como veo, su interés es sobre xilinx-fpga-oddr-odelay en total, sin nada sobre ethernet-gigabit.
Buena suerte.
PD Desde el código que se muestra, se espera que el MAC actualice los datos en posedge !tx_clk90
un momento, como puedo suponer, su código de cliente GMII inicial no tiene tal expectativa.
gestión
Paebbels