4. SÍNTESIS DEL DISEÑO
4.2. MANEJO DEL SINTETIZADOR
4.2.6. Configuración de opciones de optimización
Una vez leídos los ficheros que componen el diseño estos se analizan y elaboran. El siguiente paso consistiría en realizar la optimización de la síntesis. Previamente a esta última operación habrá que fijar las restricciones a aplicar al proceso optimización. Al igual que ocurre con el tipo de codificación de los tipos enumerados las restricciones se pueden aplicar de forma global mediante variables internas o de forma particular mediante atributos internos. Las restricciones impuestas desde el sintetizador se exportan a las herramientas de implementación mediante un fichero de restricciones en formato nativo (.ncf) que acompaña a la lista de conexiones que genera el sintetizador.
Como se ha comentado estas restricciones pueden ser topológicas o temporales. Un ejemplo del primer caso consistiría en la asignación del IOB asociado a
un puerto de la entidad de mayor jerarquía a un terminal concreto de la FPGA. Para esto se puede emplear el siguiente comando:
set_attribute -port {.work.cronometro.inside.rst} -name PIN_NUMBER -value P28
En cualquier caso, ha de destacarse que este tipo de restricciones también es posible aplicarlas desde la herramienta de implementación de Xilinx mediante un fichero de restricciones de usuario (.ucf). La elección del método dependerá de las preferencias del diseñador.
En cuanto a las restricciones temporales es posible imponer el retardo máximo admisible entre dos puntos del diseño. Si esta restricción no se cumple el sintetizador puede elegir otra estrategia de síntesis. Por ejemplo para el caso de un sumador se puede optar por sintetizarlo con acarreo paralelo frente a una implementación con acarreo serie.
Al igual que en el caso de las restricciones topológicas, las restricciones temporales también se pueden fijar durante la implementación. Sin embargo en este caso es deseable hacerlo durante la síntesis ya que estás pueden determinar la lógica inferida, de forma que si ésta no es óptima los esfuerzos realizados por las herramientas de implementación para buscar el emplazamiento más adecuado de los CLBs pueden resultar vanos.
Las restricciones temporales pueden ser globales o individuales. Las primeras se aplican a la totalidad del diseño, siendo éstas las más fáciles de utilizar. Tal y como muestra la figura 1.34 existen cuatro tipos de restricciones globales. Para fijar estas restricciones Leonardo define cuatro variables internas. Estas son:
! input2reg. Indica el máximo retardo admisible entre los puertos de entrada y el primer registro del diseño. En este tiempo se incluye el tiempo de set-up de los biestables.
! register2register. Indica el máximo retardo admisible entre los dos registros del diseño. En este tiempo se incluye el tiempo de propagación de los biestables del registro de salida y el de set-up de los de entrada.
! register2output. Indica el máximo retardo admisible entre los registros y los puertos de entrada. En este tiempo se incluye el tiempo de propagación de los biestables del registro de salida.
! input2output. Indica el máximo retardo admisible entre los dos puertos conectados únicamente por lógica combinacional.
data_in
input2register register2register register2output
output2output data_out FF2 clk D Q FF1 clk D Q data_in data_out clock Bloque combinacional A Bloque combinacional B Bloque combinacional C Bloque combinacional D
Figura 34: Uso de restricciones temporales globales. Para fijar estas restricciones se emplea el comando
set <variable> <valor>
donde <valor> es el tiempo de retardo máximo expresado en ns. Así por ejemplo para garantizar que nuestro diseño pueda funcionar al menos a una frecuencia de 10 MHz (T= 100 ns) se emplearían los siguientes comandos:
set register2register 100 set input2register 100 set register2output 100 set input2output 100
El otro tipo de restricciones permite fijar individualmente a cada uno de los puertos el máximo retardo admisible. A este tipo de restricciones se les denomina restricciones de puertos y se suelen emplear para optimizar aquellas señales de temporización más crítica. El sintetizador impone una serie de limitaciones a la hora de fijar las restricciones de puertos. Concretamente en el análisis temporal no se toman en consideración los caminos de señal que afectan a las señales de inicialización asíncrona (reset y preset) de los biestables. Tampoco se permite fijar restricciones temporales en diseños con varios relojes asíncronos. Sin embargo, si es posible el análisis de diseños con varios relojes síncronos (diseños multifase). Aun así la variedad de situaciones que se pueden abordar con las restricciones es muy amplia por lo que nos limitaremos a exponer aquellas que aparecen en diseños síncronos con una única señal de reloj. La figura 1.35 ilustra el uso de las restricciones individuales. A continuación se describirán estas restricciones.
input_arrival clock_cycle required_time FF2 clk D Q FF1 clk D Q DATA_IN DATA_OUT DATA_OUT2 CLK Bloque combinacional A Bloque combinacional B Bloque combinacional C pulse_width input_arrival required_time pulse_cycle CLK DATA_IN DATA_OUT Bloque combinacional FF Q clk D Circuito externo virtual
Figura 35: Modelado de restricciones individuales.
! clock_cycle define el periodo máximo (frecuencia mínima ) admisible de la señal de reloj del bloque. Este periodo vendrá dado por la suma del retardo de la salida de los biestables, el tiempo de propagación de la lógica combinacional y el tiempo de set-up de la entrada de los biestables.
! pulse_width permite modelar el ciclo de trabajo de la señal de reloj. ! arrival_time define la demora respecto al flanco de reloj con que
llegan los datos a la entrada del bloque.
! required_time define la demora máxima admisible desde el flanco de reloj hasta que los datos aparecen estables en el puerto de salida. Para fijar estas restricciones se emplean los siguientes comandos:
clock_cycle <periodo_reloj> <puerto_señal_reloj> pulse_width <ancho_pulso_reloj> <puerto_señal_reloj> arrival_time <valor_retardo> <lista_puertos_entrada> required_time <tiempo_necesario> <lista_puertos_salida>
Los primeros parámetros de estos comandos son valores de tiempo expresados en ns. Las lista de puertos se expresan como una lista de nombres entre llaves separadas por espacios. Como ejemplo se mostrarán los comandos a emplear para el circuito de la figura anterior bajo las siguientes suposiciones:
! Frecuencia mínima de funcionamiento: 10 MHz.
! Ciclo de trabajo de la señal de reloj: 25 %
! Tiempo de demora máximo de los datos de entrada: 12 ns ! Máximo retardo admisible en salidas secuenciales: 5 ns ! Máximo retardo admisible en salidas combinacionales: 10 ns Según esto los comandos a emplear serían:
clock_cycle 100 clk pulse_width 25 clk
arrival_time 12 {DATA_IN} required_time 5 {DATA_OUT}
En el modelado de una salida puramente combinacional, como es el caso de la señal DATA_OUT2, el tiempo necesario será la suma de la demora de las entradas más el máximo retardo admisible de estas salidas:
required_time 22 {DATA_OUT2}
Para acceder a las opciones de optimización desde el interface gráfico se utiliza la pestaña
, accediendo a la ventana de restricciones. Para generar las restricciones de cada uno de los elementos antes comentados se actúa sobre las pestañas mostrados en la figura 1.36 que se encuentra en la parte inferior de dicha ventana.
Figura 36: Selección de las restricciones para la síntesis