Você está na página 1de 65

UNIVERSIDADE DE BRASLIA

Apostila de VHDL
Traduo livre do material "The Low-Carb VHDL
Tutorial"
Copyright: 2004 por Bryan Mealy (27 - 08 - 2004)
Tradutores: Francisco Frantz e Daniel Almeida
24/02/2012

Introduo
VHDL uma abreviao para "Very high-speed integrated circuit Hardware Description
Language". Como hoje em dia se utiliza basicamente circuitos integrados para design de hardware,
suprimiu-se uma parte da sigla para simplificao.
H dois principais motivos para descrever hardware usando VHDL. Primeiramente, o VHDL
pode ser usado para modelar circuitos digitais. Isso permite fazer simulaes e testes, e, talvez mais
importante, criar um modelo na linguagem VHDL uma tima forma de aprendizado. Outro uso do
VHDL (ou outras linguagens de descrio de hardware) um dos primeiros passos na criao de
complexos circuitos digitais, podendo test-los sem a necessidade de constru-los fisicamente.
H outros simuladores lgicos disponveis que permitem modelar o comportamento de circuitos
digitais, que possuem uma abordagem grfica para descrever os circuitos. Pode ser um mtodo melhor
para o aprendizado, mas, quanto mais complexos forem os circuitos digitais, mais tedioso e confuso fica
esse mtodo, uma vez que se baseia na interconexo de linhas e portas lgicas. O VHDL propicia uma
descrio exata como o circuito digital funciona, sem ter de se preocupar com os detalhes das muitas
conexes internas ao mesmo. O conhecimento de VHDL ser uma ferramenta para modelar circuitos
digitais de uma maneira inteligente.
Finalmente, possvel criar circuitos funcionais usando o VHDL, o que permite implementar
rapidamente circuitos relativamente complexos. A metodologia usada permite dedicar mais tempo ao
projeto dos circuitos e menos a realmente constru-los em uma proto-board. Agora, deve-se descrever o
circuito usando uma linguagem como o VHDL. Para fazer isso, fundamental aprender a linguagem e
dominar suas ferramentas envolvidas no processo.

Sintaxe do VHDL
H diversos aspectos da linguagem VHDL que deve-se saber antes de prosseguir. Essa seo
detalha a sintaxe bsica de um cdigo em VHDL, como o uso de parntese e a atribuio de valores. So
aspectos caractersticos da linguagem de programao, assim como existem em C, C++, Matlab e todas as
outras. interessante memorizar o que ser abordado nessa seo, mas isso s possvel com a prtica.

Sensibilidade a letras maisculas


O VHDL no diferencia caracteres maisculos e minsculos. Isso quer dizer que ambas as
sentenas na figura 1 tem o mesmo sentido para o compilador. O objetivo agora no entender o que cada
sentena executa: isso ser visto na prxima seo.
Dout <= A and B;

doUt <= a AND b;

Figura 1: exemplo da indiferena entre maisculas e minsculas

Espaos em branco
O VHDL no sensvel a espaos em branco (espao e "tab") no documento fonte. As linhas de
cdigo da figura 2 tem o mesmo significado.
nQ <= In_a or In_b;

nQ

<= in_a

OR

in_b;

Figure 2: Exemplo da indiferena para espaos em branco

Comentrios
Isso vlido para todas as linguagens de programao: um uso adequado de comentrios melhora
a leitura e o entendimento de qualquer cdigo. A regra geral comentar toda linha ou seo de cdigo que
possa no ser bvia para outro leitor. Isso pode parecer tolo, uma vez que o cdigo executa com ou sem
os comentrios, mas de fundamental importncia, no apenas para outros leitores. Muitas vezes, faz-se
um cdigo em um dia e s se trabalha nele novamente depois de muito tempo. Na hora que o cdigo
feito, se entende tudo ele contm. Mas depois, h a necessidade de parar e pensar o que cada linha est
fazendo, o que poderia ser evitado com comentrios bem colocados. Em empresas que trabalham com
programao, h sempre uma poltica muito rgida em como devem ser comentados os cdigos. ,
portanto, uma boa prtica j comear a treinar.
No VHDL, os comentrios comeam com dois hfens ("--"), e o compilador ignora tudo que os
seguem na linha. No existe caractere que implemente comentrios de mais de uma linha. A figura 3
mostra alguns tipos de comentrios.

---------------------------Commentary
example--------------------------------- This next section of code is used to blah-blah
-- blah-blah blah-blah. This type of comment is the best
-- fake for block-style commenting.
PS <= NS_reg; -- Assign next_state value to present_state
Figura 3 - trs tipos tpicos de comentrio

Parnteses
O VHDL relativamente frouxo no uso de parnteses. Como em outras linguagens, h ordens de
procedncia associadas com os vrios operadores em VHDL. Mesmo sendo possvel escrever um cdigo
que segue essa ordem, uma boa prtica colocar alguns parnteses para melhorar a leitura do cdigo. As
duas sentenas da figura 4 possuem o mesmo significado para o compilador.
if x = 0 and y = 0 or z = 1 then
blah;
blah;
blah;
end if;
if ( ((x = 0) and (y = 0)) or (z = 1) ) then
blah;
blah;
blah;
end if;
Figura 4 - uso de parnteses e espaos para melhor leitura

Sentenas
Como em outras linguagens, toda sentena de cdigo em VHDL deve ser terminada com ponto e
vrgula (";"). Isso ajuda a remover eventuais erros de compilao do cdigo, uma vez que recorrente o
erro de esquecer o ponto e vrgula. Entretanto, deve-se entender o que constitui uma sentena em VHDL
para us-los corretamente: o VHDL no to flexvel quanto o Matlab, por exemplo, com colocaes a
mais ou a menos de pontos e vrgulas.

Declaraes if, case e loop


Uma fonte comum de frustrao enquanto se desenvolve um cdigo em VHDL o clssico erro
bobo envolvendo essas declaraes. As regras abaixo devem ser memorizadas para evitar esse tipo de
erro, evitando assim, perder tempo procurando os erros. altamente recomendvel marcar esta seo para
releitura quando estas declaraes forem melhor detalhadas.

Todo if tem de ter um correspondente then (se .... ento)


Todo if deve ser terminada por "end if"
Caso se queira usar um "else", a forma correta de faz-lo com "elsif"
Todo case terminado com "end case"
Todo loop tem um "end loop" correspondente

Identificadores
Identificador se refere ao nome dado aos itens em VHDL para discerni-los uns dos outros. Em
linguagens como C e Matlab, os nomes de variveis e de funes so identificadores. Em VHDL, h os
nomes de variveis, de sinais e de portas lgicas (sero discutidos em breve). H regras rgidas (precisam
ser seguidas) e regras flexveis ( bom serem seguidas) para usar identificadores, que podem tornar o
cdigo mais legvel, compreensvel e elegante se forem escolhidos apropriadamente. A lista e a tabela a
seguir mostram regras gerais para escolha de identificadores.
BONS IDENTIFICADORES
IDENTIFICADORES RUINS
3Bus_val
data_bus_val
Nome descritivo
DDD
WE
Clssica sigla para "write
enable"
div_flag

mid_$num

port_A

last__value

in_bus

Provavelmente "input bus"


Clssico nome para "system
clock"

clk

start_val_
in
@#$%%$
this_sucks
Big_vAlUe
pa
sim-val

Tabela 1: Identificadores desejveis e indesejveis

Identificadores devem realmente identificar o que representam, ou seja, ao olhar um identificador,


deve-se ter uma ideia da sua informao e do seu propsito
Identificadores podem ter quantos caracteres se desejar. Quanto mais curto, mais legvel; quanto
mais longo, mais informao ele possui. Deve-se levar isso em conta na hora de programar.
Identificadores s podem conter combinaes de letras (A-Z ou a-z), dgitos (0-9) e underlines
('_')
Identificadores s podem comear com caractere alfabtico
Identificadores no podem terminar em underline nem possuir dois deles consecutivos

Palavras reservadas
H uma lista de palavras s quais foi atribudo algum significado pela linguagem VHDL. Essas
palavras, chamadas palavras reservadas, no podem ser usadas como identificadores por programadores.
H uma pequena lista mostrada a seguir, e a lista completa se encontra no apndice A.
access
exit
mod
return
while
after
file
new
signal
with
alias
for
next
shared
constant
all
function
null
then
loop
attribute
generic
of
to
rem
block
group
on
type
wait
body
in
open
until
AND
buffer
is
out
use
OR
bus
label
range
variable
XOR
Tabela 2: Lista resumida de palavras reservadas em VHDL

NOR
XNOR
NAND

Estilo de programao
J falou-se disso neste material, mas deve-se reforar esse ponto. O estilo de programao de
refere aparncia do cdigo escrito em VHDL. Com a liberdade dada pela indiferena entre maisculas e
minsculas e quanto a espaos em branco, h a tendncia de se pensar no VHDL como uma linguagem
prxima da anarquia. Entretanto, deve-se sempre pensar na legibilidade do cdigo. Isso
primordialmente feito a parir dos identificadores, comentrios, espaos em branco e parnteses
desnecessrios. Abaixo, lista-se boas prticas para chegar ao objetivo da legibilidade.

Se o cdigo for legvel para o programador, provavelmente ser legvel para outras pessoas que
precisem ver o documento. Essas pessoas podem ser um colega do grupo de laboratrio, um
professor que avaliar o trabalho ou a pessoa que paga seu salrio ao final do ms. No primeiro
caso, pode no ser to motivante fazer um cdigo legvel; nos outros dois, altamente
recomendvel.
O cdigo pode ser modelado a partir de algum outro cdigo que se considere organizado e
legvel. Procurar um cdigo na internet e seguir seu estilo uma boa prtica para programadores
iniciantes.
Boas prticas durante a elaborao do cdigo propiciam uma melhor depurao de erros, caso
existam. O compilador de VHDL eficiente na deteco de erros, mas geralmente no diz onde
esses erros se encontram. Um cdigo organizado reduz o tempo de procura desses erros.

Unidades bsicas do VHDL


O VHDL descreve circuitos utilizando a abordagem das "caixas pretas". O circuito (e partes dele)
podem ser representados como caixas, que possuem entradas e sadas. Considere o seguinte exemplo:

Nesse caso, os pontos de interesse so as entradas (A,B e C) e a sada (F). No interessa, ainda, o
que acontece dentro da caixa preta para converter as entradas na sada. Essa parte da descrio do
circuito, ou seja, a caixa preta que indica as entradas e sadas (interface), chamada, em VHDL, de
entidade (entity).
Para saber como acontece essa medio da corrente, h diversas possibilidades de descrever o
problema. Por exemplo, supondo que F = A.B + B.C, as figuras a seguir descrevem formas de descrever o
que ocorre dentro da caixa preta:

Nesse caso, detalhe-se como a sada obtida a partir da entrada As interaes que ocorrem dentro
da caixa preta so definidos, em VHDL, como arquitetura (architecture). na arquitetura que so

definidos os parmetros da caixa preta (resistncia R) e os processos para a sada ser obtida.
interessante notar que, para uma mesma entidade, podem existir vrias arquiteturas.
Em VHDL, a entidade e a arquitetura so as unidades fundamentais para o projeto. Defini-se a
"caixa preta" e as "coisas que vo dentro da caixa preta". Ser sempre assim quando se trabalha com
VHDL. A criao da entidade, como se pode imaginar, muito simples, enquanto a arquitetura a parte
mais trabalhosa do projeto. Hoje em dia, na melhoria da arquitetura de circuitos que se concentra grande
parte dos esforos de engenheiros, e o VHDL uma plataforma interessante para simular diversos tipos
de arquitetura.

A entidade
Como foi dito, a entidade a verso em VHDL da caixa preta. Ela propicia um mtodo de
abstrair a funcionalidade de um circuito. A entidade simplesmente lista as entradas e sadas de um circuito
digital. Em termos de VHDL, a caixa preta descrita por uma declarao de entidade. A figura a seguir
mostra como essa declarao feita.
entity entity_name is
[port_clause]
end entity_name;
Figura 5: Forma genrica de uma declarao de entidade

O identificador entity_name serve para fazer referncia a entidade. A parte em colchetes,


[port_clause] realmente especifica a interface (entradas e sadas) da entidade. Sua sintaxe est
detalhada na figura abaixo.
port (
port_name
port_name
port_name
);

:
:
:

mode
mode
mode

data_type;
data_type;
data_type

Figura 6: Detalhamento de [port clause]

Uma "port" essencialmente um sinal que interage com o "mundo" fora da caixa preta. Pode ser
tanto um sinal de entrada na caixa preta quanto um sinal de sada dela. Colocando o cdigo da figura 6 no
lugar de [port_clause] na figura 5, a entidade est declarada por completo, ou seja,
[port_clause] nada mais do que uma lista de sinais do circuito que esto disponveis ao "mundo".
O port_name um identificador usado para diferenciar os diversos sinais. Onde se encontra " mode"
especifica-se a direo do sinal em relao caixa preta: pode ser input (entrada) ou output (sada). Para
os sinais de entrada, mode deve ser substitudo por in; para os de sada, por out. O "data_type" se refere
ao tipo de dados que a "port" possui. Em VHDL, h diversos tipos de dados, mas trabalharemos
primeiramente com o tipo std_logic; os diversos tipos de dados sero discutidos mais tarde.
A figura 7 mostra um exemplo de uma caixa preta e o cdigo VHDL que a descreve. Abaixo se
encontram algumas coisas importantes de se notar na figura; a maioria delas se refere a legibilidade e
clareza do cdigo. As palavras em negrito so apenas para lembrar as palavras-chave e no possuem
funo diferente no cdigo por estarem assim escritas.

Cada "port" possui nome nico e tem "mode" e "type" associados


O compilador do VHDL permite diversas ports em uma mesma linha, e elas so separadas por
vrgulas. type e mode so definidos no final da linha

A listagem de entradas e sadas feita de forma consecutiva


H uma tentativa de alinhar as colunas do nome da port, mode e type para melhor legibilidade:
vale lembrar que espaos em branco so ignorados pelo compilador
Um comentrio que diz coisas quase inteligentes foi adicionado

Figura 7: Caixa preta exemplo e seu cdigo

A figura 8 apresenta outra entidade em VHDL. Tudo que se foi dito sobre a figura 7 vlido
tambm para esta figura.

Figura 8: Outro exemplo de declarao de entidade

Pode ser que no esteja claro o que cada circuito acima faz, mas o importante entender como
feita a declarao da entidade.

A maior parte dos circuitos que sero projetados, analisados e testados usando VHDL tero
diversas entradas tendo similaridades entre as mesmas. Para no ser necessrio escrever cada entrada com
um nome diferente, pode-se agrup-las em "bus". Um bus ser um agrupamento de entradas, que diferem
entre si apenas por um caractere numrico que caracteriza a posio da respectiva entrada no bus. Cada
sinal do bus chamado de elemento. Pode-se fazer uma analogia: em um nibus, h diversos passageiros
sentados. O motorista no precisa saber o nome de cada passageiro para cham-lo, basta saber o nmero
do seu assento.
O uso de buses sintetiza muito o cdigo VHDL. Eles so usados frequentemente, e so facilmente
descritos no cdigo. Alguns exemplos constam na figura 9, onde deve-se notar que o mode permanece o
mesmo, enquanto o type mudou: o std_logic agora inclui a palavra vector para indicar que cada
identificador de sinal possui, na realidade, mais de um sinal. A forma de referenciar cada elemento do bus
ser detalhada mais adiante.
magic_in_bus : in std_logic_vector(0 to 3);
big_magic_in_bus : in std_logic_vector(7 downto 0);
tragic_in_bus : in std_logic_vector(16 downto 1);
data_bus_in_32 : in std_logic_vector(0 to 31);
mux_out_bus_16 : out std_logic_vector(0 to 15);
addr_out_bus_16 : out std_logic_vector(15 downto 0);
Figura 9: Alguns exemplos de sinais bus

Note que h duas maneiras possveis de se descrever sinais em um bus, que so mostrados nos
termos entre parnteses (lista de argumentos) que seguem a declarao de type. Os sinais podem ser
descritos em duas ordens: crescente (to) ou decrescente (downto). No existe um mtodo melhor que
outro, a escolha entre eles baseada na clareza do cdigo. O importante no esquecer como foi feita
essa definio.
Vamos analisar a notao para descrever os bus em uma caixa preta. A figura 10 mostra uma
caixa preta seguida da sua declarao de entidade. Note que usado um sinal de uma barra com um
nmero em cima, para indicar que a entrada ou sada um bus e quantos elementos ele possui.
importante notar que os sinais de entrada sel1 e sel0 poderiam ser descritos em um bus de dois elementos,
tendo em vista que ambos possuem mesmo type.

Figura 10: uma caixa preta contendo entradas e sadas bus, e sua respectiva declarao de entidade

A arquitetura
Enquanto a entidade descreve a interface ou a representao externa do circuito, a arquitetura
descreve o que o circuito realmente faz. Em outras palavras, a arquitetura descreve a implementao
interna da entidade associada. Como de se imaginar, descrever a entidade geralmente bem mais fcil
que descrever como o circuito deve operar. Isso cada vez mais verdade quanto mais complexos forem os
circuitos que se pretende projetar.
A parte mais desafiadora do VHDL aprender as inumerveis maneiras de se descrever um
circuito. A maior parte dessa apostila exatamente discutir os diferentes mtodos de descrever circuitos
lgicos, ento no ser feita uma discusso prolongada de arquiteturas nesse ponto. Entretanto, algumas
noes gerais so dadas seguir:

Podem existir diversas arquiteturas para descrever uma nica entidade. O estilo de cdigo na
arquitetura tem efeitos significativos no circuito sintetizado, ou seja, se o circuito for fisicamente
produzido, cada arquitetura ter um impacto diferente no resultado final. Uma pode proporcionar
maior velocidade, enquanto outra melhora o consumo de energia, por exemplo.
Os modelos bsicos para descrio de arquitetura so fluxo de dados, estrutural e
comportamental, bem como verses hbridas desses modelos, que sero descritos nas prximas
sees desse material.

O paradigma de programao em VHDL


A ltima seo foi uma breve introduo das unidades bsicas do VHDL: entidade e arquitetura.
A entidade est praticamente definida por completo, dada a sua simplicidade quando comparada com a
arquitetura. essencial lembrar que a entidade descreve a interface do circuito com o mundo, enquanto a
arquitetura descreve o funcionamento do circuito. Isso tem de estar claro nesse ponto.
Antes de entrar em detalhes das especificaes da arquitetura, devemos dar um passo atrs e
lembrar o que estamos fazendo com VHDL: estamos descrevendo um circuito digital. importantssimo
pensar nisso. A tendncia de alunos com alguma experincia em programao ver o VHDL apenas como
outra linguagem que devem aprender para passar em outra matria. Isso pode at funcionar para esse
propsito, mas isso uma m abordagem. O VHDL uma abordagem completamente difenrente
programao, mas como se assemelha em alguns aspectos a outras linguagens, h a tendncia de v-lo
como tal. Deve-se ter em mente que, para toda abstrao vlida na programao em outras linguagens, no
VHDL se est implementando algo fisicamente. Essa a diferena fundamental entre linguagens de
programao comuns e as que descrevem hardware.

Declaraes simultneas
As declaraes so o corao da maioria das linguagens de programao. Elas representam
quantidades finitas de "aes" a serem feitas. Em linguagens algortmicas, como C ou Java, elas
representam aes a serem feitas no processador, e, assim que terminada a ao, o processador comea a
ao seguinte, especificada em algum lugar do cdigo fonte associado. Isso faz sentido, e de certa forma
confortvel para humanos que, como o processador, costumam fazer uma ao por vez.
Por sua vez, o VHDL no funciona dessa maneira: tm-se a capacidade de executar um nmero
(virtualmente) infinito de aes ao mesmo tempo. Isso possvel quando pensamos que fazemos um
projeto de hardware com o VHDL, onde vrias coisas acontecem paralelamente, ou seja,
simultaneamente.
A figura 11 a seguir mostra um exemplo simples de um circuito que executa mltiplas aes
simultaneamente. A qualquer momento que uma entrada mudar, h a possibilidade da sada tambm
mudar, o que verdade para todos circuitos digitais em geral.

Figura 11: Circuito que executa aes simultaneamente


Aqui est a complicao: como somos humanos, somos capazes apenas de ler uma linha do
cdigo por vez de uma maneira sequencial, ento como podemos descrever alguma coisa que
inerentemente paralela? Esse problema no aparece quando se discute algo inerentemente sequencial,
como um algoritmo em linguagem de programao comum.

O paradigma da programao em VHDL se concentra no conceito de paralelismo de expresses e


simultaneidade de descries textuais de circuitos. A alma do VHDL so as declaraes simultneas, que
se assemelham a declaraes em linguagens algortmicas comuns mas so significativamente diferentes
porque executam mais de uma ao ao mesmo tempo.
Para ilustrar, a figura 12 mostra o cdigo que implementa o circuito da figura 11, que mostra
quatro declaraes de atribuio de sinal simultneas (concurrent signal assignement statements). O
smbolo "<=" o operador de atribuio de sinal. A verdade que no podemos escrever todas essas
operaes de uma s vez, mas devemos interpret-las como se estivessem ocorrendo simultaneamente.
Novamente, esse o principal ponto a ser entendido at aqui. Se o pensamento algortmico (sequencial)
comear se sobressair, tente cont-lo imediatamente. A prxima seo trar mais detalhes sobre atribuio
simultnea de sinais.
G <=
H <=
I <=
J <= G

A AND B;
C AND D;
E AND F;
OR H OR I;

Figura 12: Cdigo VHDL para o circuito da figura 11.

A figura 13 mostra um cdigo "C" que similar ao cdigo da figura 12. Nesse caso, as funes
lgicas foram substitudas operadores matemticos, e os operadores de atribuio de sinal por operadores
de atribuio. Nesse cdigo, cada linha executada por vez, ao contrrio do VHDL da figura 12.
importante ressaltar que a figura 13 NO um cdigo VHDL vlido.
G
H
I
J =

=
=
=
G

A
C
E
+

+
+
+
H

B;
D;
F;
+ I;

Figura 13: cdigo algortmico SIMILAR ao da figura 12 (no VHDL).

O operador de atribuio de sinal "<="


Todas linguagens algortmicas tem um tipo de operador de atribuio, por exemplo, Em "C" e
Matlab, o "=", enquanto em Pascal ":=". Esses operadores indicam uma transferncia de informaes
do lado direito para o lado esquerdo. Em VHDL, usa-se "<=", e conhecido oficialmente como operador
de atribuio de sinal, para deixar evidente o seu verdadeiro propsito. Ele especifica uma relao entre
os sinais, ou seja, o sinal esquerda do operador depende dos sinais direita do mesmo.
Sendo assim, voc j deve entender o cdigo da figura 12 e sua relao com a figura 11. A
declarao "G = A AND B;" indica que o valor do sinal "G" representa a operao AND, com entradas
A e B. J no caso da programao algortmica, "G = A + B;" indica que o valor representado pela
varivel A adicionado ao valor representado pela varivel B e o resultado da adio atribudo
varivel G. A distino entre as declaraes deve estar ficando mais clara agora.
H quatro tipos de declaraes simultneas que so examinadas nesse material. J foi examinado
brevemente a declarao simultnea de atribuio de sinal, e em breve ela ser analisada mais a fundo e
colocado no contexto de um circuito verdadeiro. Os outro trs tipos de declaraes simultneas so
declaraes de processo, atribuio condicional de sinais e atribuio seletiva de sinais.
Os 4 tipos de declaraes so ferramentas que podem ser utilizadas para implementar circuitos
digitais, e em breve, veremos a versatilidade desses tipos de declarao. Entretanto, deve-se ter em mente
que, devido essa versatilidade, h diversas maneiras de lidar com um mesmo problema. Assim, quando

se analisar um exemplo deste material, importante saber que este corresponde a uma soluo de um
conjunto muito grande delas, ento uma boa prtica tentar resolv-los de outra maneira, como exerccio.

Atribuies de sinal simultneas


A forma geral de uma atribuio simultnea apresentada na figura 14, onde target um sinal
que recebe o valor de expression, que pode ser uma constante, um sinal ou um conjunto de operadores
que operam em outros sinais e retornam algum valor.
target <= expression;
Figura 14: sitaxe da declarao de atribuio simultnea de sinal
EXAMPLO 1

Escreva um cdigo em VHDL para implementar uma porta lgica NAND de trs entradas. As entradas
devem ser nomeadas como A,B e C, e a sada como F.
Soluo: boa prtica sempre desenhar o diagrama do que se est projetando. Poderamos ter mostrado
diretamente o sinal da porta lgica NAND, mas usaremos uma caixa preta para no perder a generalidade.
Assim, a entidade j est praticamente declarada.

-- cabealho e bibliotecas
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity my_nand3 is -- define o nome da entidade
port ( A,B,C : in std_logic;
F : out std_logic);
end my_nand3;
architecture ex_nand3 of my_nand3 is
begin
F <= NOT (A AND B AND C);
--- Uma outra forma de se fazer:
-- F <= A NAND B NAND C;
-end ex_nand3;

Figura 15: resoluo do exemplo 1

Esse exemplo contm alguns detalhes que devem ser comentados:

Deve-se inserir arquivos de cabealho (header files) e bibliotecas (library files) para que o cdigo
compile de maneira correta. As linhas que descrevem essa insero esto descritas no topo do
cdigo da figura 15. As linhas aqui utilizadas possuem mais itens do que necessrio para este
exemplo, mas alguns exemplos subsequentes precisaro de todas elas.
O exemplo destaca o uso de diversos operadores lgicos. Os operadores disponveis em VHDL
so AND, OR, NAND, NOR, XOR e XNOR. O operador NOT no tecnicamente lgico mas
tambm est disponvel.

O exemplo 1 demonstra o uso da declarao de atribuio de sinal simultnea em um programa


VHDL, mas como s h uma declarao desse tipo, o conceito de simultaneidade no est evidente. A
ideia por trs dessa declarao que a sada muda sempre que um dos sinais de entrada mudar. Em outras
palavras, a sada F reavaliada sempre que um sinal na entrada muda. O exemplo a seguir ilustra melhor
a ideia de simultaneidade.
EXEMPLO 2
Escreva um cdigo em VHDL que implemente a funo descrita na tabela verdade a seguir:
L
0
0
0
0
1
1
1
1

M
0
0
1
1
0
0
1
1

N
0
1
0
1
0
1
0
1

F
0
1
0
0
0
0
1
1

Soluo: O primeiro passo no processo reduzir a funo dada. Apesar de no ser obrigatrio, pode
ajudar a diminuir o tempo usado para escrever o cdigo VHDL. Espera-se que o compilador em
reduziria o cdigo forma mnima em algum ponto, mas isso pode ser um desejo frustrado. O
diagrama da caixa preta e o cdigo VHDL associado so mostrados na figura 16.

F3L,M,N= L.M.N+ L.M

------------------------------------------------------------------------------------- cabealho e bibliotecas devem ser aqui inseridos: no o foram para poupar espao
-----------------------------------------------------------------------------------entity my_ckt_f3 is
port ( L,M,N : in std_logic;
F3 : out std_logic);
end my_ckt_f3;
architecture f3_1 of my_ckt_f3 is
signal A1, A2 : std_logic; -- sinais intermedirios (esto dentro da caixa preta)
begin
A1 <= ((NOT L) AND (NOT M) AND N);
A2 <= L AND M;
F3 <= A1 OR A2;
end f3_1;

Figura 16: soluo do exemplo 2

Esse exemplo contm novos conceitos e ideias. importante notar que as informaes de
cabealho e bibliotecas foram suprimidas, e isso vai acontecer em todos os exemplos subsequentes desse
material. Ento, para implementar os cdigos de exemplos, deve-se sempre inserir o cabealho e as
bibliotecas, como no exemplo 1. O mais importante, entretanto, notar que esse cdigo demonstra a
utilizao de declaraes de sinal (abaixo da declarao da arquitetura), que so usadas para declarar
sinais intermedirios. Essa abordagem anloga a declarar variveis extras em linguagens de
programao algortmica, onde pode-se utiliz-las para salvar resultados intermedirios que, no geral, no
so o ponto de interesse de um determinado programa. A declarao desses sinais feita de maneira
anloga declarao de ports na entidade. A figura 17 ilustra outra arquitetura que implementa a tabelaverdade, onde no necessrio fazer a declarao desses sinais.
architecture f3_2 of my_ckt_f3 is
begin
F3 <= ((NOT L) AND (NOT M) AND N) OR (L AND M);
end f3_2;

Figura 17: arquitetura alternativa f3_1

Apesar de as arquiteturas f3_1 e f3_2 das figuras 16 e 17 serem diferentes, elas funcionam da
mesma maneira. Isso porque todas as declaraes so de atribuies simultneas de sinal, porque, mesmo
f3_1 tendo trs declaraes desse tipo e f3_2 apenas uma, as declaraes em f3_1 so executadas
simultaneamente.
O exemplo 2 demonstra que pode-se facilmente converter uma funo em formato de tabelaverdade para cdigo VHDL. A converso da funo simplificada para declaraes de atribuio
simultneas de sinal foi de certa forma bem direta. A facilidade para se implementar ambas as arquiteturas
quase a mesma, mas deve-se notar que o exemplo 2 bem simples, tinha o objetivo de ilustrar as
atribuies simultneas de sinal. Para circuitos muito complexos, entretanto, essa abordagem fica tediosa,
e uma alternativa mostrada na seo a seguir.

Atribuio condicional de sinal


As declaraes de atribuio simultnea relacionam um alvo com uma expresso. O termo
atribuio condicional de sinal usado para descrever declaraes que tenham apenas um alvo mas

podem ter diversas expresses associadas, cada qual com uma determinada condio. Cada condio
avaliada sequencialmente at a primeira delas ser verdadeira (TRUE), onde a expresso associada a esta
condio avaliada e atribuda ao alvo. Apenas uma atribuio usada.
A sintaxe de atribuio condicional de sinal mostrada abaixo. O alvo nesse caso o
identificador de um sinal, e a condio baseada no estado de outros sinais no circuito. importante
notar que h apenas um operador de atribuio de sinal ("<=") com a declarao de atribuio
condicional.
target <= expression when condition else
expression when condition else
expression;
Figura 18: sintaxe da declarao de atribuio condicional de sinal

Essa talvez a forma mais fcil de entender no contexto de um circuito. Por exemplo, pode-se
refazer o exemplo 2 usando a atribuio condicional de sinal:
EXEMPLO 3
Escreva um cdigo em VHDL que implemente a funo descrita na tabela verdade a seguir:
L
0
0
0
0
1
1
1
1

M
0
0
1
1
0
0
1
1

N
0
1
0
1
0
1
0
1

F
0
1
0
0
0
0
1
1

Soluo: A entidade no muda do exemplo 2, ento a resposta ser simplificada como apenas a
arquitetura.
architecture f3_3 of my_ckt_f3 is
begin
F3 <= 1 when (L = 0 AND M = 0 AND N = 1) else
1 when (L = 1 AND M = 1) else
0;
end f3_3;

Figura 19: Soluo do exemplo 3

Alguns pontos interessantes:

Essa arquitetura parece dar mais trabalho que as anteriores, por ter mais entradas.
De fato, percebe-se que h apenas um alvo e diversas condies e expresses. A ltima expresso
a exceo s outras, ou seja, ela s executada se nenhuma outra for TRUE.

H razes mais fortes para se utilizar a atribuio condicional de sinal, e a mais clssica a
implementao de um multiplexador (MUX), descrita no exemplo a seguir.

EXEMPLO 4
Escreva um cdigo VHDL que implemente um multiplexador 4:1 usando uma nica declarao de atribuio
condicional de sinal. As entradas devem ser os dados D3, D2, D1, D0 e um bus de controle de duas entradas SEL.
A sada deve ser nica, e MX_OUT.

Soluo: Nesse exemplo deve-se recomear a descrio do problema. Isso inclu o diagrama de caixa
preta e a entidade associada. A figura 20 mostra a soluo completa.

------------------------------------------------------------------entidade e arquitetura do multiplexador 4:1 implementado usando


--atribuio condicional de sinal
--(no esquecer cabealho e bibliotecas se for compilar)
----------------------------------------------------------------entity my_4t1_mux is
port ( D3,D2,D1,D0 : in std_logic;
SEL : in std_logic_vector(1 downto 0);
MX_OUT : out std_logic);
end my_4t1_mux;
architecture mux4t1 of my_4t1_mux is
begin
MX_OUT <= D3 when (SEL = 11) else
D2 when (SEL = 10) else
D1 when (SEL = 01) else
D0 when (SEL = 00) else
0;
end mux4t1;

Figura 20: soluo do exemplo 4: 4:1 MUX usando atribuio condicional de sinal

Pontos interessantes:

A soluo parece eficiente se comparada quantidade de lgica que seria necessria caso fossem
utilizadas atribuies simultneas de sinal. Alm disso, o cdigo est bem legvel.
O operador relacional "=" usado em conjunto com um bus de sinais. Nesse caso, os valores do
bus SEL so acessados usando aspas, e no apstrofes.
Apenas para ser mais completo, foram includas todas as possibilidades do sinal SEL alm de um
else. Poderamos ter mudado a linha contendo '0' para D0 e removido a linha associada
condio SEL = "00", sendo assim, um descrio mas elegante da soluo.

importante ressaltar que, sempre que se fazemos uma atribuio condicional de sinal,
fisicamente temos um multiplexador implementado. Para fins de projeto, muito importante ter
conscincia disso.

Lembre-se que a atribuio condicional um tipo de declarao simultnea, onde a declarao


executada sempre que ocorrer uma mudana nos sinais da condio. Esse fato se assemelha declarao
de atribuio simultnea, onde a declarao executada sempre que um dos sinais direita do operador
<= muda.
A atribuio condicional de sinal um pouco menos intuitiva que a atribuio simultnea, mas
pode-se pensar nela de outra forma: ela se assemelha, em funo, s construes if-else das linguagens de
programao comuns. Essa relao ser melhor explorada quando falarmos de declaraes sequenciais.

Atribuio seletiva de sinal


A atribuio seletiva de sinal a terceira forma de declaraes simultneas que ser explorada.
Essas declaraes podem ter apenas um sinal alvo, e uma expresso determina em que so baseadas as
escolhas. Isso ficar mais claro a seguir. A sintaxe desse tipo de declarao mostrada abaixo.
with chooser_expression select
target <= {expression when choices, }
expression when choices;
Figura 21: sintaxe da atribuio seletiva de sinal
EXEMPLO 5
Escreva um cdigo em VHDL que implemente a funo descrita na tabela verdade a seguir, usando apenas a
atribuio seletiva de sinal.
L
0
0
0
0
1
1
1
1

M
0
0
1
1
0
0
1
1

N
0
1
0
1
0
1
0
1

F
0
1
0
0
0
0
1
1

Soluo: Esse outra verso do exemplo 2. O diagrama de caixa preta e a declarao de entidade desse
exemplo continuam as mesmas da figura 16, e a soluo est na figura 22.
architecture f3_4 of my_ckt_f3 is
begin
with ( (L = 0 AND M = 0 and N = 1) or
(L = 1 AND M = 1) ) select
F3 <= 1 when 1,
0 when 0,
0 when others;
end f3_4;

Figura 22: soluo ao exemplo 5

EXEMPLO 6
Escreva um cdigo VHDL que implemente um multiplexador 4:1 usando uma nica declarao de atribuio
seletiva de sinal. As entradas devem ser os dados D3, D2, D1, D0 e um bus de controle de duas entradas SEL. A
sada deve ser nica, e MX_OUT.

Soluo: Essa uma repetio do exemplo 4, exceto que a atribuio deve ser seletiva, no condicional.
A declarao de entidade no muda, mas ela repetida na figura 23. O diagrama de caixa preta o mesmo
da figura 20, e no repetido.
------------------------------------------------------------------ Entidade e arquitetura do MUX 4:1 do exemplo 6
-- Adicionar cabealho e bibliotecas caso queira compilar
----------------------------------------------------------------entity my_4t1_mux is
port ( D3,D2,D1,D0 : in std_logic;
SEL : in std_logic_vector(1 downto 0);
MX_OUT : out std_logic);
end my_4t1_mux;
architecture mux4t1_2 of my_4t1_mux is
begin
with SEL select
MX_OUT <= D3 when 11,
D2 when 10,
D1 when 01,
D0 when 00,
0 when others;
end mux4t1_2;

Figura 23: Soluo do exemplo 6

Novamente, h pontos a se destacar no exemplo 6, listados abaixo:

O cdigo possui diversas semelhanas com o da soluo do exemplo 4. A aparncia geral a


mesma. Ambas as solues so bem mais eficientes que se fosse usada atribuio simultnea de
sinal de maneira direta.
Ao invs de usar else, como na atribuio condicional, usa-se when others, para tratar dos casos
no abordados pelas condies listadas.
O circuito do exemplo um MUX 4:1, onde cada possvel condio da chooser_expression
(figura 21) - expresso de escolha - tem uma expresso correspondente nas atribuies de sinal.
Isso no necessrio, mas essencial que haja uma linha com when others no final da
declarao de atribuio seletiva.

EXEMPLO 7
Escreva um cdigo VHDL que implemente o seguinte circuito, que contm um bus de entrada contendo 4 sinais e
um de sada contendo 3 sinais. O bus de entrada, D_IN, representa um nmero binrio de 4 bits, e o bus de sada,
SZ_OUT, usado para indicar a magnitude do nmero de entrada. A relao entre entrada e sada mostrada na
tabela abaixo. Use uma declarao seletiva de sinal na soluo.
Margem de entrada de D_IN
Valor de sada de SZ_OUT

0000 at 0011

100

0100 at 1001
1010 at 1111
Condio desconhecida

010
001
000

Soluo:

------------------------------------------------------------------ Um circuito decodificador para o exemplo 7, usando atribuio


-- seletiva de sinal.
--- Adicionar cabealho e bibliotecas caso queira compilar
----------------------------------------------------------------entity my_ckt is
port ( D_IN
: in std_logic_vector(3 downto 0);
SX_OUT : out std_logic_vector(2 downto 0));
end my_ckt;
architecture spec_dec of my_ckt is
begin
with D_IN select
SX_OUT <= 100 when 0000 |
010 when 0100 |
|
001 when 1010 |
|
000 when others;
end spec_dec;

0001
0101
1000
1011
1110

|
|
|
|
|

0010 | 0011,
0110 | 0111
1001,
1100 | 1101
1111,

Figura 24: Soluo do exemplo 7

O nico comentrio dessa soluo que a barra vertical usada como um caractere de seleo na
seo choices (figura 21) da declarao de atribuio seletiva de sinal. Isso aprimora a legibilidade do
cdigo.
importante ressaltar novamente que a atribuio seletiva de sinal outra forma de atribuio
simultnea, o que se justifica porque sempre que a chooser_expression mudar, a atribuio seletiva ser
reavaliada.
Um ltimo comentrio sobre a soluo do exemplo 7: ela comparvel declarao switch ou
case de linguagens algortmicas de programao como "C" e Java no caso da primeira, e Matlab no caso
da segunda. Isso ser melhor explorado na seo de declaraes sequenciais.

A declarao de processo
A declarao de processo o ltimo tipo de atribuio simultnea que ser abordada, mas
primeiro, necessrio dar alguns passos para trs e explorar outras definies e princpios de VHDL que
no foram detalhados at este ponto. Lembre-se que h mais de mil maneiras de aprender alguma coisa,
especialmente uma linguagem de programao, onde h diversas solues para um mesmo problema.
Portanto, optou-se aqui por detalhar esse tipo de declarao depois, para ficar mais claro.

Arquiteturas comuns em VHDL


Como voc deve se lembrar, a arquitetura do VHDL descreve a funo de alguma entidade. A
arquitetura composta de duas partes: a seo de declarao, onde se nomeia a arquitetura, seguida de
uma coleo de declaraes simultneas. Estudamos trs tipos de declaraes simultneas at este ponto:
atribuio de sinal simultnea, atribuio condicional de sinal e a atribuio seletiva de sinal.
H trs diferentes estilos para se escrever arquiteturas no VHDL. Elas so fluxo de dados,
estrutural e comportamental. Geralmente, se introduz cada estilo individualmente, usando como exerccio
elaborar circuitos para cada um deles, o que uma abordagem boa por ser simples, mas um pouco
inapropriada quando se fala de circuitos mais complexos, onde se utiliza uma mistura dos estilos de
programao. importante ter isso em mente na discusso que segue, onde o foco estar nos estilos de
fluxo de dados e comportamental. A modelagem pelo estilo estrutural essencialmente um mtodo de
combinar um conjunto de modelos. Por esse motivo, no tanto um mtodo de modelagem quanto uma
forma de interligar modelos previamente elaborados.

A arquitetura por fluxo de dados


At este ponto, todos os exemplos deste material foram feitos utilizando o estilo de fluxo de
dados. Esse estilo de arquitetura especifica um circuito como uma representao simultnea do fluxo dos
dados que atravessam o circuito. Os circuitos so descritos mostrando-se a relao entre entrada e sada,
utilizando os componentes existentes na linguagem VHDL (AND,OR,XOR,NOT,etc). As trs formas de
declaraes simultneas que detalhamos at agora so todas encontradas no estilo de fluxo de dados. Se
voc examinar alguns exemplos que fizemos at agora, poder de fato ver como os dados fluem pelo
circuito, pelas declaraes de atribuio de sinal, que realmente descrevem como os dados dos sinais do
lado direito do operador <= fluem para o lado esquerdo do mesmo.
O estilo de arquitetura de fluxo de dados tem seus pontos fortes e fracos. Ele possibilita a
visualizao do fluxo de dados no circuito por simples inspeo do cdigo, alm de ser possvel fazer
uma boa predio de como o circuito lgico seria montado fisicamente. Para circuitos mais complexos,
entretanto, vantajoso utilizar a modelagem pelo estilo comportamental.

O estilo comportamental de arquitetura


Em comparao com o estilo por fluxo de dados, o estilo comportamental no nos provm de
detalhes de como o modelo implementado em hardware, ou seja, o cdigo VHDL escrito no estilo
comportamental no necessariamente reflete como o circuito implementado quando sintetizado. Ao
contrrio, ele descreve como as sadas reagem (ou se comportam) s entradas. O estilo comportamental
essencialmente a utilizao da abordagem da caixa-preta para modelar os circuitos, onde efetivamente
no se sabe o que acontece dentro da caixa, apenas se sabe a sada para cada entrada. A ferramenta de
sntese do VHDL o que decide como o circuito ser descrito fisicamente.
Todo esse estilo est centrado na declarao de processo, quarto tipo de declarao simultnea
sobre a qual ser falado. Ele significativamente diferente dos outros trs tipos estudados at aqui. A
maior diferena reside na abordagem de simultaneidade desse tipo de declarao, que a grande
dificuldade no aprendizado da declarao de processo.

A declarao de processo
Para compreender a declarao de processo, vamos primeiramente examinar as suas semelhanas
com a declarao de atribuio simultnea de sinal, para depois detalharmos as diferenas entre esses dois
tipos de declarao.
A figura 25 ilustra a sintaxe da declarao de processo. O mais importante de se notar que o
corpo da declarao de processo consiste de declaraes sequenciais, como as utilizadas nas linguagens
de programao usuais (C, Java, Pascal, etc). Essa a principal diferena entre as declaraes simultneas
de atribuio de sinal e as de processo, mas vamos focar agora nas semelhanas.
label: process(sensitivity_list)
begin
{sequential_statements}
end process label;

Figura 25: sintaxe da declarao de processo

A seguir, a figura 26 mostra a declarao de entidade para uma funo XOR, enquanto a figura 27
mostra dois estilos de arquiteturas possveis, um usando fluxo de dados e outro comportamental. A maior
diferena reside na presena da declarao de processo no estilo comportamental.
Lembre-se que a declarao de atribuio simultnea de sinal na descrio por fluxo de dados
opera da seguinte forma: a qualquer momento que houver uma mudana nos sinais listados direita do
operador <=, o sinal esquerda ser reavaliado. No caso da descrio comportamental da arquitetura,
sempre que um sinal presente na sensitivity_list de uma declarao de processo mudar, todas as
declaraes sequenciais do processo sero reavaliadas. Ou seja, a avaliao do processo controlada
pelos sinais presentes na "lista de sensibilidade" do processo, enquanto para as atribuies de sinal, para
qualquer mudana, necessria reavaliao. Essas abordagens so essencialmente as mesmas, apenas
com uma mudana significativa na sintaxe.
Neste ponto, pode ficar um tanto estranho. Mesmo que ambas as arquiteturas da figura 27 tenham
exatamente a mesma atribuio de sinal (F <= A XOR B;), a execuo dessa atribuio no modelo
comportamental controlada pelos sinais que aparecem na lista de sensibilidade do processo, enquanto
para o fluxo de dados, a atribuio executada sempre que houver mudana nos sinais A ou B. Aqui notase uma diferena na funcionalidade de cada estilo.
entity my_xor_fun is
port ( A,B : in std_logic;
F : out std_logic);
end my_xor_fun;

Figura 26: declarao de entidade para um circuito que implementa a funo XOR

architecture my_xor_dataflow of my_xor_fun is


begin
F <= A XOR B;
end my_xor_dataflow;
architecture my_xor_behavioral of my_xor_fun is
begin
xor_proc: process(A,B)
begin
F <= A XOR B;
end process xor_proc;
end my_xor_behavioral;

Figura 27: Descrio da entidade my_xor_fun usando as descries por fluxo de dados e comportamental.

A outra grande diferena entre as arquiteturas por fluxo de dados e comportamental reside no
corpo da declarao de processo, que contm apenas declaraes sequenciais. A seguir, mostramos alguns
tipos dessas declaraes.

Declaraes sequenciais
O termo "declarao sequencial" vem do fato de as declaraes dentro do corpo de um processo
so executadas sequencialmente, ou seja, uma de cada vez. A execuo das declaraes sequenciais
comea quando ocorre uma mudana em algum sinal contido na lista de sensibilidade do processo, e
termina quando todas as declaraes de dentro do processo forem executadas.
H trs tipos de declaraes simultneas com as quais trabalharemos. Com a primeira (atribuio
de sinal), j estamos bem familiarizados, ento no a discutiremos com muitos detalhes. As outras duas
so if e case, provavelmente j discutidas em outra(s) disciplina(s) de programao algortmica. Em
VHDL, a estrutura e funo das declaraes if e case so exatamente as mesmas.

A declarao de atribuio de sinal


Nesse ponto, ficar mais claro porque sempre temos o cuidado de falar atribuio simultnea de
sinal quando se trabalha com a descrio por fluxo de dados.
Sintaticamente, a atribuio de sinal em um processo e a atribuio simultnea de sinal so
equivalentes. Entretanto, em um processo, todas as declaraes so sequenciais, por isso h essa diferena
na nomenclatura da declarao de atribuio de sinal. Por exemplo, na arquitetura por fluxo de dados da
figura 27, a atribuio de sinal do tipo simultnea, enquanto na arquitetura comportamental, a mesma
atribuio de sinal sequencial. As diferenas funcionais entre declaraes simultneas e sequenciais j
foram discutidas na seo de declaraes de processos.

Declarao IF
A declarao if usada para criar um ramo no fluxo de execuo de declaraes sequenciais.
Dependendo das condies listadas no corpo da declarao if, podem ser realizadas as instrues de um
ou de outro (ou at mesmo de nenhum) ramo do cdigo. A forma geral de uma declarao if mostrada na
figura 28.

if (condition) then
{ sequence of statements }
elsif (condition) then
{ sequence of statements }
else
{ sequence of statements }
end if;

Figura 28: Sintaxe da declarao if

A ideia da declarao if deve ser familiar para voc em duas olhadas. Primeiramente, sua forma e
funo so parecidas com a maioria das linguagens de programao algortmicas; a sintaxe, entretanto,
um pouco diferente. Alm disso, o if em VHDL a declarao sequencial equivalente da declarao de
atribuio condicional de sinal. Essas duas declaraes tem essencialmente a mesma funo, mas a
declarao if a declarao sequencial encontrada dentro de um processo, enquanto a declarao de
atribuio condicional de sinal uma forma de atribuio simultnea.
Pontos importantes da declarao if:

Os parnteses usados ao redor da expresso de condio condition so opcionais, mas bom


inclu-los para ter uma melhor legibilidade do cdigo.
Cada declarao if ou elseif possui um then associado (traduzindo: "se ... ento; "caso contrrio,
se ... ento"). O ltimo else no possui then associado.
Como na figura 28, o else uma expresso que abrange todas as excees. Caso nenhuma das
condies prvias for avaliada como verdadeira, a sequncia de declaraes associada ao ltimo
else executada. Dessa forma, ao menos uma sequncia de instrues presentes no corpo do if
ser executada.
O ltimo else, entretanto, opcional. A no incluso do mesmo pode implicar na no execuo de
nenhuma sequncia de declaraes do if.

EXAMPLO 8

Escreva um cdigo em VHDL que implemente a seguinte funo lgica usando uma declarao IF

FoutA,B,C= A.B.C+ B.C


Soluo: Embora no seja dito diretamente na descrio do problema, o cdigo deve ser feito utilizando a
arquitetura comportamental, uma vez que deve ser usada uma declarao if. O cdigo de soluo
mostrado na figura 29, onde no mostrado o diagrama de caixa-preta devido simplicidade do
problema.
entity my_ex_7 is
port ( A,B,C : in std_logic;
F_OUT : out std_logic);
end my_ex_7;
architecture dumb_example of my_ex_7 is
begin
proc1: process(A,B,C)
begin
if (A = 1 and B = 0 and C = 0) then

F_OUT <= 1;
elsif (B = 1 and C = 1) then
F_OUT <= 1;
else
F_OUT <= 0;
end if;
end process proc1;
end dumb_example;

Figura 29: Soluo do exemplo 8

Essa provavelmente no a melhor maneira de implementar a funo lgica, mas serviu para
ilustrar a declarao if. Outra possvel arquitetura que soluciona o problema mostrada na figura 30,
enquanto o exemplo 9 apresenta um problema em que o uso da declarao if mais adequada.
architecture bad_example of my_ex_7 is
begin
proc1: process(A,B,C)
begin
if (A = 0 and B = 0 and C = 0) or
(B = 1 and C = 1) then
F_OUT <= 1;
else
F_OUT <= 0;
end if;
end process proc1;
end bad_example;

Figura 30: soluo alternativa ao problema do exemplo 8


EXAMPLO 9

Escreva um cdigo VHDL que implemente o MUX 8:1 mostrado abaixo. Utilize uma declarao if.

Soluo: A figura 31 mostra uma possvel soluo para o problema.


entity mux_8t1 is
port ( Data_in : in std_logic_vector (7 downto 0);
SEL : in std_logic_vector (2 downto 0);
F_CTRL : out std_logic);
end mux_8t1;
architecture my_8t1_mux of mux_8t1 is
begin
my_proc: process (Data_in,SEL)
begin
if (SEL = 111) then F_CTRL <=
elsif (SEL = 110) then F_CTRL
elsif (SEL = 101) then F_CTRL
elsif (SEL = 100) then F_CTRL

Data_in(7);
<= Data_in(6);
<= Data_in(5);
<= Data_in(4);

elsif (SEL = 011)


elsif (SEL = 010)
elsif (SEL = 001)
elsif (SEL = 000)
else F_CTRL <= 0;
end if;
end process my_proc;
end my_8t1_mux;

then
then
then
then

F_CTRL
F_CTRL
F_CTRL
F_CTRL

<=
<=
<=
<=

Data_in(3);
Data_in(2);
Data_in(1);
Data_in(0);

Figura 31: Soluo ao problema do exemplo 9


EXAMPLO 10

Escreva um cdigo VHDL que implemente o MUX 8:1 mostrado abaixo, utilizando quantas
declaraes if forem necessrias. No diagrama de caixa preta abaixo, a entrada CE um "chip enable",
ou seja, quando essa entrada for "1", a sada ser como a do MUX do exemplo 9, e quando for "0", a
sado do MUX "0".

Soluo: A soluo para o exemplo 10 similar do exemplo 9. Note que nessa soluo as declaraes if
podem ser aninhadas (colocadas umas dentro das outras) para melhorar o cdigo. A figura 32 exibe a
soluo do exemplo 10.
Figura 32: Soluo ao problema do exemplo 10

Declaraes CASE
A declarao case de certa forma similar declarao if no sentido que uma sequncia de
declaraes executada quando sua expresso associada for verdadeira. A figura 33 abaixo ilustra a
sintaxe da declarao case.
case (expression) is
when choices =>
{sequential statements}
when choices =>
{sequential statements}
when others =>
{sequential statements}
end case;
Figura 33: Sintaxe da declarao case

Como no caso da declarao if, a case deve estar familiar em poucas olhadas. Primeiramente,
pode ser considerada uma forma diferente e talvez mais compacta do if, no sendo, entretanto, to

funcional quanto. Alm disso, o case tambm utilizado em outras linguagens de programao, com
muitas similaridades em formato e funo. Finalmente, o case em VHDL a declarao sequencial
equivalente da atribuio seletiva de sinal, que um tipo de atribuio simultnea. A linha " when
others " no necessria, mas uma boa prtica inclu-la para trabalhar com situaes inesperadas.
A seguir, um exemplo de como se usar a declarao case.
EXEMPLO 11

Escreva um cdigo em VHDL que implemente a seguinte funo usando uma declarao case
Fout(A,B,C) = A.B.C + B.C
Soluo: Novamente, este exemplo cai na categoria de no ser a melhor forma de implementar o circuito
usando o VHDL. Entretanto, ele ilustra o uso da declarao case, outra ferramenta importante em VHDL.
A primeira parte da soluo requere que listemos a funo como uma soma de mintermos. Se este assunto
ainda no foi abordado em sala, no se preocupe: apenas tenha em mente que a seguinte simplificao
ajuda a resolver este problema, e, em breve, este assunto ser detalhado em sala. De forma simplificada,
multiplica-se o produto que no possui termo com A por 1, no caso, A+A. Assim, teremos a funo lgica
como uma soma de produtos, sendo que cada produto possui todas as variveis inclusas uma nica vez:
Fout(A,B,C) = A.B.C + A.B.C+A.B.C.
A segunda parte da soluo mostrada na figura 34, onde interessante notar que o agrupamento
dos trs sinais de entrada nos possibilitou utilizar uma declarao case como soluo. Essa abordagem
demandou a definio de um sinal intermedirio "ABC". Vale ressaltar que essa provavelmente no a
forma mais eficiente de solucionar este problema.
entity my_example is
port ( A,B,C : in std_logic;
F_OUT : out std_logic);
end my_example;
architecture my_soln_exam of my_example is
signal ABC: std_logic_vector(2 downto 0);
begin
ABC <= (A,B,C); -- Agrupa os sinais para usar o case
my_proc: process (ABC)
begin
case (ABC) is
when 100 => F_OUT <= 1;
when 011 => F_OUT <= 1;
when 111 => F_OUT <= 1;
when others => F_OUT <= 0;
end case;
end process my_proc;
end my_soln_exam;

Figura 34: Soluo para o exemplo 11

A seguir, refazemos o exemplo 10, mas usando o case. Note a mudana quanto legibilidade.
EXEMPLO 12

Escreva um cdigo com VHDL que implemente o MUX 8:1 mostrado abaixo, utilizando uma
declarao case. No diagrama de caixa preta abaixo, a entrada CE um "chip enable", ou seja, quando
ela for "1", o chip est ligado e a sada a de um MUX normal; quando for "0", o chip est desativado
e a sada "0".

Soluo: A soluo mostrada abaixo, na figura 35. A declarao de entidade foi repetida para sua
convenincia. A soluo insere o case dentro de uma declarao if. Caso ainda no esteja claro, o nmero
de possveis solues para um problema aumenta com a complexidade do mesmo.
entity mux_8t1_ce is
port ( Data_in :
SEL :
CE :
F_CTRL :
end mux_8t1_ce;

in std_logic_vector (7 downto 0);


in std_logic_vector (2 downto 0);
in std_logic;
out std_logic);

architecture my_case_ex of mux_8t1_ce is


begin
my_proc: process (SEL,Data_in,CE)
begin
if (CE = 1) then
case (SEL) is
when 000 => F_CTRL <= Data_in(0);
when 001 => F_CTRL <= Data_in(1);
when 010 => F_CTRL <= Data_in(2);
when 011 => F_CTRL <= Data_in(3);
when 100 => F_CTRL <= Data_in(4);
when 101 => F_CTRL <= Data_in(5);
when 110 => F_CTRL <= Data_in(6);
when 111 => F_CTRL <= Data_in(7);
when others => F_CTRL <= 0;
end case;
else
F_OUT <= 0;
end if;
end process my_proc;
end my_case_ex;

Loop FOR
Como em outras linguagens de programao, o loop for usado quando o programador sabe o
nmero de iteraes que o loop ir realizar. Geralmente, declara-se o intervalo sobre o qual sero
realizadas as iteraes. Esse intervalo pode ser descrito de duas formas: a) o intervalo pode ser
especificado na declarao do loop for ou b) o loop pode usar um intervalo definido anteriormente.

Figura 35: Loops for equivalentes que em a) especifica o intervalo e em b) usa um intervalo especificado
anteriormente.

Algumas observaes devem ser feitas a respeito da varivel de indexao para evitar futuros
erros ao se compilar o cdigo:

A varvel de indexao no precisa ser declarada.


A varivel de indexao no pode ser usada em atribuies. Porm, ela pode ser usada para clculos dentro
do loop.
A varivel de indexao s incrementada no loop em passos de um.
Como mostrado na figura anterior, o comando downto pode ser usado para declarar o intervalo da iterao.

Loops WHILE
Loops while no possuem uma varivel de indexao e so, portanto, considerados mais simples
de se trabalhar do que os loops for. A principal diferena entre os loops for e while o fato de a estrutura
do loop while no conter um critrio de parada j embutido, como ocorre com o loop for. Ainda assim, o
cdigo associado ao loop while deve conter algum critrio para que o loop termine. Na figura abaixo, h
alguns exemplos:

Figura 36: Dois exemplos para o clculo da sequncia Fibonacci usando while.

Declaraes NEXT e EXIT


A declarao next permite que o loop ignora as instrues restantes da linha de comando e inicie a
prxima iterao.

Figura 37: Exemplos da declarao next em loops for e while.

A declarao exit implica no trmino imediato da iterao:

Figura 38: Exemplos da declarao exit em loops for e while.

Operadores
Esta seo ir apresentar listagem dos principais operadores usados em VHDL. Sero apresentados alguns
operadores lgicos, relacionais, de troca, de adio, de incremento, de multiplicao e outros que no se
encaixam nos anteriores. Essa ordem na qual foram listados, a ordem de prioridade a partir da qual os
operadores sero analisados.
Essa prioridade s existe entre os tipos de operadores. Em uma mesma classe de operadores, no
existe diferena de prioridade; essa, se existir, deve ser indicada pelo uso de parnteses. Abaixo segue
uma tabela com os operadores mais comuns usados em VHDL:
Tipos de operadores
Lgicos

and

or

nand

nor

xor

xnor

Relacionais

/=

<

<=

>

>=

Troca

s11

sr1

s1a

sra

ro1

ror

Adio

Sinal

Multiplicao

abs

rem

Outros

**

abs

&

not

Operadores lgicos
So auto-explicativos: utilizados para realizar as operaes lgicas entre os sinais.

Operadores relacionais
Os operadores relacionais iro relacionar variveis de diversas formas. Alguns deles j foram
utilizados em exemplos anteriores e uma lista com a funo de cada um segue abaixo:

Operador

Nome

Explicao

Equivalncia

O valor x equivalente ao valor y?

/=

No equivalncia O valor x no-equivalente ao valor y?

<

Menor que

O valor x menor que o valor y?

<=

Menor ou igual a

O valor x menor ou igual ao valor y?

>

Maior

O valor x maior que o valor y?

>=

Maior ou igual a

O valor x maior ou igual ao valor y?

Operadores de troca
H trs tipos de operadores de troca: troca simples, troca aritmtica e rotao. A funo desses
operadores basicamente acrescentar zeros palavra binria em alguma ordem, seja da direita pra
esquerda, ou da direita pra esquerda. As poucas diferenas entre eles podem ser vistas abaixo:
Operadores de troca simples: acrescentam zeros palavra binria em uma determinada ordem,
dependendo do comando utilizado. O operador ssl (shift left) acrescenta zeros da direita pra
esquerda e o operador ssr (shift right), da esquerda para direita. Exemplo: tomando a palavra
110111 iremos realizar as duas operaes em cima dela:
result <= 110111 ssl 2
result <= 110111 ssr 3
011100
000110
Nesse caso, acrescentam- se dois zeros no final da
Nesse caso, acrescentam- se trs zeros no
palavra binria, fazendo com que os outros bits se incio da palavra binria, fazendo com que os outros
desloquem para a esquerda.
bits se desloquem para a direita.

Operadores de troca aritmtica: fazem a mesma operao dos operadores de troca simples com a
diferena de que os bits mais significativos (bits de sinal) no so alterados. O comando sla (shift
left arithmetic) equivalente ao ssl e o comando slr (shift left arithmetic) equivalente ao ssr. Ou
seja, :

result <= 110011 sla 2


result <= 110011 slr 3
101100
100010
Nesse caso, acrescentam- se dois zeros no final da Nesse caso, acrescentam- se trs zeros no incio da
palavra binria, fazendo com que os outros bits se palavra binria, fazendo com que os outros bits se
desloquem para a esquerda, sem que o bit de sinal desloquem para a direita, sem que o bit de sinal seja
seja
alterado.
alterado.

Operadores de rotao: transportam uma quantidade de bits definida pelo usurio de uma das
extremidades de uma palavra para sua outra extremidade. O comando rol (rotate left) transporta
os bits da extremidade esquerda para a extremidade direita e o comando ror (rotate right) faz o
contrrio, transporta os bits da extremidade direita para a extremidade esquerda. Exemplos:

result <= 101000 rol 2


010010
Os dgitos 10 em negrito foram levados da
extremidade esquerda para a direita pelo comando
rol.

result <= 101001 ror 2


011010
Os dgitos 01 em negrito foram levados da
extremidade direita para a esquerda pelo comando
ror.

Operadores de troca
Os outros operadores so geralmente utilizados para manipulao numrica, sendo alguns de
utilidade bem bvia. A lista abaixo segue com alguns detalhes desses operadores sendo que os operadores
mod, rem e & sero um pouco mais detalhados.

Operador
Adio
Sinal
Multiplicao

Outros

Nome

Comentrio

Adio

Calcula a operao entre dois nmeros.

Subtrao

Calcula a operao entre dois nmeros.

Identidade

Especifica o sinal de um nmero.

Negao

Especifica o sinal de um nmero.

Multiplicao

Calcula a operao entre dois nmeros.

Diviso

Calcula a operao entre dois nmeros.

mod

Mdulo

rem

Resto

**

Exponenciao Calcula a operao entre dois nmeros.

abs Valor absoluto Calcula o valor absoluto de um nmero.


&

Concatenao

Operador de concatenao (&): muito usado em circuitos digitais pois possvel atribuir ao valor
de uma varivel, o valor de outras variveis concatenadas. Por exemplo:
signal A_val, B_val : std_logic_vector(3 downto
0);
signal C_val, E_val : std_logic_vector(6 downto
0);
signal D_val, F_val : std_logic_vector(8 downto
0);
C_val <= A_val & 000;
E_val <= 111 & B_val;
D_val <= 00001 & A_val;
F_val <= A_val & B_val & 0;

Pelo cdigo acima, concluimos o seguinte:

C_val um vetor de 7 posies. As quatro primeiras posies sero preenchidas pelas


componentes do vetor A_val e as outras trs por zeros (000);
E_val um vetor de 7 posies. As trs primeiras posies sero preenchidas por uns
(111) e as outras quatro pelas componentes do vetor B_val;
D_val um vetor de 9 posies. As cinco primeiras posies sero preenchidas pelo
conjunto de bits 0001 e as outras quatro pelas componentes do vetor B_val;
F_val um vetor de 9 posies. As quatro primeiras posies sero preenchidas pelas
componentes do vetor A_val, as quatro seguintes pelas componentes do vetor B_val,
e a ltima posio preenchida por um zero.

Operador de mdulo (mod) e de resto (rem): esses dois operadores possuem definies muito
especficas na linguagem. Suas definies e alguns exemplos so mostrados abaixo:

Operador
rem

mod

Nome

Definies

Resto (remainder) 1.
2.
3.
Mdulo

1.
2.
3.

Comentrios

(X rem Y) tem o mesmo sinal de X;


abs(X rem Y) < abs (X);
X = (X/Y)*X + (X rem Y).
(X mod Y) tem o mesmo sinal de Y; N um valor inteiro
abs (X mod Y) < abs (Y);
X = Y*N + (X mod Y)

rem

mod

8 rem 5 = 3 8 mod 5 = 3
-8 rem 5 = -8 mod 5 = 3
-3
8 mod -5 =
8 rem -5 = 3
-3
-8 rem -5 = -8 mod -5 =
-3
-3

Objetos de dados
Esta seo tem como objetivo explicar um pouco da teoria por trs da linguagem VHDL
apresentando os objetos da linguagem. Objeto um item da linguagem que possui um nome
(identificador associado) e um tipo especfico. Existem quatro tipos de objetos e diversos tipos de dados
em VHDL. Alguns sero discutidos nesta seo.

Tipos de objetos de dados


- Declarao de objetos de dados
Como mencionado anteriormente, existem quatro tipos de objetos de dados: sinais (signals),
variveis (variables), constantes (constants) e arquivos (files). Sero apresentadas algumas informaes
sobre os trs primeiros tipos de objetos, afim de melhorar o entendimento dos cdigos implementados em
laboratrio. Os objetos do tipo files no sero detalhados.
Todos os trs tipo de objetos que sero discutidos apresentam uma similaridade muito grande no
modo como so declaradas. Abaixo apresentamos a forma como so declaradas sendo que as palavras
reservadas do VHDL esto em negrito:
Objeto de dados

Declarao

signal

signal signal_name : signal_type := initial_value;

variable

variable variable_name : variable_type := initial_value;

constant

constant constant_name : constant_type := initial_value;

Em exemplos anteriores, essa forma de declarao j havia sido apresentada. possvel notar que
todos os objetos acima listados podem comear com um valor inicial, e no somente a constante. Abaixo,
alguns exemplos de declarao com alguns tipos que sero vistos mais adiante.
Objeto de dados

Declarao

signal

signal sig_var1 : std_logic := '0';


signal tmp_bus : std_logic_vector(3 downto 0) := 0011;

variable

variable my_var1,my_var2 : std_logic;


variable index_a : integer_range(0 to 255) := 0;

constant

constant sel_var : std_logic_vector(2 downto 0) := 001;


constant max_cnt : integer := 12;

- Variveis e o operador de atribuio


Variveis e sinais possuem caractersticas muito similares, mas variveis no so to funcionais
uma vez que s podem ser declaradas dentro de funes, processos e procedimentos. Um dos erros mais
comuns usar uma varivel fora de um processo.
O operador de atribuio de sinal <= usado para transferir o valor de um sinal para outro
quando se est trabalhando com objetos de dados do tipo signal. Quando se trata de variveis, o operador
de atribuio :=.

- Sinais x Variveis
Sinais e variveis podem ser um pouco confusos porque so muito parecidos. Sinais, de forma
geral, podem ser comparados com os fiosou algum outro tipo de conexo fsica no design de um
circuito. Sinais tambm podem ser usados para ligar mdulos dentro de uma interface VHDL, inclusive
com os valores de entrada e sada. Uma diferena importante entre sinais e variveis que um valor pode
ser previamente atribudo a um sinal; o que no ocorre com a varivel.
Variveis deveriam ser usadas principalmente como contadores em iteraes ou como valores
temporrios em um algoritmo que realize certos clculos. Em outras situaes elas deveriam ser evitadas
pois elas no possuem a mesma capacidade de ligar mdulos em uma interface, j que no possuem uma
memria.

Tipos de dados
- Tipos de dados mais comumente usados
Existem inmeros tipos de dados em VHDL. Na tabela abaixo encontram-se os mais comuns,
sendo que alguns j foram mencionados anteriormente ou j foram usados em alguns exemplos neste
tutorial. Os tipos integer e std_logic sero um pouco mais detalhados em seguida.
Tipo
std_logic

Exemplo
signal my_sig : std_logic;

std_logic_vector signal busA : std_logic_vector(3 downto 0);


Boolean

Variable my_test : boolean := false;

integer

signal iter_cnt : integer := 0;

- Tipos integer
O uso dos tipos integer geralmente em cdigos de descrio de circuitos digitais mais
complexos. A faixa de valores que esse tipo pode ter vai de [-2 31 a +231]. Outros tipos similares ao tipo
integer so os tipos natural e positive, sendo que estes apresentam uma faixa de valores diferente. Esses
valores podem ser variados pelo usurio, fazendo-se uso dos comandos type, range and to (ou downto).
Apesar de no serem muito teis nesse curso, alguns exemplos so mostrados abaixo:

Figura 39: Exemplos de variao de algumas variveis do tipo integer

- Tipos std_logic
O tipo bit um dos tipos mais comuns em VHDL, mas muito limitado. Ele pode conter apenas os
valores de '0' e '1'. Por isso, o tipo std_logic mais usado do que o tipo bit, devido sua versatilidade e
maior possibilidade de valores. O tipo std_logic definido como um tipo enumerado e dois dos possveis
valores so, obviamente, '0' ou '1'. A definio completa mostrada abaixo. Essa definio, porm, lista

std_ulogic, ao invs de std_logic. Isso se deve pois o tipo std_logic uma verso resolvida do tipo
std_ulogic. A definio de resoluo vai alm do esse tutorial prope.

Figura 40: Definio do tipo std_logic.

Os valores mais comuns, dos listados acima, so '0', '1', 'Z' e '-'. O valor de alta impedncia 'Z'
particularmente interessante. O 'Z' geralmente utilizado quando se lida com estruturas bus. Isso
permite que um sinal ou conjunto de sinais passe a ter a possibilidade de ser conduzido por mltiplas
fontes, sem a necessidade de gerar funes de resoluo. Quando um sinal "dirigido" ao seu estado de
alta impedncia, o sinal no dirigido a partir dessa fonte e efetivamente removido do circuito. E,
finalmente, uma vez que os caracteres utilizados no tipo std_ulogic fazem parte da definio, devem ser
usados como listados. Uso de letras minsculas ir gerar um erro.

Uso de VHDL para circuitos sequenciais


Esta seo ir mostrar como descrever alguns circuitos sequenciais usando a linguagem. Ser
dada uma ateno maior ao modelo comportamental da linguagem, aplicado a alguns flip-flops D. Ser
dada uma ateno maior aos conceitos bsicos desses flip-flops, o que ir ajudar na modelagem das
mquinas de estado.

Elementos simples de armazenamento usando VHDL


O flip-flop consiste de um dispositivo com uma lgica enable, um sinal com um certo clock. O
primeiro flip-flop com o qual iremos trabalhar o flip-flop tipo D mostrado abaixo:

Figura 41: Flip-flop D.

O cdigo que descreve o comportamento do flip-flop acima pode ser dado por:

Figura 42: Definio do flip-flop D.

Algumas observaes a respeito do cdigo acima:

Como ns usamos um modelo comportamental, a arquitetura composta principalmente de uma


instruo process. As instrues dentro de process so executadas sequencialmente. Sempre que

uma mudana detectada em qualquer um dos sinais na lista de sensitividade de process, essa
instruo executada. Neste caso, as instrues dentro de process so executadas cada vez que h
mudana no nvel lgico de D ou do Clock.
A contruo rising_edge() usada na instruo if para indicar que as mudanas na sada s
ocorrem na subida do Clock. rising_edge uma funo j definida em uma das bibliotecas j
includas na linguagem.
Para melhor entendimento, o processo foi nomeado: process dff.

A maior utilidade de um flip-flop a sua funo de memria. Pois, esse dispositivo mantm o
bit anterior na sada caso no haja alterao na entrada. Isso est implcito no cdigo quando no colocase nenhuma condio ao if. Ou seja, a sada Q s ser alterada caso a condio do if seja satisfeita.
O prximo exemplo um outro flip-flop, mas agora com um enable., ou seja, uma entrada que
liga/desliga o dispositivo:

Figura 43: Flip-flop com Set.

O cdigo que descreve o comportamento do flip-flop acima pode ser dado por:

Figura 44: Definio do flip-flop D com Set.

Algumas observaes a respeito do cdigo acima:

Pelo cdigo acima, podemos perceber que o dispositivo s funciona caso a entrada S seja '1'.
Caso contrrio, a sada ser sempre '0'.

O exemplo agora um outro flip-flop tipo D, mas com um boto de Reset (R). O esquema do
dispositivo pode ser visto abaixo:

Figura 45: Flip-flop D com Reset.

O cdigo que descreve o comportamento do flip-flop acima pode ser dado por:

Figura 46: Definio do flip-flop D com Reset.

Algumas observaes a respeito do cdigo acima:

Pelo cdigo acima, podemos perceber que o Reset, diferentemente do Set, no depende do Clock
e tem prioridade sobre ele. O flip-flop s ir funcionar se o R for '1'.

Design de mquinas de estado com VHDL


Mquinas de estado (ME's) so geralmente usadas como controladores em circuitos digitais. Para
projetar ME's em hardware, o primeiro passo (e facilitador do processo) aprender a modela-las usando
VHDL. Essa modelagem uma continuidade das tcnicas usadas na seo anterior, sobre circuitos
sequenciais.
O diagrama de blocos da figura 47 traz um modelo padro de uma mquina de estado de Moore.
O bloco Next State Decoder um bloco de lgica combinatria que usa as entradas externas atuais e o
estado atual da ME para decidir o prximo estado da mquina. Em outras palavras, as entradas desse
bloco so decodificadas e produzem uma sada correspondente ao prximo estado da ME. O prximo
estado se torna o estado atual quando o clock na entrada do bloco State Registers torna-se ativo. O bloco
State Registers contm elementos de armazenamento que armazenam o estado atual da mquina. As
entradas do bloco Output Decoder so usadas para gerar as sadas externas desejadas. Esse bloco
constituido de circuitos combinatrios, que iro gerar as sadas desejadas. Como as sadas externas
dependem apenas do estado atual da mquina, ela classificada como mquina de Moore.

Figura 47: Diagrama de blocos de uma mquina de estado de Moore.

A versatilidade da linguagem ir nos permitir descrever mquinas de estado de forma mais


simples do que quando o mesmo feito em papel. H muitas formas de descrever uma mquina de estado
em VHDL. A abordagem utilizada nesta apostila parcialmente descrita pelo diagrama de blocos da
figura 48.

Figura 48: Modelo para implementao em VHDL das mquinas de estado.

A abordagem que usaremos divide a mquina de estado em dois processos em VHDL. O primeiro
processo, o processo sncrono (synchronous process), engloba tudo que se refere a clock e outros
controles associados a elementos de armazenamento. O outro processo, o processo combinatrio
(combinatorial process), engloba todos os elementos dos blocos Next State Decoder e Output Decoder,
mostrados no diagrama da figura 40. Ou seja, esse ltimo processo contm todos os circuitos
combinatrios da mquina.
As entradas denominadas parallel inputs so entradas que agem em paralelo aos elementos
armazenadores. Essas entradas incluem enables, resets, sets, clear, etc.. As entradas denominadas state
transition inputs incluem entradas externas que controlam as transies de estado.
EXEMPLO 13: Escrever o cdigo VHDL que descreve a mquina de estado abaixo.

Figura 49: Mquina de estado usada no exemplo.

Soluo: Este problema representa uma implementao bsica de uma mquina de estado. Na figura 50
abaixo, mostramos a caixa preta que representaria a mquina de estado do exemplo. Na figura 51,
temos o cdigo que a implementa.

Figura 50: Caixa preta da mquina de estado usada no exemplo.

Figura 51: Soluo do exemplo.

Alguns pontos notveis na soluo acima:

Na soluo acima, declaramos um tipo VHDL especial para representar os estados da ME. Esse
um
exemplo de como a linguagem manipula tipos de enumerao. Existe uma representao
numrica
interna para os tipos de estado listados mas s lidamos com o equivalente textual
mais expressivo.
O processo sncrono igual em forma e funo ao flip-flop D projetado na seo anterior. A nica
diferena que PS e NS substituram D e Q, respectivamente.
Os dois processos mencionados anteriormente esto no cdigo. O processo sncrono lida com o
reset assncrono e com a atribuio de um novo estado com a chegada do clock do sistema. O
processo
combinatrio lida com as sadas no tratadas no processo sncrono, com as sadas
e com a gerao
do prximo estado da MS.
Como ambos os processos operam concorrentemente, mudanas no sinal NS que so geradas no
processo combinatrio fora uma avaliao do processo sncrono. Quando as mudanas so

institudas no processo sncrono na subida do clock, as mudanas no sinal PS causa uma


avaliao do processo combinatrio.
A instruo case no processo combinatrio prev uma clusula when para cada estado da mquina
de
estados. Uma clusula when others tambm foi usada e engloba todos os outros casos que
no foram
usados anteriormente.
A sada da mquina Moore funo apenas do estado atual. Isso pode ser visto no cdigo pelo
fato
de a sada Z1 ser incondicionalmente avaliada em cada clusula when da instruo case
no processo
combinatrio.

Nesse exemplo foi desconsiderado o fato de que comum nas mquinas de estado que a sada
tambm seja uma varivel de estado. A seguir, temos o mesmo exemplo considerando que as sadas
tambm so variveis de estado.

Figura 52: Caixa preta da mquina de estado usada na


segunda parte do exemplo.

Figura 53: Soluo do exemplo considerando a sada como uma varivel de estado.

Podemos notar duas modificaes no cdigo da figura 53 com relao ao cdigo da figura 51. A
primeira na declarao da entidade para incluir a varivel de sada Y. A segunda alterao consiste na
insero de uma instruo de atribuio seletiva que atribui um valor varivel de estado de sada Y
baseado no valor da varivel de estado. Essa instruo avaliada sempre que uma mudana no sinal PS
detectada. Lembre-se que h trs intrues concorrentes no cdigo: duas instrues de processo e uma
instruo de atribuio seletiva. Nos exemplos a seguir, as variveis de estados sero consideradas como
sadas das mquinas de estado.

EXEMPLO 14: Escreva o cdigo VHDL que implementa a mquina de estados abaixo. Considere as

variveis de estado como sadas.

Figura 54: Mquina de estado usada no exemplo.

Soluo: O diagrama de estados mostrado na figura 54 indica que estamos lidando com uma mquina de
trs estados. Como h trs estados, a soluo requer pelo menos duas variveis de estado para lidar com
os trs estados da mquina. A caixa-preta do projeto mostrada na figura abaixo.

Figura 55: Caixa preta da mquina de estado do exemplo.

Figura 56: Soluo do exemplo.

Alguns pontos a serem observados:

A mquina de estados possui uma sada do tipo Mealy. A soluo essencialmente trata esta sada
como uma sada do tipo Moore nas duas primeiras clusulas when das sentenas case. No ltimo
when, a sada Z2 aparece nas duas sees da sentena if.
Duas variveis de estado foram necessrias uma vez que o diagrama de estados continha mais de
dois estados.

EXEMPLO 15: Escrever o cdigo VHDL que implementa a mquina de estado abaixo. Considere as

variveis de estado como sadas.

Figura 57: Mquina de estado usada no exemplo.

Soluo: O diagrama de estados indica que a soluo vai conter quatro estados, uma entrada e duas
sadas. A caixa-preta para a soluo mostrada na figura 58 abaixo:

Figura 58: Caixa preta da mquina de estado do exemplo.

Figura 59: Soluo do exemplo.

Os exemplos mostrados nessa seo devem ser suficientes para implementar uma base aos
estudos e implementao de mquinas de estados finitas.

Apndice A Exemplos de aula


Este apndice vem trazer mais alguns exemplos de implementao de circuitos em VHDL. A
proposta, porm, mostrar a implementao de alguns dos circuitos que j foram trabalhado em
laboratrio aos quais o aluno j obteve algum contato.

Circuitos do experimento 2

Os circuitos do experimento dois sero implementados usando a linguagem VHDL. As formas de


implementao so vrias, e aqui no iremos nos ater nos vrios mtodos, mas sim no resultado final
obtido.
i. Circuito da seo 3.1 representado pela tabela verdade abaixo:

Figura 60: Tabela verdade e modelo de circuito que implementa a funo.

Acima esto a tabela fornecida pelo roteiro do experimento e uma das formas de se implementar a
funo. Usando o mapa de Karnaugh, encontra-se que S 1=AB + B.C. A partir dessa expresso e aplicando
o Teorema de DeMorgan, possvel chegar no circuito acima.
Uma das formas de se implementar a funo acima em VHDL partir da funo encontrada. Esse
mtodo ser utilizado para todos os circuitos desse experimento. Neste primeiro, porm, sero mostradas
duas formas de se implementar essa mesma funo. O primeiro mtodo, baseado unicamente na equao
mostrado a seguir:
-- Implementao circuito 3.1 do Experimento 2 -entity circuito_1 is
port( A,B,C: in BIT;
S1: out BIT);
end circuito_1;
architecture circuito_1_op of circuito_1 is
begin
S1 <= (not(A) and B) or (not(B) and not(C));
end circuito_1_op;

A implementao acima consiste basicamente na reproduo da equao de sada do circuito.


Para test-la necessrio fazer um outro cdigo especificamente para o teste. O cdigo utilizado pra testar
o que foi feito acima segue abaixo:
-- Simulao da implementao do circuito 3.1 -entity sim_circuito_1 is
end sim_circuito_1;
architecture sim_circuito_1_op of sim_circuito_1 is
component circuito_1 is
port(A,B,C: in BIT;
S1: out BIT);
end component;
signal A_sim,B_sim,C_sim,S1_sim: BIT;
begin
U1: circuito_1 port map(A_sim, B_sim,C_sim,S1_sim);
process
begin
A_sim <=
B_sim <=
C_sim <=
wait for

'0';
'0';
'0';
20 ns;

A_sim <=
B_sim <=
C_sim <=
wait for

'0';
'0';
'1';
20 ns;

A_sim <=
B_sim <=
C_sim <=
wait for

'1';
'1';
'1';
20 ns;

A_sim <=
B_sim <=
C_sim <=
wait for

'1';
'0';
'0';
20 ns;

end process;
end sim_circuito_1_op;

Pelo cdigo acima, percebemos que o circuito ser testado para quatro valores de entrada: (0,0,0),
(0,0,1), (1,1,1) e (1,0,0). O resultado da simulao mostrado a seguir e comprova a veracidade do
cdigo acima se comparado com os valores da tabela:

Figura 61: Resultado da simulao do cdigo usado para implementar o circuito 1.

A outra forma de se implementar tal circuito usando sinais. Esses sinais esto mostrados no
esquemtico do circuito e foram chamados de X1, X2, X3, X4 e X5. Porm, para poder fazer uso de tal
recurso necessrio declarar um componente que corresponda s portas NAND utilizadas para modelar o
circuito. Tal componente pode ser declarado da seguinte forma:

entity porta_nand is
port( A,B: in BIT;
S: out BIT);
end porta_nand;
architecture porta_nand_op of porta_nand is
begin
S <= A nand B;
end porta_nand_op;

Esse componente ser utilizado na arquitetura que implementa o circuito, como mostrado abaixo:
entity circuito_1_2 is
port( A,B,C: in BIT;
S1: out BIT);
end circuito_1.2;
architecture circuito_1_2_op of circuito_1_2 is
component porta_nand is
port(A,B: in BIT;
S: out BIT);
end component;
signal X1, X2, X3, X4, X5: BIT;
begin
U1:
U2:
U3:
U4:
U5:
U6:

porta_nand
porta_nand
porta_nand
porta_nand
porta_nand
porta_nand

port
port
port
port
port
port

map(A, A, X1);
map(B, B, X2);
map(C, C, X3);
map(X1, B, X4);
map(X2, X3, X5);
map(X4, X5, S1);

end circuito_1_2_op;

O resultado o mesmo da simulao anterior. Mas utilizando os sinais, mais fcil a


manipulao do circuito e da sua implementao.
ii. Circuito da seo 3.2 representado pela tabela verdade abaixo:
A partir da tabela abaixo e usando o mapa de Karnaugh, possvel encontrarmos a sada do
circuito como: S2 = A.C + B.C + A.C.D. Essa sada pode ser facilmente implementada, como segue:

Figura 62: Tabela verdade da seo 3.2.

-- Implementao circuito 3.2 do Experimento 2 -entity circuito_2 is


port( A,B,C,D: in BIT;
S2: out BIT);
end circuito_2;
architecture circuito_2_op of circuito_2 is
begin
S2 <= (not(A) and not(C)) or (not(B) and C) or (A and C and not(D));
end circuito_2_op;

O test bench tambm foi realizado a partir do cdigo abaixo:


-- Simulao da implementao do circuito 3.2 -entity sim_circuito_2 is
end sim_circuito_2;
architecture sim_circuito_2_op of sim_circuito_2 is
component circuito_2 is
port(A,B,C,D: in BIT;
S2: out BIT);
end component;
signal A_sim,B_sim,C_sim,D_sim,S2_sim: BIT;
begin
U1: circuito_2 port map(A_sim, B_sim,C_sim,D_sim,S2_sim);
process

begin
A_sim <=
B_sim <=
C_sim <=
D_sim <=
wait for

'0';
'0';
'0';
'0';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
wait for

'0';
'0';
'1';
'1';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
wait for

'0';
'1';
'1';
'0';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
wait for

'1';
'0';
'1';
'0';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
wait for

'1';
'1';
'1';
'1';
20 ns;

end process;
end sim_circuito_2_op;

O resultado da simulao encontra-se abaixo:

Figura 63: Resultado da simulao do cdigo usado para implementar a funo obtida a partir da tabela da
figura 49.

iii. Circuito da seo 3.3 representado pela tabela verdade abaixo:


O mesmo procedimento anterior foi realizado:

Figura 64: Tabela verdade da seo 3.3.

-- Implementao circuito 3.3 do Experimento 2 -entity circuito_3 is


port( A,B,C,D,E: in BIT;
S3: out BIT);
end circuito_3;
architecture circuito_3_op of circuito_3 is
begin
S3 <= not(D) or (not(B) and not(E)) or (A and B and not(C) and E);
end circuito_3_op;

-- Simulao da implementao do circuito 3.3 -entity sim_circuito_3 is


end sim_circuito_3;
architecture sim_circuito_3_op of sim_circuito_3 is
component circuito_3 is
port(A,B,C,D,E: in BIT;
S3: out BIT);
end component;
signal A_sim,B_sim,C_sim,D_sim,E_sim,S3_sim: BIT;
begin
U1: circuito_3 port map(A_sim, B_sim,C_sim,D_sim,E_sim,S3_sim);
process
begin
A_sim <=
B_sim <=
C_sim <=
D_sim <=
E_sim <=
wait for

'0';
'0';
'0';
'0';
'0';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
E_sim <=
wait for

'0';
'0';
'0';
'1';
'1';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
E_sim <=
wait for

'0';
'1';
'0';
'1';
'1';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
E_sim <=
wait for

'1';
'0';
'0';
'1';
'0';
20 ns;

A_sim <=
B_sim <=
C_sim <=
D_sim <=
E_sim <=
wait for

'1';
'1';
'1';
'0';
'0';
20 ns;

end process;
end sim_circuito_3_op;

O resultado final, que bate com os valores da tabela, segue abaixo:

Figura 65: Resultado da simulao do cdigo anterior.

Apndice B Circuitos digitais padres


em VHDL
Este apndice traz alguns exemplos de circuitos modelados na linguagem VHDL e que podem ser
teis aos alunos nas aulas.

Flip-flop D

Figura 66: Definio de um flip-flop D.

Registrador 8-bit com Chip Select

Figura 67: Definio de um registrador 8-bit.

Comparador 8-bit

Figura 68: Definio de um comparador.

Decodificador BCD de 7 segmentos

Figura 69: Definio de um decodificador BCD.

Multiplexador 4:1

Figura 70: Definio de um multiplexador 4:1.

Decodificador 3:8

Figura 71: Definio de um decodificador 3:8.

Apndice C Palavras reservadas ao


VHDL
Abaixo, um grupo de palavras reservadas pela linguagem: