Diseño de un Time-to-Digital Converter en FPGA Xilinx Artix-7
Abstract
La versatilidad de las FPGAs permite un uso muy amplio en el ámbito de la investigación, debido a su capacidad de interconexión de diferentes elementos lógicos y la parametrización de estos, a través de un entorno de desarrollo. Este proyecto trata de codificar un intervalo temporal en dígitos binarios, ayudándose del código termométrico. Vivado 2021.1 es el sofware de desarrollo que soporta nuestra FPGA de la familia Artix-7, cuyo comportamiento es modelado por los algoritmos de nuestro proyecto. Con esto se pretende analizar el comportamiento en simulación y proponer su estudio experimental como línea de investigación futura.
Full text
Proyecto Fin de Carrera Ingeniería de Telecomunicación Diseño de un Time-to-Digital Converter en FPGA Xilinx Artix-7 Autor: Manuel Naranjo Carrizosa Tutores: Fernando Muñoz Chavero Francisco Rogelio Palomo Pinto Dpto. Ingeniería Electrónica Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024 Universidad de Sevilla
Proyecto Fin de Carrera Ingeniería de Telecomunicación Diseño de un Time-to-Digital Converter en FPGA Xilinx Artix-7 Autor: Manuel Naranjo Carrizosa Tutores: Fernando Muñoz Chavero Francisco Rogelio Palomo Pinto Dpto. Ingeniería Electrónica Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024
Proyecto Fin de Carrera: Diseño de un Time-to-Digital Converter en FPGA Xilinx Artix-7 Autor: Manuel Naranjo Carrizosa Tutor: Fernando Muñoz Chavero El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario:
Acuerdan otorgarle la calificación de: Sevilla, 2013 El Secretario del Tribunal
AGRADECIMIENTOS En primer lugar, me gustaría agradecer a mi tutor Fernando Muñoz Chavero por su confianza en mí y en este proyecto, a pesar de los obstáculos y dificultades que ha conllevado. Su orientación y experiencia han sido fundamentales para la realización de este trabajo. Por descontado, le doy las gracias a mi familia por su apoyo incondicional a lo largo de este duro pero satisfactorio camino, que, a parte de proporcionarme conocimientos técnicos; me ha hecho mejorar como persona. Finalmente, agradezco a todos los profesores de la titulación, que siempre han estado dispuestos a ayudar; al igual que compañeros de carrera, que me llevo como amigos.
RESUMEN La versatilidad de las FPGAs permite un uso muy amplio en el ámbito de la investigación, debido a su capacidad de interconexión de diferentes elementos lógicos y la parametrización de estos, a través de un entorno de desarrollo. Este proyecto trata de codificar un intervalo temporal en dígitos binarios, ayudándose del código termométrico. Vivado 2021.1 es el sofware de desarrollo que soporta nuestra FPGA de la familia Artix-7, cuyo comportamiento es modelado por los algoritmos de nuestro proyecto. Con esto se pretende analizar el comportamiento en simulación y proponer su estudio experimental como línea de investigación futura.
Figura 5.9 Simulación Reinicio Fine_TDC 35 Figura 5.10 Bloques línea de acarreo 36 Figura 5.11 Retardos Bloques Carry4 36 Figura 5.12 Simulación Value_fine_teórico = 0 36 Figura 5.13 Simulación Value_fine_teórico = 128 37 Figura 5.14 Simulación Value_fine_teórico = 256 37 Figura 5.15 Esquema lógico interconexión módulo CARRY4 - biestables 38 Figura 5.16 Particularización salida Fine_tdc 38 Figura 5.17 Fase Reinicio Codificador Termómetro - Binario 39 Figura 5.18 Simulación salida codificador Bin[7:0]_teórico = 0 39 Figura 5.19 Simulación salida codificador Bin[7:0]_teórico = 100 39 Figura 5.20 Simulación salida codificador Bin[7:0]_teórico = 128 39 Figura 5.21 Simulación salida codificador Bin[7:0]_teórico = 200 40 Figura 5.22 Simulación salida codificador Bin[7:0]_teórico = 256 40 Figura 6.1 Fichero restricciones 43
ÍNDICE DE TABLAS Tabla 5.1 Análisis retardos 27 Tabla 5.2 Análisis retardos línea de acarreo 34 Tabla 5.3 Valores salida sistema 34
1 INTRODUCCIÓN La forma tradicional de aprender y enseñar sistemas digitales ha ido cambiando en las últimas décadas mediante el uso de lenguajes de descripción de hardware (HDL) y FPGAs (Field Programmable Gate Array) [1].Estos procesadores se están posicionando como una solución perfecta para muchas aplicaciones en el campo de IoT, la informática perimetral y las tecnologías específicas para la inteligencia artificial. Su capacidad de ser programadas para usos concretos y su gran versatilidad están convenciendo a la industria, y cada vez hay más plataformas de este tipo en sectores innovadores. La versatilidad de este dispositivo semiconductor proviene de un vasto número de elementos básicos de lógica electrónica, cuya interconexión es programable (“de forma indirecta”). Este trabajo tiene como objetivo el diseño y la implementación de un ‘TDC’, para su estudio, análisis y juicio comparativo de los procesos de simulación y experimentación. Para el desarrollo de este proyecto, se utiliza una placa Basys 3, es decir, una FPGA Xilinx de la familia Artix-7, con número de pieza Xilinx “XC7A35T-1CPG236C” [2] En cuanto al software que soporta y puede gestionar dicho hardware, el entorno de desarrollo ‘Vivado 2021.1’ es el elegido en este proyecto. Las bases teóricas del proyecto, junto con los algoritmos que se implementarán para su desarrollo, son descritos detalladamente en el portal web https://sps.ewi.tudelft.nl/fpga_tdc/TDC_basic.html (actualmente no disponible). 1.1 Objetivo y alcance El objetivo de este proyecto radica en el estudio de un TDC (time to digital converter), es decir, un dispositivo que dado un periodo de tiempo determinado, proporciona una secuencia de datos binaria equivalente; además, esta cadena binaria se codifica como un número binario en una etapa posterior. Esta definición se desarrolla de forma más detallada en índices posteriores. Se ha procedido a describir el diseño mediante el lenguaje .vhdl de forma modular haciendo uso del IDE Vivado antes mencionado; además de los ficheros de restricciones .xdc y otras utilidades. Este modelo pasa por varios procesos hasta que se genera el fichero .bit, aquel que puede cargarse en la memoria de la Basys3. Estos procesos corresponden a la síntesis, que genera un circuito digital a partir de una descripción en VHDL; y a la (posterior) implementación, que ruta este circuito según restricciones y recursos. Además, será necesario comprobar el correcto funcionamiento mediante simulaciones antes de generar dicho archivo. Para el estudio de dicho conversor se llevarán a cabo las fases de simulación y experimentación. El procedimiento de la etapa de simulación ha consistido en examinar los retrasos inducidos por los componentes lógicos críticos para el diseño, para su posterior estudio y comparación con los resultados obtenidos en la segunda fase.
2 Introducción 1.2 Propósito del proyecto: La elección de plantear este proyecto, estriba en la gran resolución temporal que los TDC pueden llegar a ofrecer. Por ello este dispositivo es de vital importancia en aplicaciones que requieren una alta resolución como los LIDAR (Light Detection and Ranging), que precisa de medir el tiempo de un pulso láser reflejado en un objeto para volver al transmisor; o en física de alta energía, llegándose a usar en detectores de partículas. [3] Además, se puede proponer como línea de investigación el uso conjunto y sincronizado del dispositivo “TDC” junto con un “ADC”. Estos convertidores trabajan conjuntamente en los sensores de imagen CMOS de alta velocidad [4]
2 FUNDAMENTOS CONCEPTUALES 2.1 Carrychain Con el propósito de diseñar un TDC, se procede a implementar como estructura lógica un ‘Carrychain’; se trata de una línea de retraso temporal (Figura 2.1). Esta hilera está formada por bloques ‘Carry’ , es decir, módulos de operadores suma cuya salida devolverá el acarreo resultante de la operación.(Figura 2.2). La importancia de esta entidad (se define como tal) radica en la inducción de un retraso temporal del pulso que excita su entrada. 2.2 Slot “START – STOP” Para la realización de este proyecto, se considera una franja temporal ∆𝑻 como la entrada TDC. Para definir esta diferencia de tiempos, flancos de subida de 2 pulsos han referenciado inicio y final de dicho ‘slot’ (aunque con algunos matices como veremos al especificar el diseño). Denominamos los instantes ‘START’ y ‘STOP’ para designar dichos límites del periodo (Figura 2.3). 2.3 Código termométrico Para poder interpretar de manera compacta y compendiada el resultado del TDC (tanto experimental como tras una simulación), se hace uso de una etapa llamada “Therm_to_bin”; que codifica a binario un número determinado de líneas de pulso (valores binarios en última instancia). La cantidad total de dichas señales corresponde a una potencia binaria predefinida. Llamamos código termométrico a un valor de 1’s y 0’s , obtenido según qué líneas de pulso de nuestro diseño están activas y cuáles no, en un instante de tiempo concreto. El valor resultante de nuestro código puede ser representado como una función escalón unitaria; el instante de permutación 0 – 1 de la función corresponde con el primer índice cuyo valor es ‘1’(esta analogía es inválida para el caso en el que el valor del código termométrico es ‘0’). Dicho código termométrico se basa en la escala termométrica, cuya correcta representación estriba en la medición de un intervalo (franja temporal de entrada ∆𝑻) dividido en partes iguales, tras definir 2 puntos de referencia (‘START’ y ‘STOP’) [5]
4 Problemas Conceptuales Figura 2.1 Carrychain Figura 2.2 Bloque Carry Figura 2.3 Franja temporal de entrada ∆T del TDC
3 PLANTEAMIENTO Esta sección trata de describir las siguientes partes del proyecto de forma funcional; antesala de la descripción cualitativa y estructural del diseño. 3.1 Delay Line La línea de retraso se basa en la estructura ‘Carrychain’ antes definida, así, se determina su configuración de la siguiente manera. En primer lugar, definimos el bloque ‘Carry’ con 3 entradas y 1 salida (Figura 2.1), cuya respuesta devuelve el acarreo resultante de una suma binaria. Atendiendo al primer bloque de la cadena de dichas instancias, 2 de sus 3 entradas son estimuladas con niveles lógicos bajo y alto respectivamente, es decir, en el plano lógico se nos presenta una suma binaria “1 + 0”; a priori, el valor de acarreo equivale a ‘0’ , cifra que permuta en el instante en el que un estado alto de la señal excita la entrada restante (la llamaremos CI), y que, hace cambiar, en consecuencia, la salida del bloque a ‘1’. Este bit alto se propagará a lo largo de los módulos ‘Carry’, vagando así, por la línea de retraso. Es relevante señalar que la señal excitante de entrada del primer bloque se corresponde con el pulso START. A partir del segundo bloque, la entrada CI de cada módulo se conecta con la salida del bloque anterior, formando así la denominada ‘Carrychain’. De forma que, cada una de las entradas CI de dichos bloques recibirá la señal digital ‘START’, con un retardo estimado teórico de entre 15 y 25 ps respecto de la entrada del bloque anterior. De esta manera, con la configuración estructural mencionada, se nos presenta una línea digital de retraso, cuyo cometido consiste en la propagación de un alto nivel por la misma. La salida de cada instancia ‘Carry’ más allá de conectarse con su homólogo posterior, se interconecta con la entrada de un biestable. En la Figura 3.1 especificamos que dichos biestables se corresponden con los biestables tipo D; cada uno de ellos se define como un ‘Flip- Flop’ que recibe un valor digital por su entrada D, que se propagará hacia la salida (Q) tras el registro de un flanco de subida digital por parte de la entrada C. El dato binario a la salida del módulo en cuestión se mantiene hasta que el valor actual sea distinto del presente en la entrada en el preciso instante del evento cambio de estado a nivel alto en la entrada C. Además, el papel despeñado de las entradas CLR y CE consisten en el reinicio de la salida y en la habilitación de la entrada C, respectivamente. La ristra de ‘Flip-Flops’ interconectados uno a uno con la cadena de módulos ‘Carrychain’ constituyen lo que denominamos ‘delayline’, ilustrada en la Figura 3.2 (se omiten las entradas de los biestables ‘C’ y ‘CLR’).
6 Planteamiento La señal que perturba la entrada C se corresponde con la señal de reloj CLK. Pues bien, uno de los flancos ascendentes de CLK, se atribuye al pulso STOP; el indicado será detallado en la siguiente sección. El cometido de este pulso radica en decidir el momento exacto en el que se conformará el vector salida “Q1,Q2…Qn” según el valor de la entrada de los biestables. Este vector salida indica mediante un código binario, el tiempo transcurrido entre los flancos de subida de las señales START y STOP, es decir el ∆𝑻 objeto de este proyecto. Cabe esperar que los bits menos significativos del vector salida mantendrán un valor constante de '1' hasta que alguna de las salidas adquiera el valor de '0'. En ese momento, todas las salidas subsiguientes tomarán el valor de '0' hasta el término del vector. Figura 3.1 Biestable tipo D Figura 3.2 Delay line
7 Planteamiento 3.2 Input Filter Desglosamos la etapa “Input Filter” en 2 conjuntos, compuesto cada uno por 2 biestables tipo D; cada conjunto, cumple un cometido específico. Atendiendo al primero de los conjuntos, este tiene la finalidad de acotar temporalmente por la derecha una señal digital, definiendo así el pulso ‘START’. Se trata de un objetivo prescindible, puesto que, el único desempeño de la señal de inicio reside en la concreción del inicio de ∆𝑻. Así, la justificación del uso de este módulo estriba en una mayor claridad a la hora de definir la franja temporal de entrada. Referenciamos la configuración estructural de esta primera etapa en la Figura 3.3. La onda predecesora a ‘START’, a la que llamamos ‘hit’, que gestiona el inicio del intervalo ∆𝑻, perturba la entrada de reloj ‘C’ del primer biestable ‘input_filter1’ de esta primera sección. Un estado activo digital de la señal propagará el ‘1’ constante presente en ‘D’ hacia la salida ‘Q’. Este nivel lógico alto, provoca el reinicio en ambos biestables. El primero de dichos módulos permutará su salida al estado digital positivo, originándose así un pulso de corta duración a su salida, mientras que, el efecto en la segunda instancia consiste en establecer un ‘0’ a su salida, que, a su vez, induce el estado ‘1’ a la salida del inversor; cuyo valor mantendrá hasta que un flanco de subida infiera en el pin de reloj ‘C’ de ‘input_filter2’. Como a esta señal la llamamos pulso ‘START’, así, se concluye, que: ↑ 𝑺𝑻𝑨𝑹𝑻 ≡ ↑ 𝒉𝒊𝒕 + 𝒓𝒆𝒕𝒓𝒂𝒔𝒐𝒔 𝒃𝒍𝒐𝒒𝒖𝒆𝒔 𝒍ó𝒈𝒊𝒄𝒐𝒔 El segundo conjunto de biestables sincroniza la salida del bloque a diseñar basado en “ delayline” con la etapa encargada de la codificación código binario – termómetro mediante la emisión de un pulso discreto declarado como ‘valid’. Para ello, tal como muestra la Figura 3.4, la entrada del primer biestable coincide con la salida del inversor, y, por tanto, con ‘START’. Describiendo su funcionalidad, este pulso se propaga tras 2 ciclos de reloj hacia la salida del módulo, para conformar la onda objeto ‘valid’; para ello, el reloj gestiona la sincronización, excitando la entrada C. Tenemos que cada biestable infiere una posposición de 1 CLK. El retardo generado está en consonancia con el retraso inducido por el bloque lógico ‘fine_tdc’, que será diseñado en el próximo apartado.
14 Diseño Figura 4.4 Algoritmo instancia delayblock_2 Figura 4.5 Algoritmo Carrychain
15 Diseño Figura 4.6 CLB
16 Diseño Figura 4.7 Slice_X8Y75 Figura 4.8 Algoritmo Entidad Flip-Flop tipo D
17 Diseño Figura 4.9 Estructura lógica biestables fine_tdc implementación Figura 4.10 Algoritmo instancias columnas biestables Flipflop_1 Flipflop_2
18 Diseño Figura 4.11 Algoritmo instancia fine_tdc 4.2 Input Filter Desglosamos la etapa “Input Filter” en 2 conjuntos, compuesto cada uno por 2 biestables tipo D; cada conjunto, cumple un cometido específico. En primer lugar, y abordando los propósitos del primero de estos primeros conjuntos para optimizar el diseño (descritos en el apartado ‘planteamiento’), se pretende acotar en el dominio del tiempo, el pulso de entrada al sistema y así considerar un pulso de inicio ‘START’ cuyo flanco de bajada coincidirá con el flanco de subida de la señal de ‘STOP’. En lo relativo a la estructura lógica, se muestra un esquema de dicho primer conjunto en la Figura 3.3, haciendo uso de la herramienta ‘RTL Analysis’ de Vivado. El bloque está constituido por 2 instancias: ‘input_filter1’ e ‘input_filter2’, basadas en la entidad ‘FDCE’ descrita en la Figura 4.8 (misma estructura lógica que para los biestables de la línea de retraso). Se busca negar el pulso de la salida del segundo filtro, obteniendo un nivel alto digital tras un estado lógico bajo, suministrando el pulso START (señal trigger) como nivel alto a la entrada de la línea de retraso; representándose en el esquema como un recurso LUT. Se fija un nivel bajo en la salida mencionada tras el evento de un flanco de subida de reloj en la entrada ‘CLK’ del segundo biestable. Las señales implicadas en la interconexión entre ambos bloques, así como la definición de sus instancias vienen descritas en el algoritmo ilustrado en la Figura 4.12 (fragmento del fichero top: “fine_tdc_encoder.vhd”).
19 Diseño Atendiendo a la segunda etapa de estos filtros, su propósito radica en sincronizar la salida de la línea de retraso con la etapa encargada de la codificación “código binario – termómetro” mediante la emisión de un pulso discreto declarado como ‘valid’. De nuevo, la entidad ‘FDCE’ instancia 2 biestables encargados de dicho propósito (obsérvese Figura 4.13). Se ratifica de forma gráfica la descripción de este algoritmo en la Figura 3.4. La forma de sincronizar ambos elementos reside en la fijación de un retardo de 2 CLK con respecto al instante del suceso del evento de un flanco de subida del pulso ‘START’ tanto a la entrada de datos (D) del primer Flip- Flop del conjunto en cuestión, como a la entrada ‘trigger’ del “delay_line” ; por tanto, la transmisión de la señal de validación se ajusta al tiempo de procesamiento que sufre la línea de retraso. Figura 4.12 Algoritmo instancias input_filter1 input_filter2
20 Diseño Figura 4.13 Algoritmo instancias input_filter_fired1 input_filter_fired2 4.3 Decodificador Termómetro – Binario Como se ha comentado en el apartado planteamiento, este bloque trata de decodificar el código termómetro a binario. La funcionalidad y estructura del diseño del decodificador puede ser dividida en 2 etapas distinta. El cometido de la primera etapa reside en buscar un rango, constituido por 15 bits, en el que se da lugar la permutación binaria ′𝟏′→ ′𝟎′ ; a partir de una secuencia binaria de un tamaño determinado. Dicha sucesión de datos proviene de la salida de la línea de retraso, siendo cada bit transmitido por un biestable de la segunda columna. En cuanto a la magnitud de la secuencia, este viene determinado por el tamaño del vector entrada de datos de la entidad decodificador ‘therm2bin_pipeline_count’ (Figura 4.16), definida por: ((2**b)-1); estando ‘b’ definida como constante ‘generic’. En nuestro diseño, se define: b = 8 → ((2**b)-1) = 255 Esta etapa consta de distintas fases de elementos MUX, cuya función radica en dividir en 2 partes de igual magnitud una serie binaria, para posteriormente, optar por el fragmento en el que
21 Diseño uno de los bits es objeto de permutación. Atendiendo al primer multiplexor de la etapa (indicado por el índice de la señal ‘decoding’) ilustrado en la Figura 4.15, este se encarga de escindir dicha secuencia binaria en 2 vectores de un rango [126:0], y según el dígito recibido por la entrada de selección, una de las entradas se propaga hacia la salida. El valor binario que perturba la entrada ‘S’ del multiplexor, coincide con el valor del índice central del vector entrada; ‘thermo[255]’ en el multiplexor representado en la Figura 4.15. Para justificar este proceder, se señala que la entrada de datos del bloque sigue un patrón termométrico: “1111111111111…11000…0000” ; por tanto, se deduce que si el valor central es ‘1’, la permutación binaria se ubicará en la mitad derecha de la secuencia; dicha transición ocurrirá en la primera mitad para el caso contrario. Este algoritmo se describe en función de ‘i’ en la Figura 4.16. Este índice refleja el valor de secuencia de la iteración (bucle FOR), que a su vez, fija la fase de la etapa; ejecutada cada flanco de subida de reloj (obsérvese la Figura 4.17). Como se observa en la Figura 4.14, la salida del decodificador, y por tanto del TDC, se define como un vector cuya magnitud depende del parámetro b : “b – 1 = 7 “; según nuestros parámetros de diseño. Así los ‘b-4’(4) valores más significativos de esta salida quedan definidos por la primera etapa. Estos valores corresponden con los valores centrales de la entrada de cada fase, concordando así con cada iteración gestionada síncronamente. La segunda etapa consiste implementa un contador binario de ‘1’s, cuyo objeto de medición son los 15 bits resultantes de la salida de la primera etapa. Son necesarios 4 bits como máximo para expresar el número 15 en binario (𝟐𝟒=𝟏𝟔). La funcionalidad de esta etapa está descrita en 2 procesos síncronos. El primero, ilustrado en la Figura 4.18, se encarga de concatenar la respuesta de la primera etapa con el resultado de la función ‘count_ones ‘, cuyo argumento referencia los 15 bits donde se encuentra la permutación binaria. Además, propaga la señal de validación síncronamente, al igual que en la primera etapa. El segundo proceso(Figura 4.19) consta de una estructura secuencial que asigna la salidas concatenadas de ambos a la salida del decodificador, y por tanto, del TDC. Figura 4.14 Algoritmo Entidad codificador temómetro-binario
22 Diseño Figura 4.15 Multiplexor Figura 4.16 Algoritmo Multiplexor Figura 4.17 Algoritmo iteraciones instancia stage_proc +
23 Diseño Figura 4.18 Algoritmo proceso concatenación salida Figura 4.19 Algoritmo proceso asignación salida
30 Simulación Compárese la Figura 2.3 (boceto del problema teórico) con la Figura 5.6 (simulación del problema del proyecto); el pulso ‘trigger’ representa START, mientras que, la señal de reloj “clock_IBUF_BUFG” se corresponde con STOP. Observamos que la transición ‘0’ → ‘1’ tiene lugar 10,816 ns antes de la mitad de un periodo de reloj, es decir, 10,816 ns previos a un flanco de subida de reloj. Este valor se ha obtenido sumando los diferentes retrasos constantes, junto con el retraso que se pretende que el pulso START experimente en la línea de acarreo para el caso value_fine = 256; es decir, para este valor de salida, se estima que dicho pulso se propaga hasta la salida del último bloque de acarreo. Así, la respuesta de salida del sistema depende del valor del parámetro BLOQUES CARRY4(parámetro a configurar) de la siguiente expresión matemática (obsérvese Tabla 5.1): ∆𝑻 = RETRASOS CONSTANTES (HIT-TRIGGER + TRIGGER-CARRY4_1 + CAPTURA CLK EN FF + CLK CLK_IBUF_BUFG) + BLOQUES CARRY4 A continuación, se exponen los 3 casos más significativos de la relación entrada-salida del sistema: Value_fine: 0 ↔ ∆𝑻 = 3333 ps / BLOQUES CARRY4 = 0 ps Value_fine: 128 ↔ ∆𝑻 = 7074.5 ps / BLOQUES CARRY4 = 3741.5 ps Value_fine: 256 ↔ ∆𝑻 = 10816 ps / BLOQUES CARRY4 = 7483 ps Es relevante destacar que para poder añadir un DUT al fichero banco de pruebas, se requiere describir el componente de la entidad a examinar; además, en la entidad del fichero de simulación se han definido las constantes generic: 𝐒𝐓𝐀𝐆𝐄𝐒 = 𝟐𝟓𝟔 y FINE_BITS = 8 (la línea de acarreo de nuestro diseño contiene 256 bloques ‘Carry’, como se ha comentado anteriormente).
31 Simulación Figura 5.5 Algoritmo Test Bench Figura 5.6 Simulación Resumen Problema Proyecto
32 Simulación 5.4 Resultados Simulación Esta subsección trata de analizar los resultados de la simulación temporal post-implementación presentados en la interfaz gráfica de Vivado. El tiempo de simulación se ha definido a 500 ns y la frecuencia de la señal de reloj a 100 MHz. También se ha ejecutado la simulación para los valores de frecuencia de 1 y 10MHz, sin observarse modificaciones en la respuesta. Se estudian las formas de pulsos de cada etapa del proyecto: 5.4.1 Input Filter Esta etapa se puede desglosar en 2 grupos: un primer conjunto constituido por los biestables “input_filter1” e “input_filter2”, encargados de definir el pulso ‘START’ a partir del pulso de entrada de nuestro sistema ‘hit’. Su función radica en acotar por la derecha esta señal digital. A dicho conjunto lo denominaremos fase 1. El grupo restante, al que designaremos como fase 2, consta de los Flip-Flops “input_filter_fired1” e “input_filter_fired2”. Su cometido reside en sincronizar las etapas “finde_tdc” y “therm_to_bin” mediante la emisión de un pulso de validación al bloque de codificación, y así señalizarle del instante correcto en el que recibirá los datos. Para interpretar adecuadamente estas señales, obsérvese la estructura lógica del filtro en la Figura 3.3 Fase 1 La Figura 5.7 muestra gráficamente cómo el primer filtro emite un pulso instantáneo (salida Q), que se inicia cuando la entrada de reloj C recibe un flanco de subida del pulso ‘hit’ (entrada de datos D está a nivel alto de forma constante). Como la salida está conectada a la entrada CLR (clear), el pulso permutará a un estado lógico bajo inmediatamente después; por tanto, la duración del pulso depende del tiempo de procesamiento para la ejecución de esa operación (1.533 ns). Dicho desfase temporal seestima menor que el intervalo temporal transcurrido entre los flancos de subida de los pulsos ‘hit’ y ‘Q’. Además, se ilustra que tras 1.533 ns del flanco de subida ‘Q’, la salida del segundo filtro permuta a reposo, forzando así el estado lógico positivo en el pulso ‘trigger’, es decir, en START; instante en el que empieza la propagación del pulso objeto de estudio a través de la línea de acarreo. Esta señal vuelve a conmutar hacia el ‘0’ binario debido a la razón síncrona del proceso.
33 Simulación Fase 2 El cometido de los 2 biestables interconectados presentes en la Figura 3.4, reside en la sincronización del pulso ‘valid’ con el vector señal ‘latched_output’ (ejemplo simulación en Figura 5.8). 5.4.2 Fine tdc Referenciando las entradas y salidas de la etapa “Fine_tdc” en la Figura 5.9, se muestra el procedimiento operativo del reinicio. Esta operación consiste en la inicialización (a nivel alto, en este caso) de los pulsos ‘trigger’ (impulsado por la etapa de filtros) y ‘latched_output’. Se ha comprobado que esta operación se ejecuta siempre, independientemente del estado de la entrada ‘reset’. Atendiendo a la línea de acarreo, cuyo esquema lógico estructural resultante de la fase de implementación, queda definido mediante una indexación en la Figura 5.10; la Figura 5.11 expone los retardos que inducen los bloques ‘Carry’ (agrupados en los módulos ‘Carry4’). Se calculan 1113 ps de diferencia entre los flancos de subida ‘hit’ y ‘CO[0:3]’ (primer bloque CARRY4); valor que dista mucho de los 117 ps de retardo entre el resto de bloques consecutivos (salvo otras excepciones). La tabla 5.2 detalla los resultados cuantitativos. Además, cabe agregar que las salidas de un mismo bloque CARRY4 no sufren ningún desfase temporal entre sí; de acuerdo con la estructura lógica expuesta en la Figura 4.1. A cada bloque de acarreo se le asocia un biestable (Figura 4.9), que captura el dato en un instante de tiempo determinado, tras detectar el consiguiente flanco de subida de reloj. Para estudiar esta operación, se van a evaluar particularizaciones en simulación de los 3 casos que corresponden con los valores más significativos de la respuesta del sistema, cuya relación con la entrada (y cálculo del mismo) se ha analizado en la subsección fichero test bench : Value_fine (binario) ≡ Latched_output (termométrico) = 0 – Figura 5.12 Value_fine (binario) ≡ Latched_output (termométrico) = 128 - Figura 5.13 Value_fine (binario) ≡ Latched_output (termométrico) = 256 - Figura 5.14 En las Figuras 5.12 y 5.13 se observa un error de 3 bits por encima del valor teórico. En la Figura 5.14, el bit más significativo está conectado a alta impedancia. Esto se debe a que, como se observa la Figura 5.15, la salida CO[3] está flotante, sin conectarse al biestables_line[255] de la primera columna que le correspondería; un flip-flop que no existe en nuestro diseño.
34 Simulación Una vez capturados los pulsos que se presentan a la salida de los bloques ‘Carry’, se propagarán a través de la segunda columna de biestables hacia la salida, tras el siguiente ciclo de reloj, tal y como se ilustra en la Figura 5.16. 5.4.3 Therm_to_bin De forma análoga a la etapa “fine_tdc”, se ha de considerar la fase de reinicio en este bloque. Como se representa en la Figura 5.17, la salida se define a su máximo valor para esta fase. Tras este preludio, se ilustra la respuesta del bloque (en esta etapa coincide con la del sistema) en función de las entradas de bloque y sistema. Se exponen varios ejemplos en la Tabla 5.3: Salida bloque/sistema Entrada bloque Entrada sistema Bin[7:0] - experimental Bin[7:0] - teórico Thermo[255:0]- teórico ∆T Figura 0 0 0 3333 5.18 102 100 100 6258 5.19 131 128 128 7074.6 5.20 202 200 200 9180.6 5.21 256 256 256 10816 5.22 Tabla 5.3 Valores salida sistema Resulta relevante señalar que, la interfaz gráfica computa el valor en binario del vector señal ‘Bin[7:0] ‘en el instante en el que está fijada la barra amarilla. RETARDOS (ps) Carry_delay_line[0] Carry_delay_line[1] Carry_delay_line[1 - 62] Carry_delay_line[63] 1113 126 117 229 Tabla 5.2 Análisis retardos línea de acarreo
35 Simulación Figura 5.7 Simulación Interconexión Filtros Fase 1 Figura 5.8 Simulación Interconexión Filtros Fase Figura 5.9 Simulación Reinicio Fine_TDC
36 Simulación Figura 5.10 Bloques línea de acarreo Figura 5.11 Retardos Bloques Carry4 Figura 5.12 Simulación Value_fine_teórico = 0
37 Simulación Figura 5.13 Simulación Value_fine_teórico = 128 Figura 5.14 Simulación Value_fine_teórico = 256
38 Simulación Figura 5.15 Esquema lógico interconexión módulo CARRY4 - biestables Figura 5.16 Particularización salida Fine_tdc
39 Simulación Figura 5.17 Fase Reinicio Codificador Termómetro - Binario Figura 5.18 Simulación salida codificador Bin[7:0]_teórico = 0 Figura 5.19 Simulación salida codificador Bin[7:0]_teórico = 100 Figura 5.20 Simulación salida codificador Bin[7:0]_teórico = 128
46 Anexo LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.ALL; LIBRARY unisim; USE unisim.vcomponents.ALL; LIBRARY work; USE work.tdc_library.ALL; ENTITY fine_tdc_with_encoder IS GENERIC ( STAGES : INTEGER := 256; FINE_BITS : INTEGER := 8; Xoff : INTEGER := 8; Yoff : INTEGER := 24); PORT ( clock : IN std_logic; reset : IN std_logic; hit : IN std_logic; value_fine : OUT std_logic_vector((FINE_BITS-1) DOWNTO 0)); END fine_tdc_with_encoder; ARCHITECTURE structure OF fine_tdc_with_encoder IS ATTRIBUTE keep_hierarchy : string; ATTRIBUTE keep_hierarchy OF structure : ARCHITECTURE IS "true"; SIGNAL fine_value_reg : std_logic_vector((STAGES-1) DOWNTO 0); SIGNAL fine_value_bin : std_logic_vector((FINE_BITS-1) DOWNTO 0); SIGNAL filtered_hit_1 : std_logic; SIGNAL filtered_hit_2 : std_logic; SIGNAL filtered_hit : std_logic; SIGNAL fired : std_logic;
47 Anexo SIGNAL valid : std_logic; COMPONENT FDCE IS GENERIC ( INIT : STD_LOGIC); PORT ( D : in STD_LOGIC; C : in STD_LOGIC; CE : in STD_LOGIC; CLR : in STD_LOGIC; Q : out STD_LOGIC); END COMPONENT; BEGIN input_filter1 : FDCE GENERIC MAP ( INIT => '0') PORT MAP ( Q => filtered_hit_1, CLR => filtered_hit_1, D => '1', C => hit, CE => '1'); input_filter2 : FDCE GENERIC MAP ( INIT => '0') PORT MAP ( Q => filtered_hit_2, CLR => filtered_hit_1, D => '1', C => clock, CE => '1'); filtered_hit <= NOT filtered_hit_2;
48 Anexo input_filter_fired1 : FDCE GENERIC MAP ( INIT => '0') PORT MAP ( Q => fired, CLR => '0', D => filtered_hit, C => clock, CE => '1'); input_filter_fired2 : FDCE GENERIC MAP ( INIT => '0') PORT MAP ( Q => valid, CLR => '0', D => fired, C => clock, CE => '1'); fine : fine_tdc GENERIC MAP ( STAGES => STAGES, Xoff => Xoff, Yoff => Yoff) PORT MAP ( trigger => filtered_hit, clock => clock, reset => reset, latched_output => fine_value_reg); t2b : therm2bin_pipeline_count GENERIC MAP ( b => FINE_BITS) PORT MAP ( clock => clock, reset => reset, valid => valid,
49 Anexo thermo => fine_value_reg, bin => fine_value_bin); value_fine <= fine_value_bin; END structure
50 Anexo library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity FDCE is GENERIC ( INIT : STD_LOGIC := '0' ); Port ( D : in STD_LOGIC; C : in STD_LOGIC; CE : in STD_LOGIC; CLR : in STD_LOGIC; Q : out STD_LOGIC); end FDCE; architecture Behavioral of FDCE is begin sinc:process(C,CE,CLR) begin if (CLR = '1') then Q <= '0'; elsif(rising_edge(C) and (CE = '1')) then Q <= D; end if; end process; end Behavioral;
51 Anexo library IEEE; use IEEE.STD_LOGIC_1164.ALL; Library UNISIM; use UNISIM.vcomponents.all; entity fine_tdc is GENERIC ( STAGES : INTEGER; Xoff : INTEGER; Yoff : INTEGER); PORT( trigger : IN STD_LOGIC; reset : IN STD_LOGIC; clock : IN STD_LOGIC; latched_output : OUT STD_LOGIC_VECTOR(STAGES-1 DOWNTO 0)); end fine_tdc; architecture Behavioral of fine_tdc is signal unreg: std_logic_vector(STAGES-1 DOWNTO 0); signal reg: std_logic_vector(STAGES-1 DOWNTO 0); ATTRIBUTE keep_hierarchy : string; ATTRIBUTE keep_hierarchy OF Behavioral : ARCHITECTURE IS "true"; Attribute LOC: string;
52 Anexo begin carry_delay_line: FOR i IN 0 TO STAGES/4-1 GENERATE first_carry4: IF i = 0 GENERATE ATTRIBUTE LOC OF delayblock: LABEL IS "SLICE_X"&INTEGER'image(Xoff)&"Y"&INTEGER'image(Yoff+i); BEGIN delayblock: CARRY4 PORT MAP( CO => unreg(3 DOWNTO 0), O => open, CI => '0', CYINIT => trigger, DI => "0000", S => "1111"); END GENERATE; next_carry4: IF i > 0 GENERATE ATTRIBUTE LOC OF delayblock: LABEL IS "SLICE_X"&INTEGER'image(Xoff)&"Y"&INTEGER'image(Yoff+i);
53 Anexo BEGIN delayblock: CARRY4 PORT MAP( CO => unreg(4*(i+1)-1 DOWNTO 4*i), O => open, CI => unreg(4*i-1), CYINIT => '0', DI => "0000", S => "1111"); END GENERATE; END GENERATE; biestables_line: FOR j IN 0 TO STAGES-1 GENERATE begin Flipflop_1: FDCE PORT MAP( D => unreg(j), C => clock, CE => '1', CLR => reset, Q => reg(j)); Flipflop_2: FDCE PORT MAP( D => reg(j), C => clock, CE => '1', CLR => reset, Q => latched_output(j));
54 Anexo END GENERATE; end Behavioral; LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; LIBRARY work; USE work.tdc_library.ALL; ENTITY therm2bin_pipeline_count IS GENERIC ( b : INTEGER := 8); PORT ( clock : IN std_logic; reset : IN std_logic; valid : IN std_logic; thermo : IN std_logic_vector(((2**b)-1) DOWNTO 0); bin : OUT std_logic_vector((b-1) DOWNTO 0)); END therm2bin_pipeline_count; ARCHITECTURE behaviour OF therm2bin_pipeline_count IS ATTRIBUTE keep_hierarchy : string; ATTRIBUTE keep_hierarchy OF behaviour : ARCHITECTURE IS "true"; SIGNAL stage_final_bin : std_logic_vector((b-1) DOWNTO 0); SIGNAL stage_final : std_logic_vector(15 DOWNTO 0); SIGNAL data_valid : std_logic_vector((b-3) DOWNTO 0); TYPE decoder_array IS ARRAY (0 TO b-4) OF std_logic_vector(((2**b)-2) DOWNTO 0); SIGNAL decoding : decoder_array; TYPE binary_array IS ARRAY (0 TO b-4) OF std_logic_vector(b DOWNTO 0); SIGNAL binary : binary_array; BEGIN
55 Anexo decoding(0) <= thermo(((2**b)-2) DOWNTO 0); data_valid(0) <= valid; generate_stages : FOR i IN 0 TO b-5 GENERATE stage_proc : PROCESS (clock, reset) BEGIN IF reset = '1' THEN decoding(i+1) <= (OTHERS => '0'); binary(i+1) <= (OTHERS => '0'); data_valid(i+1) <= '0'; ELSIF rising_edge(clock) THEN binary(i+1)(b DOWNTO b-1-i) <= binary(i)(b DOWNTO b-i) & decoding(i)(((2**(b- i))-2)/2); data_valid(i+1) <= data_valid(i); IF decoding(i)(((2**(b-i))-2)/2) = '1' THEN decoding(i+1)(((2**(b-i))-2)/2-1 DOWNTO 0) <= decoding(i)(((2**(b-i))-2) DOWNTO ((2**(b-i))-2)/2+1); ELSE decoding(i+1)(((2**(b-i))-2)/2-1 DOWNTO 0) <= decoding(i)(((2**(b-i))-2)/2-1 DOWNTO 0); END IF; END IF; END PROCESS; END GENERATE; stage_final <= decoding(b-4)(15 DOWNTO 0); -- The final stage of the decoder is a bit counter for the remaining 16 bits stage_final_proc : PROCESS (clock, reset) BEGIN IF reset = '1' THEN stage_final_bin <= (OTHERS => '0'); data_valid(b-3) <= '0'; ELSIF rising_edge(clock) THEN stage_final_bin <= binary(b-4)(b-1 DOWNTO 4) & std_logic_vector(to_unsigned(count_ones(stage_final), 4)); data_valid(b-3) <= data_valid(b-4); END IF;