Introducción
VHDL es extremadamente potente cuando un gran sistema se divide en sub-sistemas individuales, pequeños, y luego se va creando el sistema mediante la conexión de los componentes individuales. algunos les llaman sub-sistema, sub-componentes, otros sub-modulos, etc. también se le llama diseño top-down a este modo de dividir en partes pequeñas un sistema complejo.
Para poder construir un componente complejo a partir de diversos sub-componentes, VHDL tiene un par de instrucciones que facilitan este proceso: declaración de componente, e instanciacion de componente.
Declaración de Componentes
Para usar un componente ya
definido (entity/architecture), que va pasar a ser un sub-componente, en un nuevo componente es necesario primer
declarar el componente a usar, y luego instanciarlo. Una declaración de
componente simplemente específica la interface de E/S del componente mediante
el uso de los puertos de E/S (I/O ports), y los generics.
-- declaracion de component
component register
generic(bus);
port (
clk: in std_logic;
rst: in std_logic;
d_b: in std_logic_vector(bus-1 downto 0);
reg: out std_logic_vector(bus-1
downto 0)
);
end component;
Nota: cuando la cantidad de declaración de componentes sea un número considerable, es aconsejable declarar los componentes en un paquete. De este modo el código en sí queda mas ordenado, limpio, y fácil de seguir. De todos modos a partir de VHDL-2008 no hace falta la declaración de componentes si la sintaxis de la instanciación de componentes es similar a la que se detalla en el ejemplo debajo.
Instanciación de Componentes
Específica como las E/S del
componente declarado (usando la declaración de componente explicada
previamente), son conectadas en el diseño en que se utiliza el componente.
-- a)instanciacion de componente con
asociacion posicional
U1: register port map (sys_clk, sys_rst, data_bus, reg_data);
-- b) instanciacion
de componente con asociacion por nombre
U1: register port map (
clk => sys_clk,
rst => sys_rst,
d_b => data_bus,
reg => reg_data
rst => sys_rst,
d_b => data_bus,
reg => reg_data
);
-- c) instanciación en VHDL-2008 (sin declaración de componente)
U1: entity work.register port map
(
clk => sys_clk,
rst => sys_rst,
d_b => data_bus,
reg => reg_data
);
d_b => data_bus,
reg => reg_data
);
En la instanciación por posición, la lista de conexiones se hace en el mismo orden en que los puertos fueron declarados en la entidad del componente instanciado.
Se aconseja el uso de asociación por nombre, ya que es menos propensa a errores. En esta caso también se aconseja separar las asociaciones por funcionalidad mas que por si son entradas o salidas.
Ejemplo Sencillo
library
ieee;
use iee.std_logic_1164.all;
entity GATING is
port (A, CK, MR, DIN: in std_logic;
use iee.std_logic_1164.all;
entity GATING is
port (A, CK, MR, DIN: in std_logic;
RDY, CTRLA : out std_logic);
end GATING;
architecture STRUCT of GATING is
component AND2
port( X, Y: in std_logic;
Z : out std_logic);
end
component;
component DFF
port (D, CLOCK: in std_logic;
Q, QBAR : out std_logic);
end
component;
component NOR2
port ( DA, DB: in std_logic;
DZ : out std_logic);
end component;
signal S1, S2: std_logic;
begin
D1: DFF port map (A, CK, S1, S2);
A1: AND2 port
map (x => S2, y=>DIN, Z => CTRLA);
N1: NOR2 port
map (S1, MR, RDY);
end STRUCT;
Salidas no Usadas
En caso en que una salida del componente instanciado no se use cuando se instancia el componente, se debe explícitamente usar la palabra clave open para especificar que esa salida se deja abierta, no se utiliza, por lo que si es posible el sintetizado puede optimizar la lógica correspondiente.Entradas no Usadas
En caso en que una entrada del componente instanciado no se use cuando se instancia el componente, se debe explícitamente fijar un valor lógica a dicha entrada. Para ello se puede asociar la entrada no utilizada con '1' o '0'.
Generic Map
El generic es un valor constante usado para describir
en forma parametrizada una entidad. Ahora bien, diferentes instanciaciones de una misma
entidad pueden tener diferentes valores de generic,
para ello se usa el generic map.
Del mismo modo que antes, en caso de haber mas de un generic se puede usar asociación por posición o asociación por nombre.
Ejemplo:
entity registro_dff
generic(reg_width: positive);
port(
rst,clk: in std_logic;
d, q
: out std_logic_vector(reg_width-1 downto 0);
);
end entity registro_dff;
. . .
architecture
ejemplo of registro_dff is
....
....
end ejemplo;
-- instanciacion de registro_dff en otra entity
....
architecture test of registro_bus is
....
....
end ejemplo;
-- instanciacion de registro_dff en otra entity
constant
width_8 : positive:= 8;
constant
width_16: positive:= 16;
signal d8,
q8 : std_logic_vector(7 downto 0);
signal
d16, q16: std_logic_vector(15 downto
0);
. . .
begin
ff8: registro_dff generic map(width_8)
port map (rst, clk, d8, q8);
ff16: registro_dff generic map(width_16)
port map (rst, clk, d16,
q16);
. . .
end test;