Una de las principales dudas que tiene cualquier persona que comienza con VHDL, sobre todo si viene del mundo de la programación es el concepto de señal.

VHDL utiliza tanto señales como variables, y su funcionamiento es completamente diferente. Es muy importante conocer en detalle el mismo para saber cuando hay que utilizar cada una de ellas.

Para entender que es una señal tenemos que asumir que en VHDL no estamos programando, si no que estamos describiendo el comportamiento de un circuito electrónico, compuesto por “componentes”, que son nuestras entidades y “cables”, que son nuestras señales. Estas señales nos permitirán conectar componentes y procesos entre sí, igual que lo haría un cable colocado en una placa.

Por el contrario una variable es simplemente un almacén temporal de un valor que se utiliza como apoyo mientras estamos programando. No tiene ningún significado físico y deriva de los lenguajes de programación.

Una vez entendido esto podemos establecer las diferencias básicas entre las dos:

  • Ámbito de declaración. Una señal se declara a nivel de la arquitectura y puede ser leída por varios procesos. Una variable se declara dentro de un proceso y solo puede ser leída y escrita desde él.
architecture funcional of prueba is
  signal a: std_logic_vector(7 downto 0);
begin
  
  process(a)
    variable var: std_logic_vector(15 downto 0);
  begin
    var := x"5C";
    a <= var(7 downto 0);
  end process;

end architecture
  • La asignación a una variable se hace mediante el operador := , a una señal se le asigna valores mediante la flecha <=
  • Si estamos describiendo un proceso combinacional, todas las señales que leamos deben ser declaradas en la lista de sensibilidad del proceso. Las variables no.
  • También tener en cuenta que los puertos se comportan como señales.
  • Y la más importante y en ocasiones complicada de entender. Una variable toma inmediatamente el valor que se le asigna, como en un lenguaje de programación. Sin embargo en una señal los valores que se le dan no se “cargan” hasta que avanza en tiempo de simulación y en ese momento tomará el último valor que se le haya dado.

Para entender este último punto veamos un ejemplo. Si hacemos la simulación como se ve en la imagen, veremos que la salida va con retraso frente a la señal. Esto es así porque mi_senal toma el valor de la entrada pero hasta que no termina en proceso no toma el valor de la entrada dado en la asignación, por lo que salida toma el valor antiguo.

 

entity prueba is
 port (entrada : in std_logic_vector(7 downto 0);
       salida : out std_logic_vector(7 downto 0));
end entity;

architecture funcional of prueba is
  signal mi_senal: std_logic_vector(7 downto 0);
begin
  
  process(entrada)    
  begin
    mi_senal <= entrada;
    salida   <= mi_senal;
  end process;

end architecture

Para que se comportará de la manera “esperada” tendríamos que añadir mi_senal a la lista de sensibilidad el proceso, de tal manera que al termina el proceso y existir un cambio en mi_senal, el proceso volviera a ejecutarse, esta vez si con el valor actualizado y la salida tomaría el valor de la entrada tras dos ciclos de simulación.

simulación señales y variable

A estos ciclos de simulación que se ejecutan hasta que todas las señales tengan un valor estable se denominan “ciclos delta” y son la base de los simuladores RTL como Modelsim. Estos simuladores no avanzan el tiempo de simulación hasta que haya dos ciclos delta seguidos sin cambios en los valores de las señales.

Este tipo de simulaciones puede dar lugar a ejemplos como el siguiente:

entity comb_loop is
 port (entrada : in std_logic_vector(7 downto 0);
       salida : out std_logic_vector(7 downto 0));
end entity;

architecture funcional of comb_loop is
  signal a: std_logic_vector(7 downto 0);
begin
  
  process(a)
    
  begin
    a <= not(a); 
  end process;

  salida <= a;

end architecture

En este ejemplo lo que ocurre es algo que se llama bucle combinacional. Al asignar a la señal su valor negado el proceso se vuelve a ejecutar, vuelve a asigna el valor negado y se vuelve  a ejecutar ya que el valor de la señal ha cambiado. Como el valor nunca se estabiliza el tiempo de simulación no avanza y el simulador habitualmente se cuelga.

Y no olvidéis que tenemos un curso sobre VHDL en Udemy donde podréis aprender VHDL desde cero e implementar vuestro propio microprocesador. Os dejamos aquí el enlace.

https://www.udemy.com/crea-tu-primer-circuito-con-vhdl-y-fpga/learn/v4/