PCI Express en los FPGA Intel de la serie V: funciones básicas de interfaz y características principales del hardware

Introducción


La interfaz PCI Express o PCIe, familiar para muchos, ya estaba disponible para los desarrolladores de sistemas FPGA cuando recién comenzaba a extenderse en la tecnología digital. En este momento, había una solución en la que el núcleo del software estaba conectado a un microcircuito externo de nivel físico [ 5 ]. Esto hizo posible crear una línea PCIe de un solo carril a una velocidad de 2.5 gigaciones por segundo. Además, gracias al desarrollo de tecnologías, la capa física de la interfaz migró a los bloques de hardware PCIe dentro de los propios FPGA; el número de canales posibles aumentó a 8, y en varios microcircuitos nuevos, a 16; Siguiendo los estándares modernos, las posibles tasas de transferencia de datos han crecido.

Al mismo tiempo, aún es difícil encontrar materiales auxiliares para trabajar con los núcleos de hardware de los FPGA modernos en fuentes en ruso; no hay mucha información disponible en la interfaz PCIe. La guía de núcleos PCI Express de hardware implica que el desarrollador ya se ha familiarizado con el estándar y comprende los conceptos básicos de la transferencia de datos entre el dispositivo y una computadora personal (PC). Sin embargo, la abundancia de información en el estándar PCIe en sí no comprende de inmediato qué pasos se deben tomar para transferir con éxito los datos del dispositivo a la memoria de la PC o viceversa. Para obtener una imagen más completa, una parte considerable de la información debe recopilarse poco a poco de varias fuentes. Para los desarrolladores de sistemas Intel FPGA, la dificultad también esque la mayoría de los materiales y artículos disponibles describen el trabajo con núcleos de hardware Xilinx FPGA.

En este artículo, el autor intentará hablar sobre lo que el diseñador del sistema FPGA necesita saber para trabajar con la interfaz PCI Express; considerará las características de trabajar con núcleos de hardware PCI Express FPGA de la serie V de Intel en la versión Avalon-ST.

Niveles PCIe y tipos de paquetes


A pesar de que PCI Express a menudo se denomina bus, de hecho, esta interfaz es una red de dispositivos conectados por grupos de canales dúplex en serie. La propia red PCI Express consta de varios nodos principales: la raíz (raíz), el punto final (punto final) y el enrutador (conmutador) (Figura 1). Para transferir datos solo entre dos dispositivos, es suficiente tener una raíz y un punto final. En el caso de las PC modernas, la raíz de la red se encuentra en un sustrato junto con los núcleos del procesador central. Independientemente de dónde se encuentre la raíz PCIe, está asociada con la memoria del sistema.


Figura 1 - Red PCIe

El protocolo de transferencia de datos PCIe se divide en tres capas: la capa de transacción, la capa de enlace de datos y la capa física. Los datos de la interfaz se transmiten en forma de paquetes. En la


Figura 2 se muestra una vista generalizada de los paquetes. Figura 2: Una vista generalizada de los paquetes PCIe

A nivel de transacción, cualquier paquete (TLP) consta de al menos un encabezado. Dependiendo del tipo de paquete, el encabezado puede ir seguido de datos, el contenido útil del paquete. También se puede agregar una suma de verificación adicional al final del paquete. Existen los siguientes tipos principales de paquetes a nivel de transacción (tabla 1):

Tabla 1 - Tipos de paquetes a nivel de transacción
No. p.Vista del paqueteNombre del tipo de paquete según la especificación
1Solicitud de lectura de memoriaSolicitud de lectura de memoria
2Solicitud de escritura de memoriaSolicitud de escritura de memoria
3Solicitud de lectura de espacio de E / SSolicitud de lectura de E / S
4 4Solicitud de escritura de espacio de E / SSolicitud de escritura de E / S
5 5Leer solicitud de configuraciónSolicitud de lectura de configuración
6 6Escribir solicitud de configuraciónSolicitud de escritura de configuración
7 7Respuesta de lecturaTerminación
8MensajeMensaje

En la capa de enlace, se agrega un número de secuencia de paquete y una suma de comprobación de enlace a cada paquete de nivel de transacción. La capa de enlace de datos también forma sus propios tipos de paquetes (DLLP), que incluyen (tabla 2):

Tabla 2 - Tipos de paquetes de enlace de datos
No. p.Vista del paqueteNombre del tipo de paquete según la especificación
1Confirmación de paquete de nivel de transacciónTLP Ack
2Rechazo de paquete de nivel de transacciónTLP Nack
3Administración de energíaAdministración de energía
4 4Control de flujo de datos.Control de flujo

Finalmente, la capa física complementa los paquetes con símbolos del principio y el final de los paquetes, que se toman prestados del estándar IEEE 802.3. Para los paquetes a nivel de transacción, se utilizan los símbolos K27.7 y K29.7, respectivamente; para paquetes de enlace de datos, símbolos K28.2 y K29.7.
Cuando se trabaja con núcleos de hardware FPGA, el desarrollador necesita formar solo paquetes de nivel de transacción; los paquetes de canal y capa física están formados por bloques de kernel.

Enrutamiento de paquetes a nivel de transacción


En total, los diferentes tipos de paquetes pueden llegar de remitente a receptor de tres maneras:

  • enrutamiento a la dirección;
  • Enrutamiento de ID
  • Enrutamiento indirecto.

La relación entre el método de enrutamiento y el tipo de paquete de nivel de transacción se presenta en la Tabla 3.

Tabla 3 - Correspondencia del método de enrutamiento y tipo de paquete
№p
1.
I/O I/O
2.
ID.

3ID

.


Cada punto final tiene su propio espacio de configuración, donde se encuentran varias instrucciones y registros de estado. Entre ellos se encuentran el Registro de dirección base o BAR. Al inicializar los puntos finales, el BIOS o el sistema operativo escanea la BAR de los puntos finales para determinar cuánta memoria y espacio se requiere para cada punto final. Luego, en cada BAR activa, se escribe la dirección inicial de la parte asignada de la memoria del sistema. Como resultado, el punto final adquiere una dirección donde se pueden enviar las solicitudes apropiadas. Por lo general, en el punto final, se forma un mapa de registro, que está vinculado a las áreas de memoria asignadas.

Además, cada punto final, o más bien, el dispositivo lógico en su interior, obtiene su identificador único, que consta de tres partes: número de bus, número de dispositivo, número de dispositivo lógico (función).

De esta manera, el sistema tiene suficiente información para comunicarse con el punto final. Sin embargo, la transmisión de datos mediante consultas en BAR tiene un bajo rendimiento. En primer lugar, para una BAR de 32 bits de ancho, la longitud de solicitud utilizable se limita a una palabra doble (DWORD); para un BAR de 64 bits, dos palabras dobles. En segundo lugar, cada solicitud se produce con la participación del procesador central. Para reducir la carga en el procesador central, así como aumentar el tamaño de cada paquete, es necesario que el punto final mueva de forma independiente los datos hacia o desde la memoria del sistema. Para hacer esto, el punto final debe saber en qué direcciones de memoria del sistema puede escribir o leer datos.

Dado lo anterior, el esquema general de transferencia de datos entre el punto final y la memoria del sistema se puede representar de la siguiente manera:

  1. el controlador de punto final asigna memorias intermedias en la memoria del sistema para escribir datos;
  2. el controlador forma en la memoria del sistema un conjunto de direcciones y tamaños de búfer: descriptores de búfer para escribir datos;
  3. el controlador de punto final escribe la dirección del conjunto de descriptores en los registros del dispositivo asociados con las áreas BAR;
  4. el controlador de punto final programa registros de control de transferencia de datos asociados con áreas BAR;
  5. el punto final envía una solicitud para leer la memoria del sistema para obtener un conjunto de descriptores para escribir en la memoria del sistema;
  6. el punto final envía solicitudes de escritura a la memoria del sistema y llena las memorias intermedias de almacenamiento;
  7. / , , , ;
  8. PCIe.


En la etapa en que el controlador configura los registros de punto final, dependiendo del tipo de espacio de direcciones asociado con la BAR, el punto final recibirá una solicitud de escritura en la memoria (Figura 3) o una solicitud de escritura en el espacio de E / S. Si el controlador lee un registro durante la configuración del registro, el punto final también recibe las solicitudes de lectura correspondientes (Figura 4).

imagen
Figura 3 - Ejemplo de una solicitud para escribir en la memoria 1 DW de largo


Figura 4 - Ejemplo de una solicitud para leer de la memoria 1 DW de largo

A diferencia de las solicitudes de escritura o lectura, las solicitudes de E / S tienen varias limitaciones. Primero, las solicitudes de escritura y lectura requieren una respuesta del destinatario. Esto lleva al hecho de que la velocidad de transferencia de datos mediante solicitudes al espacio de E / S se vuelve mucho más baja de lo que permite el ancho de banda PCIe teórico. En segundo lugar, la dirección de las solicitudes de espacio de E / S está limitada a 32 bits, lo que no permite el acceso a fragmentos de memoria del sistema más allá de 4 GB. Tercero, las solicitudes de espacio de E / S no pueden exceder una palabra doble y no pueden usar múltiples canales virtuales para el transporte. Por estas razones, las solicitudes de escritura y lectura en el espacio de E / S no serán consideradas más a fondo. Sin embargo,El contenido de los encabezados para escribir / leer la memoria y el espacio de E / S difiere solo en varios campos, por lo tanto, las estructuras de paquetes que se muestran en las Figuras 3, 4 también son aplicables a las solicitudes en el espacio de E / S.

Cuando un punto final o raíz PCIe recibe una solicitud para leer memoria o espacio de E / S, el dispositivo debe enviar una respuesta. Si el remitente de la solicitud no recibe una respuesta dentro de un tiempo determinado, esto conducirá a un error al esperar una respuesta. Si por alguna razón el dispositivo no puede enviar los datos solicitados, debe generar una respuesta de error. Las posibles razones pueden ser: el destinatario no admite esta solicitud (Solicitud no admitida); el destinatario no está listo para aceptar la solicitud de configuración y solicita repetirla más tarde (Estado de reintento de solicitud de configuración), se ha producido un error interno, debido al cual el destinatario no puede responder y rechaza la solicitud (Cancelación completa).

Los formatos para una respuesta exitosa a una solicitud de lectura y una respuesta de error para una solicitud no admitida se muestran en las Figuras 5, 6.


Figura 5 - Ejemplo de una respuesta exitosa para leer


Figura 6— Ejemplo de una respuesta sobre una solicitud no admitida

Mientras el punto final está accediendo a un área de memoria dentro de 4 GB, el formato de los encabezados de paquete no difiere de los encabezados que se muestran en las Figuras 3, 4. Para solicitudes de escritura o al leer la memoria más allá de 4 GB, se utiliza una palabra doble adicional con bits de orden superior de la dirección de destino en el encabezado (Figura 7).


Figura 7 - Un ejemplo de un encabezado de solicitud de escritura de 128 bytes. Las

explicaciones de los nombres abreviados de los campos de encabezado de paquete se presentan en la Tabla 4.

Tabla 4 - Lista de abreviaturas para los campos de encabezado
No. p.Designación de campoNombre del campoCita
1TCCategoría de tráfico - Clase de tráficoDefine la membresía del canal virtual
2AtrAtributos: , , ID, ID.
3TH‒ TLP Processing Hint, [1..0] .
4TD‒ TLP Digest, .
5EP, .
6AT‒ Address Translation, : , ,
7BE‒ Byte Enable
8PHSugerencia de procesamiento de paquetes - Sugerencia de procesamientoInforma al destinatario del paquete cómo se debe usar el paquete, así como la estructura de datos
9 9BCMLa presencia de un cambio en el número de bytes.Indica si la cantidad de bytes en el paquete ha cambiado. Solo un remitente frente a un dispositivo PCI-X puede establecer un indicador

Si un punto final usa interrupciones para informar un evento, también debe formar un paquete apropiado. En total, PCIe puede usar tres tipos de interrupciones:

  • interrupciones heredadas (interrupciones heredadas o INT);
  • interrupciones en forma de mensajes (interrupciones señalizadas por mensaje o MSI);
  • interrupciones de mensajes extendidos (interrupciones señalizadas de mensajes extendidas o MSI-X).

Las interrupciones INT heredadas se utilizan para compatibilidad con sistemas que no admiten interrupciones de mensajes. De hecho, este tipo de interrupción es un mensaje (un paquete de tipo Mensaje) que simula el funcionamiento de una línea de interrupción física. Ante un evento específico, el punto final envía un mensaje a la raíz PCIe de que la interrupción INT se ha activado, y luego espera la acción del manejador de interrupciones. Hasta que el controlador de interrupciones realice la acción especificada, la interrupción INT está en el estado activado. Las interrupciones heredadas no le permiten determinar el origen del evento, lo que obliga al controlador de interrupciones a explorar secuencialmente todos los puntos finales en el árbol PCIe para atender esta interrupción. Cuando se da servicio a la interrupción, el punto final envía un mensaje que indica queque la interrupción INT está más inactiva. Los núcleos de hardware FPGA, en una señal de la lógica del usuario, generan de forma independiente los mensajes necesarios para las interrupciones INT, por lo que no se considerará la estructura del paquete.

Las interrupciones de mensajes junto con su versión extendida son el tipo principal y obligatorio de interrupción en PCIe. Ambos tipos de interrupciones, de hecho, son una solicitud para escribir en la memoria del sistema con una longitud de una palabra doble. La diferencia con una solicitud regular es que la dirección de grabación y el contenido del paquete se asignan para cada dispositivo en la etapa de configuración del sistema. En este caso, el controlador de interrupción programable avanzado local (LAPIC) dentro del procesador central se convierte en el destino. Cuando se usa este tipo de interrupción, no es necesario sondear secuencialmente todos los dispositivos en el árbol PCIe. Además, si el sistema permite que el dispositivo use varios vectores de interrupción, cada vector puede asociarse con su propio evento.Juntos, esto reduce el tiempo del procesador para procesar las interrupciones y aumenta el rendimiento general del sistema.

Las interrupciones de MSI permiten la formación de hasta 32 vectores separados. El número exacto depende de las capacidades del punto final. En este caso, el sistema puede permitir el uso de solo una parte de los vectores. En la etapa de configuración, el sistema escribe la dirección de interrupción y los datos iniciales para escribir en los registros especiales del espacio de configuración del punto final. Todas las interrupciones activas usan la misma dirección. Pero para cada vector, el punto final cambia los bits de los datos iniciales. Por ejemplo, deje que un punto final admita un máximo de 4 vectores de interrupción, los 4 vectores están permitidos en el sistema y los datos iniciales para la escritura son 0x4970. Luego, para formar el primer vector, el punto final pasa los datos iniciales sin cambios. Para el segundo vector, el dispositivo cambia el primer bit y transmite el número 0x4971.Para el tercer y cuarto vectores, el dispositivo transmitirá los números 0x4972 y 0x4973, respectivamente.

Los núcleos de hardware FPGA forman independientemente un paquete con una interrupción MSI por una señal de la lógica del usuario. Sin embargo, antes de ordenar al núcleo que envíe una interrupción, la lógica del usuario también debe proporcionar el contenido del paquete para el vector requerido a una interfaz especial del núcleo.

Las interrupciones MSI-X permiten la formación de hasta 2048 vectores individuales. En los registros correspondientes del espacio de configuración, el punto final indica en cuál de los espacios de direcciones BAR y con qué desplazamiento desde la dirección base se ubican la tabla de interrupciones (Figura 8) y la tabla de indicadores de interrupción pendientes (Matriz de bits pendiente - PBA, Figura 9), así como los tamaños de ambos mesas. El sistema escribe una dirección y datos separados para escribir en cada línea de la tabla de interrupción, y también permite o prohíbe el uso de un vector específico a través del primer bit del campo Control de vectores. Para un evento determinado, el punto final establece un indicador en la tabla de indicadores de interrupciones pendientes. Si no se establece una máscara para esta interrupción en el campo Control de vectores, el punto final envía una interrupción a la dirección desde la tabla de interrupciones con el contenido especificado del paquete.


Figura 8 - Tabla de vectores de interrupción MSI-X


Figura 9 - Tabla de indicadores para interrupciones pendientes Los

núcleos de hardware FPGA no tienen una interfaz especializada para interrupciones MSI-X. El desarrollador mismo debe crear una tabla de interrupciones en la lógica del usuario y una tabla de indicadores de interrupciones pendientes. Un paquete de interrupción también es completamente generado por el usuario y transmitido a través de la interfaz general del núcleo junto con otros tipos de paquetes. El formato de paquete en este caso, como ya se mencionó anteriormente, corresponde a una solicitud de escritura en la memoria del sistema con una longitud de una palabra doble.

Características de los núcleos de hardware PCI Express FPGA V-series de Intel en la versión Avalon-ST


A pesar del hecho de que los núcleos de hardware de los FPGA PCI Express de diferentes fabricantes implementan una funcionalidad similar, las interfaces de núcleo individuales o el orden de su operación pueden diferir.
Los núcleos de hardware PCI Express FPGA Intel V-Series están disponibles en dos versiones: con Avalon-MM y Avalon-ST. Este último, aunque requiere más esfuerzo del desarrollador, le permite obtener el mayor ancho de banda. Por esta razón, no se considerará un kernel con una interfaz Avalon-MM.

La documentación principal de PCI Express con la interfaz Avalon-ST describe con suficiente detalle los parámetros del núcleo, las señales de entrada y salida. Sin embargo, el núcleo tiene una serie de características a las que un desarrollador debe prestar atención.

El primer grupo de características se relaciona con métodos que le permiten configurar FPGA dentro de los 100 ms de acuerdo con los requisitos de PCIe. Además de la carga paralela del tipo FPP, al desarrollador se le ofrecen métodos tales como la Configuración a través del Protocolo (CvP) y el modo autónomo del núcleo (modo autónomo). El desarrollador debe asegurarse de que la configuración a través del protocolo o el modo de kernel independiente sea compatible con la velocidad PCIe seleccionada (parámetro "Lane Rate"). Para la configuración a través del protocolo, se puede encontrar información relevante en la documentación del núcleo. En el caso del modo fuera de línea, no existe dicha información, por lo que debe compilar el proyecto. Si el modo de kernel independiente no es compatible con la velocidad actual del kernel, Quartus generará un error correspondiente (Figura 10).


Figura 10 - Error al compilar un núcleo PCIe para el modo fuera de línea

Si un desarrollador planea usar la configuración a través de un protocolo, también debe prestar atención a qué núcleo FPGA está conectado el conector PCIe. Esto es especialmente cierto si el desarrollador no utiliza una placa terminada, sino su propio dispositivo. En FPGA con múltiples núcleos de hardware PCIe, solo un núcleo permite que CvP esté habilitado. La ubicación del núcleo con soporte CvP se indica en la documentación de FPGA.
El segundo grupo de características se relaciona con la interfaz de transferencia de datos Avalon-ST. Es esta interfaz la que se utiliza para transferir paquetes a nivel de transacción entre la lógica del usuario y el núcleo.

En el lado receptor, el núcleo tiene dos señales que permiten al usuario pausar la recepción de los paquetes recibidos: la señal rx_st_mask y la señal rx_st_ready.
Usando la señal rx_st_ready, el desarrollador puede pausar la salida de todos los tipos de paquetes. Sin embargo, si activa esta señal, el núcleo detendrá la salida de paquetes después de solo dos ciclos de reloj de la frecuencia de operación. Por lo tanto, durante la activación de la señal, la lógica del usuario debe estar lista para recibir una cantidad adicional de datos. Si, por ejemplo, un desarrollador utiliza un búfer en forma de FIFO, debe evitar los desbordamientos del búfer. De lo contrario, se perderá parte del contenido del paquete.

Usando la señal "rx_st_mask", el desarrollador suspende la emisión de solicitudes para las cuales se deben enviar respuestas. Esta señal tampoco detiene inmediatamente la salida de paquetes. Según la documentación, después de activar la señal, el núcleo puede emitir hasta 10 solicitudes. Si la lógica del usuario activa "rx_st_mask", y no hay suficiente espacio en el búfer para procesar los paquetes recibidos, esto también puede activar la señal "rx_st_ready". En esta situación, la lógica del usuario deja de leer cualquier paquete del búfer interno del kernel de hardware. Esto no solo supera los búferes de kernel de hardware, sino que también viola los requisitos de pedido de paquetes. El dispositivo debe omitir las solicitudes que no requieren una respuesta y leer las respuestas. De lo contrario, el canal de datos se bloqueará fuertemente.Por esta razón, el desarrollador debe usar un búfer adicional para procesar las solicitudes con respuestas y no permitir que la lógica bloquee los paquetes de mayor prioridad.

En el lado de transmisión, las señales tx_st_valid y tx_st_ready pueden causar problemas. Si la señal tx_st_ready está activa, está prohibido que la lógica del usuario reinicie tx_st_valid en el medio del paquete saliente. Esto significa que durante la transferencia, el desarrollador debe proporcionar todo el contenido del paquete. Si la fuente de datos es más lenta que la interfaz del núcleo, la lógica del usuario debe acumular la cantidad de datos requerida antes del inicio del paquete.
Tanto en el lado de recepción como en el lado de transmisión, el desarrollador debe prestar atención al orden de bytes en el encabezado y al contenido del paquete, así como a la alineación de los datos.

En el paquete Avalon-ST del núcleo de hardware, dentro de cada palabra doble dentro del encabezado del paquete PCIe, los bytes siguen de menor a mayor; dentro del contenido del paquete, desde el más antiguo hasta el más joven. El desarrollador debe usar un orden similar en los paquetes salientes para transferir con éxito los datos desde el punto final a la raíz.

La interfaz Avalon-ST del núcleo del hardware alinea los datos en múltiplos de 64 bits. Dependiendo del ancho de la interfaz Avalon-ST, la longitud del encabezado del paquete a nivel de transacción y la dirección del paquete, el núcleo puede agregar una palabra doble vacía entre el encabezado del paquete y su contenido. A su vez, al transmitir datos, la lógica del usuario debe agregar una palabra doble vacía por adelantado, por analogía con el núcleo. Esta palabra doble vacía no se tiene en cuenta en la longitud del paquete y solo es necesaria para el correcto funcionamiento del núcleo del hardware.

La siguiente característica está relacionada con las respuestas de lectura entrantes. La descripción del núcleo dice que no pierde las respuestas entrantes cuyo identificador no coincide con la solicitud saliente. Al mismo tiempo, la lógica del usuario debe seguir el tiempo de espera para las respuestas. Si se supera el tiempo de espera, la lógica del usuario debe elevar el indicador "cpl_err [0]" o "cpl_err [1]". La documentación no aclara cómo funcionará el filtrado cuando el punto final envíe múltiples solicitudes de lectura. La lógica del usuario solo le dice al kernel que el tiempo de espera ha expirado para una de las solicitudes, pero no puede pasar el identificador de esta solicitud al kernel. Existe la posibilidad de que el núcleo pueda transmitir al usuario respuestas del lado de una solicitud con un tiempo de espera expirado. Por lo tanto, el desarrollador debe crear su propio filtro para las respuestas entrantes.

Finalmente, se recomienda a los desarrolladores que utilicen la información sobre préstamos disponibles para paquetes salientes. La documentación principal dice que esto no es necesario, ya que el núcleo verifica los préstamos y bloquea los paquetes cuando no hay suficientes préstamos. Sin embargo, todos los tipos de paquetes llegan al núcleo a través de una única interfaz. Si el búfer del paquete del núcleo se desborda, el núcleo reduce la señal tx_st_ready a cero. Hasta que la señal tx_st_ready se establezca en uno, la lógica del usuario, en principio, no puede enviar ningún paquete. La cantidad de préstamos disponibles se actualiza a través de paquetes desde un dispositivo asociado. Si la lógica del usuario no solo escribe a menudo, sino que también lee, la velocidad con la que el núcleo actualiza los contadores de límite disminuye. Al final, el rendimiento general del sistema sufre.

Conclusión


El artículo describe los principios generales de la transferencia de datos a través de PCI Express, los formatos de los principales paquetes de datos. Sin embargo, el autor omitió componentes de la interfaz tales como canales virtuales, control del volumen de respuestas entrantes para leer y el orden de los paquetes no es estricto. Estos temas se analizan en detalle en varias fuentes extranjeras [ 4 , 6 ].
El artículo también incluye las características de los núcleos de hardware FPGA FPGA Intel Express serie V que el autor encontró mientras trabajaba en el controlador de interfaz. Esta experiencia puede ser útil para otros desarrolladores.

Lista de fuentes utilizadas


  1. Una arquitectura PCIe DMA para transmisión de datos de varios gigabytes por segundo / L. Rota, M. Caselle, et. Alabama. // TRANSACCIONES IEEE SOBRE CIENCIA NUCLEAR, VOL. 62, NO. 3 de junio de 2015.
  2. An Efficient and Flexible Host-FPGA PCIe Communication Library / Jian Gong, Tao Wang, Jiahua Chen et. al. // 2014 24th International Conference on Field Programmable Logic and Applications.
  3. Design and Implementation of a High-Speed Data Acquisition Card Based on PCIe Bus / Li Mu-guo, Huang Ying, Liu Yu-zhi // 《测控技术》2013年第32卷第7期。
  4. Down to the TLP: How PCI express devices talk (Part I) / Eli Billauer
  5. Low-Cost FPGA Solution for PCI Express Implementation / Intel Corporation.
  6. Managing Receive-Buffer Space for Inbound Completions / Xilinx // Virtex-7 FPGA Gen3 Integrated Block for PCI Express v4.3, Appendix B
  7. PCIe Completion Timeout / Altera Forum
  8. PCIe packet in cyclone VI GX / Altera Forum
  9. PCIe simple transaction / Altera Forum
  10. PCIe w/ Avalon ST: Equivalent of ko_cpl_spc_vc0? / Altera Forum
  11. Point me in the right Direction – PCIe / Altera Forum
  12. Solicitar tiempos de espera en PCIE / Altera Forum
  13. El diseño de interfaz de alta velocidad basado en PCIe de la plataforma no cooperativa de verificación de receptores / Li Xiao-ning, Yao Yuan-cheng y Qin Ming-wei // 2016 Conferencia internacional sobre mecánica, control, electricidad, mecatrónica, información e informática
  14. Revisión de especificaciones de PCI Express Base 3.0 / PCI-SIG
  15. Interfaz Stratix V Avalon-ST para soluciones PCIe / Intel Corporation
  16. Interfaz Cyclone V Avalon-ST para soluciones PCIe / Intel Corporation

All Articles