Introducción
En una FPGA, cada puerto de E/S tiene su propia zona pequeña dentro del entramado lógico. Esta zona, denominada IOB (Input / Output Block, bloque de entrada/salida), contiene todo lo necesario para soportar las funciones de ese puerto de E/S: circuitos analógicos que garantizan las tensiones y corrientes adecuadas en el pin de E/S, además de algunos elementos lógicos especiales.
Conviene señalar que el término «IOB» pertenece a la terminología de AMD (antes Xilinx). Cada fabricante de FPGA utiliza un término distinto.
Casi siempre hay registros IOB dentro de un IOB. Estos registros son biestables (flip-flops) conectados directamente al pin del puerto de E/S.
Algunos biestables están pensados para cuando el pin actúa como puerto de entrada: la entrada D de estos biestables está conectada al pin del puerto de E/S. De este modo, un biestable de este tipo realiza el muestreo (sampling) de la señal que llega del mundo exterior.
Otros biestables están dedicados al pin cuando este actúa como puerto de salida. La salida Q de estos biestables está conectada al pin.
La estructura de los IOB varía de una FPGA a otra. Algunos IOB son complejos y están llenos de funciones, mientras que otros tienen una estructura más sencilla. Con bastante frecuencia, el registro IOB forma parte de un elemento lógico mayor, por ejemplo un SERDES. Por tanto, aunque en el dibujo de la documentación que describe el IOB no aparezcan biestables de forma explícita, es posible que los pines de E/S de la FPGA tengan registros IOB.
Por qué usar registros IOB
La principal motivación para usar registros IOB es la temporización (timing): gracias a la proximidad de estos registros al pin del puerto de E/S, el tiempo de reloj a salida (clock-to-output) que se consigue es insuperable. También para los puertos de entrada, un registro IOB es el que más posibilidades tiene de cumplir la temporización requerida.
Pero incluso cuando es fácil cumplir los requisitos de temporización, hay una buena razón para insistir en los registros IOB: la repetibilidad. De lo contrario, el retardo entre el pin del puerto de E/S y el biestable es distinto en cada implementación del proyecto de FPGA. Esto es así porque las herramientas pueden colocar el biestable en una ubicación diferente cada vez. También pueden variar el retardo de encaminamiento, siempre que se cumplan las restricciones de temporización (timing constraints). Esto no supone un problema siempre que el diseño de la placa de circuito impreso (PCB) sea correcto y la interfaz con los componentes externos esté bien planificada. Sin embargo, cuando existen este tipo de problemas, la diferencia en el retardo entre una implementación y otra puede causar confusión: algo no funciona, arreglas algo en el diseño y parece que el problema se ha solucionado. Pero lo que realmente marcó la diferencia fue un pequeño cambio en la temporización de E/S en algún punto.
El uso de registros IOB garantiza que la interfaz eléctrica con los componentes externos no cambie de forma involuntaria durante el desarrollo de la lógica de la FPGA. Esto facilita el aislamiento de los problemas cuando aparecen.
Cómo solicitar registros IOB
Puede ser necesario indicar explícitamente a las herramientas de FPGA que usen registros IOB. Normalmente, el sintetizador (synthesizer) es el encargado de hacerlo, así que se puede usar con Vivado un atributo de síntesis como este:
(* IOB = "TRUE" *) input the_input,
También es posible hacer lo mismo en el archivo XDC:
set_property IOB true [get_ports the_input]
Otra opción es añadir un atributo de síntesis al registro conectado a la entrada:
(* IOB = "TRUE" *) reg the_input_samp;
Ten en cuenta que un atributo en el archivo XDC puede no ser suficiente. Con frecuencia, se pide al sintetizador que replique registros para poder colocar biestables en el IOB. Esto es relevante cuando la salida del biestable también la usa la lógica normal de la FPGA. La razón es que la salida del biestable situado dentro del IOB solo puede utilizarse para el puerto correspondiente. Por tanto, se necesita otro biestable que produzca la misma salida para poder usarla en el entramado lógico. En esta situación suele ser necesario un atributo de síntesis (como el mostrado arriba).
Con Quartus, se pueden añadir comandos de este tipo al archivo QSF:
set_instance_assignment -name FAST_INPUT_REGISTER ON -to the_input set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to the_output
Cada herramienta tiene una forma ligeramente distinta de conseguir esto.
Restricciones de temporización
¿Hay alguna razón para escribir restricciones de temporización (timing constraints) para un puerto que utiliza un registro IOB? Después de todo, solo hay una posición posible para el registro IOB. ¿No es razonable concluir que la temporización será siempre la misma, con o sin restricciones de temporización?
Así pues, hay principalmente dos buenas razones para escribir restricciones de temporización incluso cuando se usan registros IOB.
La primera es asegurarse de que se utiliza un registro IOB: a veces, un cambio en el diseño lógico puede impedir de forma involuntaria que se usen los IOB en todos o algunos puertos. Las herramientas rara vez avisan cuando esto ocurre. En lugar de ello, se utiliza silenciosamente un biestable que no está dentro del IOB. Una restricción de temporización puede evitar esta situación: si la restricción solo se puede cumplir cuando todos los biestables implicados están dentro de sus IOB, la expulsión de estos biestables no pasará desapercibida: la restricción de temporización fallará como consecuencia.
La segunda razón es que las herramientas pueden introducir un retardo intencionado entre el pin del puerto de E/S y el registro IOB (aunque no todas las FPGA admiten esta función). La finalidad de este retardo es mejorar la temporización con respecto a thold (consulta este ejemplo con Quartus). Esta manipulación indeseada puede evitarse con una restricción de temporización que solo sea alcanzable sin ese retardo adicional.
set_max_delay suele ser la restricción de temporización adecuada para garantizar un uso uniforme de los registros IOB. Si las herramientas de FPGA admiten la opción «datapath_only» con este comando (o una función similar), aún es más cómodo.
Conclusión
Los registros IOB deberían usarse siempre que sea posible. Las herramientas de FPGA quizá no se ofrezcan a hacerlo por sí solas, así que conseguir este objetivo puede requerir un pequeño esfuerzo. La recompensa de este esfuerzo no es solo una temporización óptima, sino también un comportamiento repetible de los puertos de E/S.