Los ingenieros que desarrollan aplicaciones de prueba utilizando protocolos de comunicación digital no soportados o personalizados pueden utilizar el módulo LabVIEW FPGA para implementar o crear prototipos de diferentes interfaces de comunicación en el hardware de E/S reconfigurable basado en FPGA de la serie R. A diferencia de diseñar y construir hardware personalizado como un ASIC o escribir su propio código VHDL para ejecutarse en un FPGA, con el LabVIEW FPGA Module desarrolla, prueba y depura nuevas funcionalidades fácilmente sin necesidad de herramientas de desarrollo especializadas.
Una necesidad común en el desarrollo de sistemas de prueba en automoción, aeronáutica y una gama de otras industrias es desarrollar o implementar interfaces para la comunicación digital entre el sistema de prueba y otros dispositivos. Estos dispositivos incluyen otros sistemas de prueba u ordenadores, instrumentos, DUT, componentes de sistemas de bajo nivel como ECU y más.
Idealmente, al desarrollar un nuevo sistema de pruebas, tendrá una interfaz lista para su protocolo de comunicación digital que incluye un controlador fácil de usar para su herramienta de desarrollo de aplicaciones. Sin embargo, en muchos casos esto no es la realidad. Es posible que tenga que desarrollar una placa u otra interfaz para comunicarse con su dispositivo externo. Esto se puede hacer desarrollando su propio hardware personalizado llegando a extremos como diseñar su propio ASIC, o al menos soldar una nueva placa basada en componentes listos para usar. Sin embargo, con hardware de E/S reconfigurable y el LabVIEW FPGA Module puede diseñar su hardware personalizado utilizando solo LabVIEW y sus herramientas de programación gráfica. Su diseño de hardware personalizado se carga en la FPGA del hardware de E/S reconfigurable para crear su placa de interfaz personalizada específica para sus necesidades.
Describiremos cómo puede utilizar el LabVIEW FPGA Module para implementar una amplia gama de protocolos de comunicación en su propia placa de interfaz personalizada. Estas técnicas son aplicables tanto a las tarjetas de E/S reconfigurables PCI y PXI (serie R) como a la plataforma CompactRIO, proporcionando una carcasa resistente preparada para la industria.
Existe una amplia gama de protocolos de comunicación en uso en sistemas de prueba que van desde interfaces extremadamente comunes como RS-232 y GPIB hasta protocolos personalizados implementados por proveedores individuales y desarrolladores de aplicaciones. Las interfaces comunes, aunque no tan conocidas, incluyen la SPI (interfaz periférica en serie) y la I2C (circuito integrado) utilizadas para la comunicación dentro de los dispositivos y sistemas electrónicos y entre ellos. Estos protocolos, aunque comunes en aplicaciones, no siempre pueden ser soportados por interfaces de comunicación disponibles en una amplia gama de plataformas y entornos de software. Para tales necesidades LabVIEW FPGA y la plataforma de E/S reconfigurable son una herramienta ideal para proporcionar una solución rentable.
Los protocolos de comunicación digital pueden agruparse por sus áreas de aplicación o industrias, así como en función de la naturaleza y las especificaciones técnicas del propio protocolo. Discutiremos los detalles técnicos y la naturaleza de los diferentes protocolos en detalle en las siguientes secciones y mostraremos cómo se utiliza LabVIEW para implementarlos. Con respecto a la aplicación y la industria, a continuación se presenta un conjunto básico de categorías y protocolos de muestra que incluyen interfaces de comunicación que se han resuelto utilizando LabVIEW FPGA
Los protocolos de comunicación digital pueden clasificarse en función de su definición técnica y sus requisitos. Esta aplicación independiente de la forma de ver un protocolo ayuda a centrarse en los detalles que son importantes en la selección de la implementación óptima utilizando las herramientas de desarrollo a mano. El resto de este documento se centrará en estos criterios de clasificación y cómo se implementan los diferentes grupos de protocolos en la FPGA.
La mayoría de las interfaces de comunicación digital se dividen en una de dos categorías muy generales, serie y paralelo, dependiendo del número de señales de datos entre un emisor y un receptor. Si los datos se transfieren en una sola línea de datos, es un enlace de datos en serie, ya que todos los bits de datos se transmiten secuencialmente o en serie. Un enlace de datos paralelo tiene más de una línea de datos y a menudo un múltiplo de ocho líneas de datos. Los datos se transfieren en paralelo, comúnmente un byte o palabra a la vez. Tradicionalmente se han utilizado enlaces de comunicación tanto en serie (por ejemplo, RS-232) como en paralelo (por ejemplo, GPIB) con enlaces de comunicación paralelos que ofrecen velocidades de transferencia de datos más altas a la misma velocidad de reloj. A medida que las tasas de bits que son posibles en una sola línea de datos han aumentado en el rango de Megabit y Gigabit, los enlaces seriales se han vuelto mucho más comunes y dominantes en el mercado, ya que proporcionan una solución más rentable, reduciendo el costo de los componentes de la interfaz (por ejemplo, controladores de línea), así como el costo del cableado. Tanto en las interfaces de comunicación en serie como en las paralelas puede haber líneas de señal adicionales utilizadas para sincronizar y activar, así como para la comunicación de control y comandos.
Una segunda clasificación básica de la interfaz de comunicación física son los niveles de tensión y la referencia a tierra que se utilizan para las líneas de señal digital. Los bits de datos y otra información son transferidos por los diferentes niveles de voltaje de las líneas de señal, pero puede haber una diferencia significativa en los niveles de voltaje utilizados entre diferentes tipos de interfaces. En una señal digital de un solo extremo, el nivel de tensión de una línea de señal se mide en relación con una referencia a tierra común. Una señal digital diferencial consiste en dos señales no referenciadas y el nivel de tensión entre las dos líneas de señal representa el valor de la señal. Las señales diferenciales son más inmunes al ruido captado por las líneas de señal y normalmente se pueden utilizar para transferir señales a mayor distancia. Los niveles de voltaje específicos utilizados en la comunicación digital están referenciados por estándares como TTL, CMOS y LVDS y no se abordan en la implementación del protocolo en el FPGA. Las entradas y salidas digitales en el hardware de E/S reconfigurable utilizan niveles de voltaje compatibles con TTL/CMOS. Si se requieren otros niveles, es necesario insertar un convertidor/traductor de señal entre el hardware de interfaz y el enlace de comunicación.
A medida que analizamos un protocolo y pensamos en su implementación en LabVIEW FPGA necesitamos identificar las diferentes líneas de señal utilizadas por el protocolo y el propósito de cada señal. El número de líneas de señal utilizadas por el protocolo determinará cuántos recursos de hardware necesitamos configurar en el proyecto LabVIEW y cuántas líneas digitales estaremos utilizando en el diagrama LabVIEW. El siguiente diagrama de tiempos (figura 1), que muestra el protocolo SPI (Serial Peripheral Interface), ilustra el uso de tres líneas de señal que necesitamos gestionar en la implementación de este protocolo.
Figura 1: Diagrama de temporización simple del protocolo SPI con una línea de datos
Al comenzar la implementación nos damos cuenta de que para convertir el diagrama de tiempos en el código FPGA LabVIEW correspondiente, nos preocupamos por dos cosas: encender y apagar las líneas digitales y esperar la cantidad de tiempo adecuada entre establecer el estado de las diferentes líneas digitales. En aplicaciones donde estamos leyendo un protocolo digital nos preocupa leer el estado de las líneas digitales y anotar la cantidad de tiempo entre cualquier transición en cada línea de señal. Normalmente, la salida de un protocolo digital es más fácil de implementar y, por lo tanto, abordaremos este caso primero.
Uno de los siguientes criterios que utilizamos para clasificar un protocolo es la fuente de reloj utilizada por el protocolo. Las dos categorías principales son los protocolos síncronos y asíncronos. Los protocolos síncronos incluyen una señal de temporización específica en el protocolo, mientras que los protocolos asíncronos se temporizan usando una tasa de bits definida.
Un ejemplo típico de protocolo síncrono es el protocolo SPI mostrado en el diagrama de temporización anterior. El protocolo incluye una señal de reloj dedicada que permite a cualquier receptor utilizar la línea de reloj como base de tiempo para leer o escribir la línea de datos. Probablemente el protocolo asíncrono más conocido es el bus serie (RS-232) utilizado en muchos PC. Al usar el bus serie especificamos la velocidad de baudios (bits por segundo) del dispositivo con el que estamos comunicando. El emisor y el receptor utilizan la velocidad de baudios para actualizar o leer la señal de datos a la misma velocidad. Debido a que la fuente de tiempo no será exactamente la misma en ambos extremos de la comunicación, los paquetes de datos de comunicación asíncronos son de longitud limitada para evitar la desalineación de bits. La comunicación asíncrona necesita resincronizarse con frecuencia para permitir ligeras diferencias de tiempo. Los protocolos de comunicación síncrona por otro lado pueden comunicarse continuamente ya que están sincronizados en cada bit de datos.
Cuando implementamos una señal de reloj como parte de un protocolo síncrono, el reloj FPGA se utiliza para determinar la base de tiempo del protocolo y actualizar la señal de reloj en consecuencia.
Figura 2: Diagrama LabVIEW FPGA que genera una señal de reloj de 10 us (100 kHz)
Para un protocolo asíncrono no se genera una señal de reloj separada, pero el reloj FPGA y la velocidad de baudios definida se utilizan para determinar cuándo actualizar o leer la señal o señales de datos.
Figura 3: Diagrama FPGA LabVIEW actualizando la línea de datos a 4800 baudios
(8333 ciclos de reloj FPGA = 208,3 us = 1/4800 Hz)
Basándose en la velocidad especificada por la señal de reloj o especificación de temporización, los datos se codifican en la señal de datos o se leen de la señal de datos y luego se decodifican. La codificación de los datos se puede realizar en varios formatos diferentes. El método más común es representar el valor de un bit de datos por uno o varios estados de la señal de datos. Esta clase general de métodos de codificación se llama Modulación por Código de Pulsos (PCM).
El subconjunto de métodos PCM en los que el bit de datos está representado por un solo estado de la señal de datos se denominan Sin retorno a cero (NRZ). Por ejemplo, una señal de datos alta representa un bit '1', mientras que una señal de datos baja representa un bit '0'. Este método se llama NRZ-L ya que el nivel de la señal de datos representa el bit de datos. En algunos protocolos, como RS-232, esta lógica se invierte donde el estado alto representa '0', y el estado bajo representa '1'. Esto se llama NRZ-I (inverso). Los subtipos NRZ adicionales son NRZ-M (marca) y NRZ-S (espacio) donde el valor de bit de datos '1' se representa por un cambio en la señal de datos (NRZ-M) o un '0' se representa por un cambio de la señal de datos (NRZ-S).
Figura 4: Métodos de codificación NRZ (sin retorno a cero)
La modulación de código de pulso incluye otro conjunto de esquemas de codificación que combina la señal de reloj y la señal de datos en una línea de datos; cada bit está representado por múltiples estados de la señal de datos. Estos se llaman codificación bifásica y el esquema de codificación común de Manchester es un tipo de codificación bifásica.
Otros esquemas de codificación más avanzados incluyen diferentes formas de codificación de ancho de pulso. El esquema de modulación por ancho de pulso (PWM) comúnmente utilizado convierte un valor analógico directamente en el ancho de pulso variable de un tren de pulsos de frecuencia constante. Otras formas de codificación de ancho de pulso usan dos anchos de pulso diferentes para representar un bit '0' y '1' en una secuencia de bits tradicional.
Ahora que tenemos una nomenclatura básica para describir protocolos comunes podemos ver cómo implementar protocolos en LabVIEW FPGA. Para implementar un protocolo en LabVIEW FPGA normalmente comenzamos caminando por el diagrama de tiempos y convirtiendo los cambios de estado de las diferentes líneas de señal y el tiempo entre estos cambios en las funciones y estructuras LabVIEW correspondientes. Cada cambio de estado de una línea digital se implementa utilizando el nodo de E/S FPGA y la temporización se implementa utilizando las funciones de temporización LabVIEW FPGA (Loop Timer y Wait). Los pasos del diagrama de tiempos que se repiten varias veces se implementan utilizando el bucle For o While. Para protocolos más extensos, grupos de funciones y estructuras pueden encapsularse en subVI para permitir la reutilización del código y hacer que el código sea más modular y manejable.
Como primer ejemplo implementamos el diagrama de temporización SPI mostrado anteriormente en la Figura 1 anterior. La comunicación mediante el protocolo SPI consiste en paquetes de datos enviados entre dos dispositivos. En la comunicación SPI hay un dispositivo maestro que controla la señal ChipSelect y la señal Clock. Puede haber uno o más dispositivos esclavos con línea de señal ChipSelect dedicada desde el maestro a cada esclavo y una línea de datos común para todos los dispositivos. Si la aplicación incluye comunicación en ambas direcciones entre maestro y esclavo(s), comúnmente se usan dos líneas de datos; estas se etiquetan Master Out Slave In (MOSI) y Master In Slave Out (MISO). En nuestro ejemplo solo nos centraremos en una línea de datos.
Figura 5: Diagrama de cableado para la comunicación SPI entre dos dispositivos
Las transferencias de paquetes siempre son iniciadas por el dispositivo maestro afirmando la línea ChipSelect del dispositivo esclavo al que se dirige. Comúnmente, la línea ChipSelect está activa baja de modo que permanece en un estado alto cuando el sistema está inactivo y es bajada por el maestro para iniciar una transmisión. Después de la afirmación de la señal ChipSelect, el maestro actualizará la línea de datos y luego alternará la línea de reloj para transferir cada bit de datos al esclavo. El contenido del paquete de datos es específico de la aplicación y se deja a la definición del desarrollador y diseñador del dispositivo.
En el diagrama FPGA LabVIEW correspondiente (ver figura 6 a continuación) cada transferencia de datos se inicia configurando el control booleano 'Write'. Esto provoca la ejecución del caso True. Inicialmente, la línea ChipSelect (SPI CS*) se afirma bajando la salida digital. Al mismo tiempo, el valor de datos 'Data Out' se convierte en la secuencia de bits correspondiente (matriz booleana). La función de espera de un microsegundo (1us) proporciona tiempo para que el dispositivo esclavo esté listo para los siguientes bits de datos. A continuación, se repite una secuencia de actualización de la línea de datos y de conmutación de la línea de reloj 16 veces en el bucle For. Cada bit de la matriz booleana se envía a la línea de datos (SPI DOUT), seguido de la línea de reloj (SPI SCLK) que se establece primero alto y luego bajo. La función Loop Timer permite que el bucle funcione a intervalos de 2 us, mientras que la función Wait controla la longitud de la fase alta de la señal de reloj para que sea de 1 us, generando una señal de reloj de 500 kHz del 50% del ciclo de trabajo. Después de que se hayan generado los 16 bits, las líneas de datos y de selección de chip se devuelven a su estado inactivo y se inserta la función de espera de tiempo inactivo mínimo de 5 us. En este punto la FPGA está lista para el siguiente comando Write.
Figura 6: Diagrama FPGA LabVIEW de una implementación de salida SPI simple
Basándose en la especificación de los dispositivos SPI que se utilizan y la aplicación, cualquiera de los parámetros de comunicación (por ejemplo, número de bits de datos a transferir, frecuencia de la señal de reloj, etc.) se puede ajustar en el diagrama o se puede controlar dinámicamente mediante un control en el panel frontal del LabVIEW FPGA VI.
Si es necesario, la dirección de cada una de las líneas digitales utilizadas en la aplicación puede establecerse mediante programación utilizando el nodo de método de E/S Set Output Enable FPGA (véase la figura 7).
Figura 7: LabVIEW FPGA inicialización de líneas digitales
Implementar la parte de entrada de un protocolo puede presentar algunos desafíos únicos, ya que el código debe ser más flexible en la detección y procesamiento del protocolo. En lugar de actualizar las líneas de salida digitales e insertar los retardos apropiados, el código monitorea el estado de las diferentes líneas digitales y, si es necesario, mide el tiempo entre transiciones específicas en las líneas de señal.
El siguiente ejemplo muestra una implementación de entrada SPI básica, correspondiente al ejemplo de salida SPI anterior. Mientras está en el estado inactivo, la FPGA está monitoreando la línea ChipSelect y detecta cualquier borde que caiga. En respuesta a un borde descendente, comienza a monitorear la línea de reloj. Para cada uno de los 16 bordes ascendentes de la señal de reloj, la FPGA lee la señal de datos y almacena el valor de bit en una matriz booleana preasignada. Al final del paquete de datos, después de 16 ciclos de reloj, la matriz booleana se convierte a un valor de datos entero y se pone a disposición en el panel frontal del VI.
Figura 8: Diagrama FPGA LabVIEW de una implementación de entrada SPI simple
Debido a la naturaleza del protocolo SPI, este ejemplo no necesita realizar ninguna medición de tiempo, ya que toda la temporización está directamente controlada por bordes en el protocolo.
En esta sección abordamos una serie de temas adicionales a tener en cuenta al desarrollar un protocolo de comunicación digital usando LabVIEW FPGA.
En los ejemplos SPI anteriores, cada línea de señal solo es accionada por un único dispositivo. Sin embargo, en muchos protocolos las líneas de señal pueden ser accionadas o controladas por más de un dispositivo dependiendo del estado del bus o la comunicación. Esto permite que más del dispositivo inicie la transmisión en el bus o utilice la misma línea de datos para enviar y recibir datos. Típicamente esto se logra usando un circuito de colector abierto/drenaje abierto. En esta configuración, un dispositivo solo puede conducir o tirar de una línea de señal a nivel bajo, pero dejará que la línea de señal flote cuando quiera establecer la línea alta o no conducir la línea. Además de cada dispositivo que está conectado a una línea de señal, la línea de señal también tiene una resistencia de elevación a un voltaje establecido para establecer el alto voltaje de la línea si ninguno de los dispositivos conectados está impulsando la señal baja. Usando esta configuración, cualquier dispositivo puede conducir la línea baja sin crear una disputa de voltaje entre diferentes dispositivos. Tales señales se definen típicamente como activas-bajas, lo que significa que la línea está en un estado alto cuando el bus está inactivo y un dispositivo afirmará la señal tirando de la línea baja. Las señales activas-bajas a menudo se indican mediante una barra a través del nombre de la señal o un asterisco después del nombre de la señal, como en el caso de la señal ChipSelect* (SPI CS*) utilizada en los ejemplos anteriores.
Para implementar una señal de colector abierto en LabVIEW FPGA utilizamos la capacidad de controlar la dirección de la línea digital para cambiar entre conducir una línea baja y dejarla flotar. En LabVIEW FPGA el método de E/S Node se utiliza para habilitar o deshabilitar una línea de salida digital. Mientras una línea está deshabilitada, la FPGA no conduce la línea digital y permite que flote alto. Para bajar la línea cuando está activada, establecemos los datos de salida en False. Datos de salida es un registro de software que mantiene su valor independientemente de si la línea está configurada para accionar o flotar la línea.
Las siguientes figuras muestran un ejemplo de una configuración de colector abierto en LabVIEW FPGA para el protocolo I2C (circuito integrado). I2C se utiliza en aplicaciones similares a SPI para comunicarse con diferentes tipos de circuitos integrados, como EEPROM, ADC, DAC, etc. El bus I2C solo tiene dos líneas de señal, reloj y datos, y cada una es una línea de colector abierto. Para seleccionar el receptor adecuado para una comunicación, el emisor transmite primero una dirección de dispositivo única que especifica el dispositivo receptor.
Para inicializar el VI para la comunicación de colector abierto, las dos líneas de señal (SCL y SDA) están deshabilitadas para poner el bus en el estado inactivo. Los datos de salida para cada señal se establecen en Falso. A partir de este punto, el estado de cada línea se controla mediante el método Set Output Enable para habilitar la línea y conducirla a nivel bajo o para desactivarla y dejarla flotar a nivel alto.
Figura 9: Configurar dos líneas digitales para la comunicación de colector abierto
Para iniciar una transmisión en el bus I2C, el emisor transmite una condición de inicio accionando la línea de datos (SDA) a nivel bajo seguido de accionar la línea de reloj (SCL) a nivel bajo.
Figura 10: Implementar la condición I2C Start en el bus
Para transmitir un bit de datos en el bus I2C (véase la figura 11), el emisor actualiza la línea de datos (1° fotograma) y luego alterna la línea de reloj alta (2° fotograma) y baja (4° fotograma).
En el protocolo I2C después de transferir cada byte de datos (8 bits), se inserta un ciclo de reloj adicional en la comunicación para permitir que el dispositivo receptor reconozca la recepción exitosa del byte anterior. Para este propósito, el receptor baja la línea de datos durante el 9o ciclo de reloj. En el lado del remitente en nuestro ejemplo esto se implementa enviando un bit de datos alto y comprobando el estado real de la línea de datos (3er cuadro) durante el ciclo de reloj. A pesar de que el emisor está dejando que la línea de datos flote alto, el valor de datos real debe ser bajo ya que el receptor está tirando de la línea de datos bajo para acusar recibo del último byte de datos.
Figura 11: Transmitir un bit de datos en el bus I2C
El modelo de referencia OSI (Open Systems Interconnection) es una representación de las diferentes capas lógicas de un protocolo de comunicación incluyendo la aplicación que está utilizando el protocolo de comunicación. Se utiliza para definir y comprender mejor los diferentes aspectos de un protocolo y una red.
Figura 12: Modelo de referencia OSI
La capa 1 es la capa física que se ocupa de los detalles eléctricos y mecánicos que proporcionan la capacidad de enviar datos a través de un portador. Los paquetes asíncronos simples operan a este nivel.
La capa 2 proporciona una definición básica de los datos de nivel de bits y bytes, así como modulación más allá de NRZ y sincronización.
El siguiente par de capas se ocupan del direccionamiento, definición de paquetes de datos, comprobación de errores, etc.
Como podemos ver en nuestros ejemplos, la FPGA opera en la Capa Física L1 interconectando directamente con cada una de las líneas digitales de entrada y salida a nivel eléctrico. Esto significa que nosotros, como desarrolladores de un protocolo de comunicación digital en LabVIEW FPGA, somos responsables de todas las capas del modelo de referencia en lo que respecta al protocolo y la aplicación. Para muchos protocolos más simples esto solo requerirá un poco más de programación que lo que hemos hecho hasta ahora, para agregar una interfaz en la parte superior de la capa de protocolo para permitir que la aplicación interactúe con la FPGA y use el protocolo. Sin embargo, para protocolos más avanzados podemos necesitar significativamente más programación para proporcionar estas capas de protocolo intermedias, como la detección y manejo de errores a nivel de bus, la construcción y análisis de paquetes, el manejo de diferentes tipos de paquetes, etc.
Como hemos visto, el calendario desempeña un papel muy importante en el desarrollo de una aplicación del protocolo. Los datos y las líneas de reloj deben actualizarse a intervalos precisos. Al decodificar un protocolo es importante medir con precisión estos mismos intervalos. Es importante tener en cuenta el comportamiento temporal de la FPGA cuando desarrollamos protocolos de comunicación para garantizar que nuestra implementación cumpla con los requisitos y especificaciones del protocolo.
La FPGA funciona en una frecuencia de reloj base y todas las funciones de temporización se basan en la misma frecuencia de reloj. Para LabVIEW FPGA la frecuencia de reloj predeterminada de FPGA es de 40 MHz, de modo que cada ciclo de reloj y unidad de tiempo es de 25 nanosegundos (ns). En LabVIEW FPGA podemos especificar intervalos de tiempo para las funciones de temporización en unidades de milisegundos, microsegundos y ticks. Cada tic corresponde a un ciclo de reloj o 25 ns. Esto significa que la resolución más alta que tenemos para especificar cualquier retardo o tiempo de iteración de bucle es de 25 ns. Si bien esto suena muy preciso, cuando tomamos la inversa y determinamos las posibles frecuencias que podemos generar vemos el efecto que tiene a tasas más altas.
Para generar una tasa de actualización de 1 MHz para una línea digital podemos usar una función Loop Timer establecida para 40 ticks.
1 MHz => 1 us = 1000 ns
1000 ns / 25 ns por garrapata = 40 garrapatas
¿Y si queremos una tasa de actualización de 1,25 MHz?
1,25 MHz = > 0,8 us = 800 ns
800 ns / 25 ns por tic = 32 ticks
Para 1,25 MHz usamos un retardo de 32 ticks. ¿Y si queremos una tasa de actualización de 1,1 MHz?
1,1 MHz => 0,9091 us = 909,1 ns
909,1 ns / 25 ns por garrapata = 36,36 garrapatas
Como no podemos elegir ciclos de reloj parciales específicos tendríamos que elegir 36 ciclos de reloj lo que supone un retardo de 900 ns y corresponde a una frecuencia de 1,111 MHz. La siguiente frecuencia más baja que podríamos usar es de 37 ticks o 1,081 MHz. Así que vemos que usando el reloj FPGA de 40 MHz podemos actualizar las líneas digitales a 1,081 MHz o 1,111 MHz, pero no entre medias.
Utilizando las propiedades y recursos de reloj de FPGA en el proyecto LabVIEW tenemos la opción de cambiar la frecuencia de reloj base de FPGA a 80 o 120 MHz. Esto hará funcionar la FPGA a una frecuencia más alta y mejorará la resolución de temporización de las funciones de temporización. Sin embargo, la frecuencia de reloj más alta también reducirá la cantidad de complejidad que se puede utilizar en el diagrama FPGA VI y compilar con éxito para la FPGA.
Al planificar la implementación de un protocolo cronometrado, debe determinar si la resolución de temporización de la FPGA es adecuada para las necesidades del protocolo y la aplicación. Esto es especialmente importante para el tiempo requerido para generar un protocolo como los cálculos anteriores han demostrado. Para la lectura y decodificación de protocolos, a menudo es adecuado poder leer las líneas de señal a una velocidad mayor que la velocidad de actualización más alta del protocolo. Deberíamos poder muestrear las señales al menos el doble de rápido que la tasa de actualización para estar seguros.
Si necesitamos hacer mediciones de tiempo en una señal de entrada para decodificar los datos contenidos en el protocolo, entonces necesitamos hacer cálculos adicionales para determinar la resolución de temporización requerida para decodificar con precisión el protocolo.
Las máquinas de estado pueden ser una técnica útil para implementar la codificación o decodificación de un protocolo de comunicación digital. En LabVIEW se pueden implementar fácilmente máquinas de estado utilizando el bucle While y una estructura Case para representar cada uno de los diferentes estados.
La máquina de estados ayuda en el desarrollo de protocolos de comunicación ya que descompone de forma natural el diagrama de tiempos en pasos separados y podemos convertir cada uno en un estado separado en el diagrama FPGA de LabVIEW. Esto aísla cada paso del programa y reduce la complejidad de la programación en cualquier parte de la implementación. Además, simplifica las operaciones genéricas, como el manejo de errores y excepciones, permitiéndonos saltar desde cualquier parte de la ejecución del protocolo a estados especiales de manejo de errores. A veces las especificaciones del protocolo se escriben en términos de una máquina de estado, que luego puede traducir directamente en un diagrama de estado LabVIEW.
Para el diagrama de temporización de SPI en la figura 1, los siguientes pasos son una posible manera de descomponer el diagrama de temporización en una máquina de estados.
Observamos que hay cinco pasos únicos, aunque algunos de ellos se repiten para cada bit de datos. Originalmente implementamos estos pasos repetidos en un bucle For. En la máquina de estados creamos un estado único para cada uno de estos cinco pasos y luego los recorremos en ciclo. Para los tres pasos repetidos que actualizan la línea de datos y alternan la línea de reloj, configuramos la máquina de estados para que repita esta secuencia 16 veces antes de continuar con el último paso. En la máquina de estados LabVIEW esto se implementa usando un contador en un registro de desplazamiento del bucle While.
Otra ventaja de la arquitectura de máquina de estados es que nos permite implementar una implementación de protocolo dentro de un LabVIEW FPGA Single Cycle Timed Loop (SCTL). El SCTL proporciona una ejecución más rápida del diagrama FPGA de LV, permitiendo que cada ciclo del bucle se ejecute en un ciclo de reloj. Esto nos permite actualizar una línea de señal a la frecuencia de reloj base de FPGA. El SCTL también optimiza la generación de código para que el código en la FPGA sea más eficiente y use menos bienes raíces de la FPGA. Sin embargo, hay varias restricciones en el código implementado dentro de un SCTL. Por ejemplo, solo podemos acceder a cada una de las líneas de señal una vez por iteración SCTL. Por lo tanto, necesitamos definir los estados de nuestra máquina de estados de manera que solo leamos o actualicemos cada línea de señal una vez por estado.
Los siguientes diagramas (figura 13) muestran la implementación del protocolo de salida SPI utilizando una máquina de estado dentro de un SCTL. El estado Ocioso espera a que el comando Write inicie la salida del siguiente paquete de datos. También convierte el valor de los datos en una matriz booleana para la operación de salida. El siguiente paso Establecer CS afirma la línea ChipSelect. Luego comenzamos a emitir los bits de datos. En Restablecer reloj actualizamos la línea de datos con el siguiente valor de bit y restablecemos la señal de reloj. En Set Clock establecemos la señal de reloj que activa el receptor para leer la señal de datos. En este par de estados incrementamos un contador en un registro de desplazamiento, que selecciona el valor de datos adecuado de la matriz booleana para enviar a la línea de datos. Después de emitir el bit 16, hacemos la transición al estado Reset CS que restablece todas las líneas de señal al estado inactivo del bus. De ahí volvemos al estado Ocioso y esperamos el siguiente comando Write.
Figura 13: Implementación de la salida SPI en un solo ciclo de bucle temporizado
La codificación o modulación bifásica es un tipo muy común de codificación de datos utilizada en muchos protocolos diferentes. Combina la señal de datos y la señal de reloj en una línea de señal, reduciendo las necesidades de cableado y mejorando significativamente la integridad de los datos en distancias de cableado más largas.