VHDL es usado generalmente para el diseño de Hardware. Este ejemplo comienza con un sumador completo cuya descripción se encuentra en el archivo adder.vhdl:
entity adder is -- i0, i1 y el carry-in ci son las entradas del sumador. -- s es la salida ( la suma ), co es el carry-out. port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit); end adder; architecture rtl of adder is begin -- La arquitectura de este sumador contiene dos asignaciones concurrentes. -- Calculamos la suma. s <= i0 xor i1 xor ci; -- Calculamos el acarreo ( carry ). co <= (i0 and i1) or (i0 and ci) or (i1 and ci); end rtl;
Podemos analizar el archivo de diseño:
$ ghdl -a adder.vhdl
Podemos tratar de ejecutar el diseño del "sumador", pero esto es innecesario, porque no obtendremos ningún resultado visible. Si queremos chequear el diseño, debemos correr un testbench. Este testbench es muy simple, debido a que el sumador también es muy simple: lo único que hace el tb es chequear exhaustivamente todas las entradas y controlar las salidas.
El archivo adder_tb.vhdl contiene el testbench para el sumador:
-- Un testbench no tiene puertos. entity adder_tb is end adder_tb; architecture behav of adder_tb is -- Declaración del componente que será instanciado. component adder port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit); end component; -- Especificamos que entidad está ligada con el componente. for adder_0: adder use entity work.adder; signal i0, i1, ci, s, co : bit; begin -- Instanciamos el componente. adder_0: adder port map (i0 => i0, i1 => i1, ci => ci, s => s, co => co); -- Este process hace realmente el trabajo. process type pattern_type is record -- Las entradas del sumador. i0, i1, ci : bit; -- Las salidas esperadas del sumador. s, co : bit; end record; -- Los patrones a aplicar. type pattern_array is array (natural range <>) of pattern_type; constant patterns : pattern_array :=(('0', '0', '0', '0', '0'),('0', '0', '1', '1', '0'), ('0', '1', '0', '1', '0'),('0', '1', '1', '0', '1'), ('1', '0', '0', '1', '0'),('1', '0', '1', '0', '1'), ('1', '1', '0', '0', '1'),('1', '1', '1', '1', '1')); begin -- Chequeamos cada patrón. for i in patterns'range loop -- Seteamos las entradas. i0 <= patterns(i).i0; i1 <= patterns(i).i1; ci <= patterns(i).ci; -- Esperamos por los resultados. wait for 1 ns; -- Chequeamos las salidas. assert s = patterns(i).s report "resultado de la suma erróneo" severity error; assert co = patterns(i).co report "acarreo de salida erróneo" severity error; end loop; assert false report "fin del test" severity note; -- Esperamos por siempre; esto terminará la simulación. wait; end process; end behav;
Como es usual, debemos analizar el diseño:
$ ghdl -a adder_tb.vhdl
Y construir un ejecutable para el testbench:
$ ghdl -e adder_tb
No debemos especificar que objetos son requeridos: GHDL los conoce y automaticamente los agrega en el ejecutable. Ahora, es tiempo de correr el testbench:
$ ghdl -r adder_tb
adder_tb.vhdl:52:7:(assertion note): fin del test
Si el diseño es algo más complejo, podríamos inspeccionar las señales. Los valores de las señales pueden ser volcados usando el formato de archivo VCD. El resultado puede ser leído con un visor de ondas como puede ser GTKWave. Primero debemos simular el diseño y volcarlo en un archivo de forma de onda.
$ ghdl -r adder_tb --vcd=adder.vcd
Luego, vemos las ondas:
$ gtkwave adder.vcd
- Inicie sesión o regístrese para enviar comentarios
- 668 lecturas
-



