Programación en VHDL/Entidad

← Elementos básicos del lenguaje Entidad Arquitectura →


Durante los capítulos anteriores se ha insistido varias veces en que VHDL sirve para describir hardware. Un circuito electrónico puede ser parte de otro más grande, en este caso el primero sería un subcircuito del segundo. Por lo tanto, un circuito puede estar compuesto por muchos subcircuitos y estos subcircuitos se interconectarían. Así aparece una jerarquía en el diseño. En la parte alta de la jerarquía aparecerían los circuitos más complejos, que estarían compuestos por subcircuitos y, a su vez, cada uno de estos subcircuitos podría estar compuesto por subcircuitos más sencillos.

Un ejemplo de jerarquía sería un microprocesador. El circuito más complejo y el más alto en la jerarquía sería el propio microprocesador. Éste estaría compuestos por subcircuitos, por ejemplo el de la unidad de control, el de la unidad aritmético-lógica, memorias, registros, etc. Estos subcircuitos estarían conectados por líneas eléctricas, pueden ser simples como un cable o complejas como un bus. Una unidad de control estaría compuesta por más subcircuitos, más registros, más buses, etc.

Cuando se está diseñando en un determinado nivel, seguramente se empleen elementos de niveles más bajos. Para usar estos elementos de nivel bajo en un nivel más alto sólo se necesita conocer su interfaz, es decir, sus entradas y salidas, sobre ellas se conectarían los cables o buses que correspondieran.

Declaración de entidad

editar

La entidad sirve para definir las entradas y salidas que tendrá un determinado circuito. Para definir una entidad se realizará mediante la palabra reservada ENTITY.

En principio pudiera parecer que esta definición sea equivalente a la cabecera de una función de un lenguaje cualquiera de programación. En VHDL es más conveniente ver a la entidad como una caja negra con cables para las entradas y salidas. La ventaja de pensar en una entidad como en una caja negra a la que se conectan cables es que es más fácil comprender la ejecución concurrente que ocurrirá en el hardware. La descripción de cómo funciona por dentro esa caja negra es la arquitectura, que se verá en el siguiente capítulo.

A continuación se muestra la sintaxis de una entidad.

     ENTITY nombre IS
       [GENERIC(lista de parámetros);]
       [PORT(lista de puertos);]
     END [ENTITY] nombre;

La instrucción GENERIC define y declara propiedades o constantes del módulo. Las constantes declaradas en esta sección son como los parámetros en las funciones de cualquier otro lenguaje de programación, por lo que es posible introducir valores, en caso contrario tomará los valores por defecto. Para declarar una constante se indicará su nombre seguido de dos puntos y el tipo del que se trata, finalmente se indicará el valor al que es inicializado mediante el operador de asignación :=. En el caso que existan más constantes se terminará con un punto y coma, la última constante no lo llevará.

 nombre_constante : tipo := inicializacion;

La instruccion PORT definen las entradas y salidas del módulo definido. Básicamente consiste en indicar el nombre de la señal seguido de dos puntos y la dirección del puerto (se verá más adelante), además del tipo de señal del que se trata. Al igual que antes, si existe más de una señal se finalizará con un punto y coma, exceptuando la última señal de la lista.

 nombre_señal : dirección tipo;

A continuación se muestra un ejemplo de una entidad, con una serie de constantes y señales de entrada y salida.


     ENTITY mux IS
       GENERIC(
         C_AWIDTH : integer := 32;
         C_DWIDTH : integer := 32
       );
       PORT(
         control  : IN bit;
         entrada1 : IN bit;
         entrada2 : IN bit;
         salida   : OUT bit
       );
     END mux;


En este ejemplo la entidad de llama mux. Su interfaz se compone de las señales control, entrada1 y entrada2 como entradas de tipo bit y de la señal llamada salida como salida, también de tipo bit. Además, se incluyen dos constantes que servirán a la parte declarativa para realizar alguna operación.

En la introducción se vio como asignar las señales de entradas y salidas mediante la palabra PORT MAP, para el caso de los genéricos se realiza con la palabra reservada GENERIC MAP, esta parte se estudiará con mayor detalle en los siguientes capítulos. Un ejemplo para utilizar el código anterior como un componente sería el siguiente.


     mux_1 : ENTITY work.mux
       GENERIC MAP(
         C_AWIDTH => C_AWIDTH,
         C_DWIDTH => C_DWIDTH
       )
       PORT MAP(
         control  => control,
         entrada1 => entrada1,
         entrada2 => entrada2,
         salida   => salida
       );

Obsérvese que en todo momento se habla de señales y no de variables, para el caso de los puertos.

Direcciones de los puertos de una entidad

editar

Las señales representarían la función que harían los cables en un diseño hardware tradicional, es decir, sirven para transportar información y establecer conexiones. Dentro de una entidad los puertos son considerados como señales, en donde se pueden diferenciar varios tipos.

  • IN: Son señales de entrada, las cuales sólo se pueden leer, pero no se le pueden asignar ningún valor, es decir, no se puede modificar el valor que poseen. Por lo tanto, su funcionalidad es similar a las constantes.
  • OUT: Corresponden a las señales de salida, en este caso su valor puede ser modificado, pero en este caso no pueden leerse, es decir no pueden ser utilizadas como argumentos en la asignación de cualquier elemento.
  • INOUT: Este tipo es una mezcla de los dos anteriores, pueden ser utilizados tanto como de lectura o de escritura.
  • BUFFER: Es idéntico al anterior, con la diferencia de que sólo una fuente puede modificar su valor.
← Elementos básicos del lenguaje Entidad Arquitectura →