Documente Academic
Documente Profesional
Documente Cultură
Gustavo G. Parma
1 Introdução Teórica
VHDL, VHSIC (Very High Speed Integrated Circuits) Hardware Description Language, foi desenvol-
vido como um padrão de linguagem de programação que descreve a estrutura e o funcionamento de
circuitos integrados digitais. Sendo um padrão desenvolvido pelo IEEE, a cada 5 anos é feita uma
revisão do assunto podendo haver modificações no padrão inicialmente proposto.
A utilização do VHDL possibilita o desenvolvimento metodológico de sistemas complexos. Inicial-
mente ele permite a descrição do sistema em partes, ou seja, ele permite a decomposição de um grande
sistema em subsistemas indicando como estes subsistemas estão conectados. Em segundo lugar, ele
permite a utilização de formas padrões de programação no desenvolvimento de um sistema digital e,
como conseqüência, ele permite a simulação do sistema digital antes de sua implementação. Além
disto, por ser uma linguagem padrão de programação de circuitos digitais, o código VHDL é desen-
volvido independentemente do CI a ser utilizado permitindo, desta forma, uma grande flexibilidade
na hora da implementação do sistema.
Por se tratar de uma linguagem de programação, VHDL segue alguns preceitos básicos de um
linguagem estruturada.
Em VHDL um elemento que executa uma função digital qualquer é chamado de entity e os pinos
de entrada ou saı́da deste componente estão listados na seção de port. A primeira etapa no desenvol-
vimento de um sistema digital utilizando VHDL é a definição da entidade e seus pinos de entrada e
saı́da, a qual funciona como a interface entre que o componente realmente faz e o mundo exterior a
ele. A declaração utiliza o seguinte código:
entity nome-do-elemento is
port (NPI1,NP2I,NPI3 : in tipo-variável;
NPI4,NPI5 : in tipo-variável;
NPO1,NPO2 : out tipo-variável;
NPO3,NPO4 : out tipo-variável);
end nome-do-elemento;
onde:
NPI1,NPI2,NPI3,NPI4 e NPI5 são os nomes dos pinos de entrada;
NPO1, NPO2, NPO3 e NPO4 são os nomes dos pinos de saı́da;
As palavras em negrito são palavras reservadas;
o tipo-variável indica qual o tipo da varı́avel de entrada/saı́da do pino. Este tipo define quais
operações podem ser executadas com um determinado pino. Os seguintes tipos são suportados pelo
software da Xilinx:
1. BOOLEAN: o mais abstrato dos tipos de variável. Uma variável booleana pode ser verdadeira
ou falsa;
2. INTEGER range 0 to 31: A variável inteira permite operações matemáticas básicas com os
sinais, devendo ser especificado os limites desta variável. Os limites máximos para uma variável
do tipo integer são: −(231 ) até (231 − 1). Não se pode ter acesso direto aos bits de uma variável
do tipo inteiro.
3. BIT: pode assumir dois valores lógicos, 0 ou 1;
4. BIT VECTOR (3 downto 0): vetor de bits, no caso um vetor de quatro elementos;
5. STD LOGIC; Este tipo é pré-definido em uma biblioteca do software. Esta biblioteca permite,
dentre outras coisas, o acesso aos bits de uma variável do tipo inteiro.
6. STD LOGIC VECTOR (0 to 3): similar ao tipo anterior, porém definindo um vetor de 4 ele-
mentos.
A associação de valores para as variáveis pode ser executada de duas formas distintas, em função
do tipo da variável e da forma como a variável foi definida (VARIABLE ou SIGNAL).
A := 1; – para VARIABLE
B <= 1; – para SIGNAL
C <=0 10 ; – para SIGNAL tipo BIT
D <= ”0101”; – para SIGNAL do tipo vetor de BIT (bit vector ou STD logic vector)
2
uma variável SIGNAL possui escopo global, ou seja, se a arquitetura possui mais de um processo,
todos os processos ”enxergam”a variável SIGNAL, enquanto que o escopo da variável VARIABLE é
local, somente o processo no qual ela foi definida consegue ”enxergá-la”.
variable A, B: BIT;
signal C: BIT VECTOR(1 to 4);
A := ’1’; – variável A possui o valor ’1’
B := ’0’; – variável B possui o valor ’0’
C <= ”1100”; – variável C possui o valor ”1100”
Em função do tipo da variável, pode-se executar operações matemáticas ou lógicas com a variável
criada. Os operadores em HDL podem ser lógicos, relacionais, unários, soma, multiplicadores ou
outros.
1. Operadores lógicos: AND, OR, NAND, NOR, XOR e NOT, podendo ser aplicados a variáveis
do tipo DIT, BOOLEAN ou vetores destes tipos. É importante ressaltar que a precedência de
execução do AND e igual à do OR, desta forma é importante separar os termos com parenteses
para que a implementação de uma dada função lógica não ocorra de forma erronea.
3
4. Operador de soma: podendo ser soma aritmética ou concatenação. Os operadores + e − são
utilizados para operação aritmética entre variáveis do tipo inteiro e o operador & é utilizado
para a concatenação de todo os tipos variáveis unidimensionais e é utilizado para a construção
de vetores.
Onde:
4
sensitivity list é a lista das variáveis (SIGNALs e PORTs) que serão acessı́veis ao processo, sepa-
rados por vı́rgula;
process declarative item é o espaço no qual são feitas as declarações de sub-programas, Tipos,
constantes e variáveis locais ao processo;
sequential statement é o espaço no qual é feita a programação sequencial, propriamente dita.
Pode-se utilizar os seguintes códigos de programa nos processos:
1. Comando IF THEN
if condition then
{ sequential statement }
{ elseif condition then
{ sequential statement } }
[ else
{ sequential statement } ]
end if;
Exemplo:
case expression is
when choices =>
{ sequential statement }
{ when choices =>
{ sequential statement } }
end case;
exemplo:
5
Z3 <= ’0’;
Z4 <= ’0’;
case VALUE is
when 0 => – verifica o 0
Z1 <= ’1’;
when 1 | 3 => – verifica o 1 ou 3
Z2 <= ’1’;
when 4 to 7 | 2 => – verifica o 2, 4, 5, 6 ou 7
Z3 <= ’1’;
when others => – verifica os valores restantes, 8 até 15
Z4 <= ’1’;
end case;
3. Comandos de LOOP
Existem ao menos três tipos de iteração para loops
(a) Loop: Esquema básico sem critério de parada pré-definido. O processo é executado ao
encontrar um comando NEXT ou um comando EXIT. Este esquema deve conter ao menos
uma linha de comando de espera.
[label :] loop
{ sequential statement }
end loop [label];
(b) while...loop: Este equema de loop possui um sistema de iteração booleana. Se a condição
da iteração for avaliada como TRUE, a sequencia é executada uma vez. A condição é,
então, reavaliada. O loop só irá terminar quando a condição for avaliada como FALSE.
Este esquema deve conter ao menos uma linha de comando de espera.
6
– segundo código, utilizando associação direta
A(1) <= B(1);
A(2) <= B(2);
A(3) <= B(3);
4. Comando WAIT
Uma linha de espera suspende a execução de um processo até que seja detectado uma transição
positiva ou negativa em um determinado sinal, pode-se utilizar as seguintes sintaxes:
5. Comando NEXT
Este comando termina a iteração corrente de um loop e muda para o primeiro comando dentro
do loop.
7
signal A, B: BIT VECTOR(1 downto 0);
signal A LESS THAN B: Boolean;
. . .
A LESS THAN B <= FALSE;
for I in 1 downto 0 loop
if (A(I) = ’1’ and B(I) = ’0’) then
A LESS THAN B <= FALSE;
exit;
elsif (A(I) = ’0’ and B(I) = ’1’) then
A LESS THAN B <= TRUE;
exit;
else
null; – continua a comparação
end if;
end loop;
É importante ressaltar que um processo não é chamado ou executado, ele é, simplesmente, im-
plementado. Uma arquitetura pode conter vários processos, sendo que os processos são concorrentes
entre si. Desta maneira, as atribuições a variáveis ou pinos dentro de um processo só acontece real-
mente ao fim do processo, se pensarmos de forma sequencial. Por isto deve-se tomar cuidado extra ao
se trabalhar com processos, nos quais podemos pensar de forma ”sequencial”(entre aspas) mas que é
implementado concorrentemente aos demais comandos da arquitetura.
8
2 Parte Experimental :
Desenvolva o código VHDL para a implementação do semáforo da aula anterior, o qual havia sido
implementado usando a ferramenta gráfica do Quartus II.