Tal vez no sea una respuesta directa a tu pregunta, pero quiero llamar tu atención sobre las siguientes soluciones posibles:
-
la tasa de sesgo es controlable tanto en RGMII PHY como en FPGA IC
Por lo general, RGMII PHY implementa un mecanismo de desvío (por ejemplo, KSZ9021 puede absorber sesgos de hasta 1,8 ns, muy cerca de lo que necesita), por lo tanto (si su phy lo tiene, por la causa) lo activa. Cambie (retrase) el reloj de su PHY manteniendo los datos iguales. Las áreas sombreadas en la imagen a continuación lo explican gráficamente.
Además,ademásdeloscambiosdePHY,sinoessuficiente,tambiénpuedeconfigurarlavelocidaddegiroenFPGAparareducirlavelocidaddelosdatosmientrasayunaelreloj.
ElseguimientodePCBpodríaserflexible,nodogmático
(si,decausa)Puede(entonces)enrutarlatrazadelreloj"proporcionalmente" más tiempo que los datos (o viceversa, dependiendo de la sincronización directa / invertida).
-
fpga controla las 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 forma (no solo los cálculos) acerca de ODELAY parece correcta, pero yo (y creo que cualquiera) no puede confirmar / refutar porque esa corrección puede ser aprobada finalmente solo en el diseño (placa) donde hay varios efectos secundarios, como jitter de reloj , que son difíciles de predecir y simular, se pueden observar y estimar.
Además, parece un poco extraño que utilice relojes divisibles no 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 origen único, alineados en fase, puede usar el más alto para controlar las líneas cambiadas en el reloj más bajo, con salidas no DDR también.
EDIT 1
si TX_Clock es el reloj de referencia de lógica de transmisión (es decir, el bloque se construye alrededor de always @(posedge TX_Clock)
), entonces los ODDR (en el modo SAME_EDGE) deben usar su versión modificada de 90 grados, es decir, TX_Clock90, no al revés. Pero usted escribió:
El reloj normal se usa para los registros ODDR y el reloj de cambio de fase se envía al dispositivo PHY.
¿Es correcto? ¿Podría dar 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) )
para ser síncrono fase a fase con las señales de datos, RGMII_TXDs y RGMII_TXCTRL, como lo requiere el protocolo RGMII.
Esto también se menciona en la Guía de 7 Series SelectIO:
Reenvío de reloj
La 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
reloj de carga tiene un controlador de reloj único. Esto se logra atando la entrada D1 del
Primaria ODDR Alta, y la entrada D2 Baja. 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 funcionará en modo esclavo 1000BASE-T o en modo de recepción basado en DPLL 1000BASE-X / SGMII, para ambos donde GMII_RXCLK es un CDR de baja calidad? basado en uno que no se puede utilizar 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 lo que desea: RGMII "puro" (denominado GMII original en el documento que mencionó) o RGMII "con cambio de reloj" (RGMII-ID en el documento). Su código rgmii.vhdl se trata del código "desplazado". Aquí, te recomiendo que te reelijas a RGMII "puro" porque (del documento RGMII con fecha 2002 y de los circuitos integrados PHY / SERDES que utilicé) cualquier GbE PHY moderno admite el cambio de reloj / datos y no tienes necesidad de sofisticar tu código .
Segundo, para cualquier valor que haya seleccionado para ODELAY, deberá aprobar y de cien a uno para sintonizarlo en el tablero activo mediante un osciloscopio en sus manos. 26 es normal, deja que sea tu primer toque para la iteración paso a paso.
Además, te recomiendo que hagas una nueva pregunta como
- cómo programar ODELAY a la derecha (en Xilinx FPGA)?
- ¿Cómo cambiar un reloj 90 grados sin DCM / PLL (en Xilinx FPGA)?
- ¿Cómo usar ODDR teniendo solo un reloj y sin su réplica modificada (en Xilinx FPGA)?
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.
P.S. A partir del código que se muestra, se espera que el MAC actualice los datos en posedge !tx_clk90
, mientras que, como puedo suponer, su código de cliente GMII inicial no tiene tal expectativa.