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.
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;
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.
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
clk
start_val_
in
@#$%%$
this_sucks
Big_vAlUe
pa
sim-val
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.
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
:
:
:
mode
mode
mode
data_type;
data_type;
data_type
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.
A figura 8 apresenta outra entidade em VHDL. Tudo que se foi dito sobre a figura 7 vlido
tambm para esta figura.
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.
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.
A AND B;
C AND D;
E AND F;
OR H OR I;
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;
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.
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;
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.
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.
------------------------------------------------------------------------------------- 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;
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;
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.
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;
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.
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.
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;
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;
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:
0001
0101
1000
1011
1110
|
|
|
|
|
0010 | 0011,
0110 | 0111
1001,
1100 | 1101
1111,
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.
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;
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
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.
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;
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:
EXAMPLO 8
Escreva um cdigo em VHDL que implemente a seguinte funo lgica usando uma declarao IF
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;
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;
Escreva um cdigo VHDL que implemente o MUX 8:1 mostrado abaixo. Utilize uma declarao if.
Data_in(7);
<= Data_in(6);
<= Data_in(5);
<= Data_in(4);
then
then
then
then
F_CTRL
F_CTRL
F_CTRL
F_CTRL
<=
<=
<=
<=
Data_in(3);
Data_in(2);
Data_in(1);
Data_in(0);
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;
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;
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:
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.
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
/=
<
Menor que
<=
Menor ou igual a
>
Maior
>=
Maior ou igual a
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, :
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:
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
Subtrao
Identidade
Negao
Multiplicao
Diviso
mod
Mdulo
rem
Resto
**
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;
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
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.
Declarao
signal
variable
constant
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
variable
constant
- 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;
integer
- 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:
- 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.
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.
O cdigo que descreve o comportamento do flip-flop acima pode ser dado por:
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:
O cdigo que descreve o comportamento do flip-flop acima pode ser dado por:
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:
O cdigo que descreve o comportamento do flip-flop acima pode ser dado por:
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'.
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.
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.
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
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 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
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.
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
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:
Os exemplos mostrados nessa seo devem ser suficientes para implementar uma base aos
estudos e implementao de mquinas de estados finitas.
Circuitos do experimento 2
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;
'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:
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;
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;
Figura 63: Resultado da simulao do cdigo usado para implementar a funo obtida a partir da tabela da
figura 49.
'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;
Flip-flop D
Comparador 8-bit
Multiplexador 4:1
Decodificador 3:8