viernes, 6 de julio de 2012

Lazos Combinacionales


Introduccion

Lazos combinacionales son estructuras lógicas que contienen realimentación sin ningún elemento sincrónico en el camino. Normalmente los lazos combinacionales provocan inestabilidad y sistemas pocos confiables, violando los principios de diseño sincrónico al establecer un lazo de realimentación sin registros. 

Porqué? Cómo se genera un lazo combinacional?

Un lazo combinacional es implementado en hardware cuando en el código VHDL escrito una señal que está del lado izquierdo de una instrucción de asignación (a la izquierda del símbolo <=) también aparece en la expresión aritmética/lógica del lado derecho de la instrucción de asignación (a la derecha de <=); siempre y cuando se esté describiendo lógica combinacional. Por ejemplo las siguientes líneas de código generaran un lazo combinacional si se escribe en un proceso combinacional o directamente como una instrucción de asignación concurrente.
  
1 acc <= acc + data;
2
3 Z <= Z nand B;
4
5 cnt <= cnt + 1;

 

Sin embargo es importante, muy importante, aclarar que si estas mismas líneas de código son escritas dentro de un proceso controlado por reloj, se generara la respectiva lógica secuencial; debido a que el reloj del proceso almacena el valor correspondiente por un ciclo de reloj, de este modo no existe una realimentación combinacional.

Hardware

La siguiente figura representa un esquema de un lazo combinacional:



Como se ve en la figura, la salida de la lógica combinacional se realimenta a si misma sin ningún tipo de registro en el medio. Este tipo de esquema lógico, normalmente no se desea, no es lo que se desea implementar, por ello la herramienta de síntesis genera una advertencia (warning) tal como se detalla en el siguiente ejemplo.

 1 library ieee;
 2 use ieee.std_logic_1164.all;
 3
 4 entity lazo_comb is
 5   port(
 6     a: in  std_logic;
 7     z: out std_logic);
 8 end lazo_comb;
 9
10 architecture beh of lazo_comb is
11
12  signal y: std_logic;
13
14 begin
15     z <= y; 
16
17 process(a,y)
18  begin
19     y <= y nand a;
20 end process;
21
22 end beh;

La herramienta de síntesis, Synplify en este ejemplo, genera el siguiente mensaje de advertencia para este código:


El mensaje ‘found combinational loop at y’ significa que la señnal ‘y’ es realimentada combinacionalmente tal como se puede apreciar en el diagrama RTL de la respectiva implementación del código descrito:


  
A continuación se puede ver la simulación del sistema descrito arriba.



                Esta figura merece un detallado análisis. En primer lugar la primer ventana (de arriba hacia abajo) grafica las formas de ondas de las señales del sistema cuya principal expresión es la de la línea 24 de la segunda ventana. La tercer ventana, Transcript, detalla un error de simulación, diciendo que el limite de iteraciones del simulador fue alcanzado a los 50ns y no se llego a ningún valor estable. Es decir que el sistema empezó a oscilar y se quedo oscilando. El numero de iteración limite es programable en ModelSim (Simulate->Runtime Options), y en la mayoría de los simuladores. Por defecto este valor es de 5000. Viendo mas en detalle la parte inferior de la ventana donde se grafican las formas de ondas, se puede leer que el numero de Delta alcanzado es de 5000, que es justamente el numero limite de iteraciones configurado. Han transcurridos 5000 Deltas y aun el sistema no es estable.  
Otro punto importante a considerar en este ejemplo es el hecho de lo importante que es simular un sistema aun cuando sea muy simple. Suponiendo que hubiéramos directamente configurado el FPGA sin haber realizado la simulación (ya que la herramienta de síntesis nos da solo un ‘warning’), hubiéramos visto que la salida del sistema no era estable; y hubiéramos perdido una considerable cantidad de tiempo tratando de ver porque la salida no es estable
         En diseños con una gran cantidad de código a veces es muy fácil cometer errores como el del código descrito arriba. Por ello, hay que seguir un cierto orden en la escritura del código, tratando de mantener un cierto flujo de datos, por ej. de derecha a izquierda.
            En casos en que deliberadamente se desea implementar cierta lógica con un lazo combinacional tener en cuenta:
  • Comentar suficientemente el código de modo que se puede fehacientemente conocer la razón de existencia del lazo. 
  •  Realizar todas las simulaciones posibles, primero en PC y luego en hardware para comprobar que aun con la existencia del lazo el sistema sigue funcionando correctamente.
       Otro punto importante a tener en cuenta cuando deliberadamente se implementa un lazo combinacional, es que la herramientas de análisis de tiempo estático (Static Taming analysys, STA) normalmente incrementan por un valor (2-8 veces) el periodo mínimo cuando encuentran un lazo combinacional. Por ello, en estos casos se debería decirle a la herramienta STA que ‘ignore’ ese camino en particular. La sintaxis para el caso de Quartus (Altera), es ‘set_false_path’ (recordar que las herramientas de Altera usan constraints con las sintaxis de Synopsys; para ISE (Xilinx) use TIG con su respectiva sintaxis.