Linguagem VHDL
Linguagem VHDL
Linguagem VHDL
1 Visão Geral
VHDL (VHSIC1 Hardware Description Language) é uma linguagem de descrição de hardware desenvolvida
pelo departamento de defesa estadunidense para documentar o comportamento de circuitos integrados que
eram vendidos a este departamento. O objetivo era permitir que o funcionamento de um componente fosse
descrito com melhor clareza e que não restringisse a portabilidade.
Com o desenvolvimento de ferramentas que utilizavam a VHDL como linguagem para o a descrição textual
de circuitos para a documentação, descrição, simulação, teste e sı́ntese, esta linguagem tornou-se popular
neste segmento, levando a sua padronização pelo IEEE em 1987. A partir desta época foram feitas algumas
revisões, sendo a versão mais recente de 2008.
Uma descrição em VHDL pode ser usada para simular o comportamento de um circuito eletrônico ou ainda
para ser implementado em uma tecnologia, como em FPGA ou ASIC. O processo de compilar a descrição
em VHDL para a tecnologia apropriada é chamado de sı́ntese. Diferente do processo de simulação, nem
todas as construções em VHDL podem ser sintetizadas em todas as tecnologias, existindo um subconjunto
de construções sintetizáveis que devem ser usadas como uma boa prática de programação para interessados
na implementação da descrição.
∗ Este mini-curso é uma ação vinculada ao convênio INPE/UFSM e tem por objetivo oferecer uma introdução a Computação
Hı́brida Reconfigurável
1 Very High Speed Integrated Circuits
1.1 Estrutura
Em um arquivo VHDL podemos identificar uma estrutura básica que é parecida com o código de uma
linguagem de programação de software. Na Listagem 1 temos um exemplo de uma estrutura básica, onde:
Nesta descrição, podemos identificar três regiões, que caracterizam um arquivo VHDL básico:
2
1.2 Exemplo Simples: somador de 1 bit
Para facilitar a compreensão da configuração de um sistema em VHDL usaremos um exemplo simples par-
tindo de seu circuito lógico. Usaremos para este propósito um somador de 1 bit com carry.
Um método para organizar o desenvolvimento em VHDL é elaborar um desenho com o componente a ser
implementado, a fim de estabelecer os sinais que farão parte da interface deste componente. Na Figura 1a
temos a representação do nosso somador de 1 bit, onde indicamos somente as entradas e as saı́das. Neste
momento já é possı́vel criar a entity no nosso arquivo VHDL. Na Listagem 2 vemos a declaração desta
entidade, onde temos os sinais a, b e cin como sinais de entrada e s e cout como saı́da.
O próximo passo é implementar a architecture da nossa descrição. Para isso é necessário estabelecermos o
comportamento do nosso componente. Como já dito anteriormente, usaremos um circuito lógico do somador
de 1 bit. Na Figura 1b representamos a interação entre os sinais de entrada para a obtenção dos sinais de
saı́da. Neste momento podemos descrever o comportamento do nosso sistema dentro da nossa arquitetura,
que no nosso exemplo é chamada de simples.
Na architecture da Listagem 2 podemos ver como pode ser descrito o comportamento do nosso circuito.
Na linha 14 podemos ver a declaração de um novo sinal que conterá o resultado da operação lógica xor entre
as entradas a e b. O uso deste sinal não é essencial nesta descrição, mas facilita a legibilidade do código.
Entre as linhas 16 e 18 é descrito as demais operações de nossa descrição.
3
s a x o r b <= a xor b ; 16
s <= ( s a x o r b xor c i n ) ; 17
cout <= ( ( a and b ) or ( s a x o r b and c i n ) ) ; 18
end architecture s i m p l e s ; 19
2 Elementos da Linguagem
2.1 Tipos
A Linguagem VHDL disponibiliza tipos básicos e meios de criar tipos compostos. Tipos básicos são tipos que
não tem elemento ou estrutura interna, incluem números inteiros, reais, quantidades fı́sicas e enumerações.
Sendo que todos seus valores devem ser possı́veis de ser ordenados e estão numa faixa de valores pré-definida.
Alguns tipos básicos podem ser vistos na Tabela 1.
O tipo real pode ser usado em simulações, mas não pode ser sintetizado diretamente. Para projetos que
necessitam deste tipo de representação são usadas bibliotecas que dão suporte a operações desta natureza.
Mais informações sobre este caso será visto no item 2.1.2.
A declaração de um sinal utilizando um tipo pode ser vista na Listagem 3, tendo sua formulação genérica
na primeira linha e um exemplo na linha seguinte.
Listagem 3: Declaração de um sinal
−− s i g n a l <nome do s i n a l > : <t i p o >; 1
s i g n a l m e u s i n a l : integer ; 2
Tipos compostos possuem uma estrutura interna, como é o caso de vetores. Vetores podem ser utilizados
através de formatos pré-definidos como o caso de bit vector e string, onde após o nome do tipo deve ser
informada a quantidade de elementos do vetor. Na Listagem 4 temos a declaração de um sinal usando
bit vector. Entre as linhas 8 e 15, temos algumas opções para atribuir um valor ao sinal barramento. Quando
é atribuı́do um conjunto (mais que 1) de valores, utiliza-se aspas duplas(”) e para valores com um caractere,
aspas simples (’). Os dados podem ser informados em formato binário (linha 8), octal (linha 9), hexadecimal
(linha 10) ou ainda acessando cada elemento do vetor (linhas 12 até 15).
Um segundo modo de estruturar vetores é através da definição de um novo tipo. Na quarta linha da
Listagem 4 é mostrado um exemplo da criação de um vetor de bits. A atribuição de valores ao sinal
barramento2 pode ser feita da mesma forma que foi realizada para barramento.
4
Listagem 4: Uso de Vetores
−− Usando v e t o r pre−d e f i n i d o 1
s i g n a l barramento : bit vector ( 1 1 downto 0 ) ; 2
−− D e f i n i n d o um novo t i p o 3
type meu vetor i s array ( 1 1 downto 0 ) of b i t ; 4
s i g n a l barramento2 : meu vetor ; 5
6
−− A t r i b u i c a o de v a l o r e s 7
barramento <= ” 101010111100 ” ; −− b i n a r i o 8
barramento <= o ” 5274 ” ; −− o c t a l 9
barramento <= x”ABC” ; −− h e x a d e c i m a l 10
11
barramento ( 1 1 ) <= ’ 1 ’ ; 12
barramento ( 1 0 ) <= ’ 0 ’ ; 13
... 14
barramento ( 0 ) <= ’ 0 ’ ; 15
Além dos tipos nativos suportados pela linguagem, existem ainda bibliotecas que definem novos tipos e
suas operações, como a std logic 1164 que define a representação de valores lógicos padronizados pela IEEE
1164. Esta representação define 9 estados possı́veis de um sinal. Esta definição vai em desencontro com a
idéia de dois estados lógicos de um sinal (’0’ e ’1’), entretanto representa os estados fı́sicos reais de um sinal
em uma tecnologia CMOS. Os estados definidos são:
Para a declaração de um sinal usando este padrão pode ser utilizado o std logic e o std logic vector
para vetores. A biblioteca std logic 1164 possui ainda fuções para para o tipo std logic, as principais são
falling edge e rising edge, que são usadas para detectar a transição de descida ou subida dos sinais espe-
cificados. O uso de rising edge(clk) é equivalente aos comandos clk’event and clk=’1’. Na Listagem 5 são
mostradas essas duas formas de uso. A condição do comando if somente será satisfeita quando houver a
mudança do clk para o estado ’1’, indicando uma borda de subida no clk.
5
a <= b ; 2
end i f ; 3
4
−− e q u i v a l e n t e 5
i f ( c l k ’ e v e n t and c l k = ’ 1 ’ ) then 6
a <= b ; 7
end i f ; 8
2.1.1 Enumeráveis
O uso de tipos enumeráveis é muito utilizado na descrição de uma máquina de estados. Nesta situação, são
criados estados através de palavras que os identificarão. Esta comando é semelhante ao uso do comando
enum em linguagem C. Sua definição, a declaração e uso são mostrados na Listagem 6. Durante o processo
de sı́ntese as palavras esperar, verificar, processar e terminar serão transformadas em valores inteiros
com quantos bits forem necessários para identificá-las, por isso, não devem existir estados com mesmo nome
em tipos diferentes de enumeráveis.
Listagem 6: Enumeráveis
type e s t a d o s i s ( e s p e r a r , v e r i f i c a r , p r o c e s s a r , t e r m i n a r ) ; 1
signal s e s t a d o : estados ; 2
3
s e s t a d o <= e s p e r a r ; 4
5
i f ( s e s t a d o = p r o c e s s a r ) then 6
s e s t a d o <= t e r m i n a r ; 7
end i f ; 8
Números em ponto flutuante podem ser representados com o tipo real. Entretanto este formato não é
sintetizável, sendo usado somente no caso de simulação de componentes. Se for necessário o uso deste tipo e
de suas operações devem seu usadas bibliotecas que implementam componentes que realizam a manipulação
deste formato. Existem algumas bibliotecas de código aberto que podem ser utilizadas, ou ainda podem ser
utilizados módulos disponı́veis nas ferramentas de desenvolvimento, como no Ise Foundation da Xilinx. Esta
ferramenta possui implementações deste tipo de operação otimizadas para os dispositivos que comercializa.
Como as operações não são nativas da linguagem, é necessária a utilização de componentes, a modularização
com componentes é vista no item 2.9 deste material.
O sinais usados em VHDL podem ser combinados através de operadores lógicos. Os operadores and, nand,
or, nor, xor, xnor exigem dois operando e o operador not apenas um. Essas operações podem ser utilizadas
com os tipos bit, boolean, bit vector, std logic, std logic vector, etc, desde que os operandos sejam do mesmo
tipo. No caso de vetores estas operações são efetuadas bit a bit.
6
2.3 Operadores Numéricos
Em VHDL estão disponı́veis os operadores de adição (+), subtração (-), multiplicação (*), divisão (/),
módulo (mod), valor absoluto (abs), resto (rem) e potência (**) para os tipos integer e real. Para estes
operadores numéricos, os operandos devem ser do mesmo tipo. Vale lembrar que nem todas as construções
em VHDL são sintetizáveis e, portanto, servirão somente para documentação ou simulação.
A comparação entre dois objetos pode ser feita usando os operadores: igual (=), diferente (/=), menor (¡),
menor ou igual (¡=), maior (¿) ou maior ou igual (¿=). Os elementos devem ser do mesmo tipo e em caso
de vetores com dimensões diferentes, o maior será justificado para o tamanho do menor para a comparação.
Itens de vetores podem ser indexados individualmente através indicação do ı́ndice dentro de parenteses ()
adjacentes ao nome do sinal. Um subvetor pode ser indexado através do uso de to e downto. Com isso é
possı́vel inverter a ordem dos bits de um barramento (vetor). Na Listagem 7 pode ser visto alguns exemplos
de indexação de vetores, sendo que na linha 8 o sinal s barramento1 recebe os dados de s barramento0 em
ordem inversa. Na última linha é possı́vel ver o uso do operador de concatenação & para atribuir valores a
um vetor.
2.6 Entidade
A entity funciona como a interface do componente a ser implementado. Deve definir os sinais de saı́da e
entrada e seus tipos. Analogamente, seria o protótipo de uma função de uma linguagem de programação,
onde são definidos os argumentos e o retorno.
Além dos sinais de entrada e saı́da, uma entidade pode ter ainda opcionalmente o comando generic,
que serve para descrever o valor de constantes. Estas constantes podem ser usadas para a confecção de
componentes que possam ser modificados através da alteração destas constantes. Uma entidade que utiliza
uma constante N para determinar o tamanho dos vetores de entrada pode ser vista na Listagem 8.
7
Listagem 8: Entidade
entity somador i s 1
generic (N: p o s i t i v e := 8 ) ; 2
port ( 3
a : in s t d l o g i c v e c t o r (N−1 down 0 ) ; 4
b : in s t d l o g i c v e c t o r (N−1 down 0 ) ; 5
c i n : in s t d l o g i c ; 6
s : out s t d l o g i c v e c t o r (N−1 down 0 ) ; 7
c o u t : out s t d l o g i c ) ; 8
end entity somador ; 9
2.7 Arquitetura
A architecture é a implementação de uma entity, onde é definido o comportamento e iteração dos sinais. É a
implementação da função, quando comparada a um programa. Múltiplas architectures podem ser definidas
para uma mesma entidade, bastando que tenham nomes diferentes.
Um exemplo de architecture pode ser visto na Listagem 2, onde é apresentada uma arquitetura que possui
3 linhas, cada uma com uma operação de atribuição. Uma caracterı́stica importante a ser observada nesta
arquitetura, é que a ’execução’ destas linhas não acontece sequencialmente na ordem em que aparecem no
código, sendo processados em paralelo, visto que representam conexões entre sinais e não instruções a serem
executadas em um processador. Este é exatamente o comportamento esperando com o circuito da Figura 1b.
As operações serão computadas de forma imediata à alterção de um dos sinais, levando somente o tempo de
propagação do sinal pelo condutor. Para testar o funcinamento, troque a ordem das linhas 16, 17 ou 18 e
veja o comportamento em um simulador.
2.8 Processos
O comportamento do sistema descrito em uma architecture acontece em paralelo, sem que haja um fluxo
sequencial de execução. Entretanto, em algumas situações é necessário uma ordenação e a utilização de
fluxos de controle. Para estes casos são utilizados process. Processos são declarados dentro de architecture
e a operação de cada linha é executada sequencialmente. Na Listagem 9 temos o exemplo de uma entidade
implementado usando processo, que está entre as linhas 16 e 25. A declaração deve ser feita iniciando pela
nome do processo, seguido por dois pontos (:) e pela palavra reservada process. Dentro dos parenteses vão
os sinais que ativam a execução do process, ou seja, o processo do nosso exemplo somente será executado
quando houver alguma alteração no estado de clk. Na ausência de sinais de ativação, o processo será executado
novamente a cada ciclo do FPGA. Os sinais que sofrem alterações dentro de um processo, somente terão
seus valores alterados efetivamente na finalização do processo.
Ainda na Listagem 9 podemos ver um segundo processo, chamado segundo processo. Considerando que
que todos os sinais, de s a até s c, estejam com o valor 1 e ocorra uma borda de subida no clk, após a
execução deste processo os sinais terminam com os valores: s a = 2, s b = 2, s c = 1. A atribuição de 5
ao s a é descartada pois somente a ultima atribuição é efetivada. O s b não recebe o valor 6, como poderia
ser a intenção, pois s a somente teria o valor 5 ao final do processo. Em situações onde é necessário que a
atribuição ocorra sem atraso, é possı́vel o uso de variables, pois o valor atribuı́do a uma variable é válido
8
imediatamente após a atribuição. No terceiro processo do nosso exemplo, é feita a implementação usando
variables, e considerando o mesmo estado inicial anterior, no final deste processo teremos: s a2 = 3, s b2 =
6 e s c2 = 3. Observe que foram utilizados outros sinais dentro deste processo, pois os sinais estão no escopo
da arquitetura e são compartilhados pelos processos. Uma variável somente pode ter atribuição dentro de
um processo, e leituras em quantos necessário. Na Tabela 2 é feita uma entre sinais e variáveis.
Uma última observação a ser feita no código da Listagem 9 é quanto à execução dos processos. Como
todos eles são sensı́veis ao sinal clk, quando este sinal sofrer uma variação, os três processos entrarão em
operação concorrentemente, como se fossem processos independentes.
9
begin 29
s a <= 5 ; 30
s b <= s b + s a ; 31
s a <= s a + 1 ; 32
s c <= s a ; 33
end i f ; 34
end process s e g u n d o p r o c e s s o ; 35
36
t e r c e i r o p r o c e s s o : process ( c l k ) 37
variable v a , v b , v c : integer ; 38
begin 39
v a := 5 ; 40
v b := s b 2 + v a ; 41
v a := s a 2 + 1 ; 42
v c := v a ; 43
s a 2 <= v a ; 44
s b 2 <= v b ; 45
s c 2 <= v c ; 46
end process t e r c e i r o p r o c e s s o ; 47
48
end architecture a r c h 1 ; 49
Como já pode ser observado em exemplos anteriores, dentro de processos podem ser utilizados alguns con-
troles de fluxo. Este controles, assim como em softwares, servem para selecionar as operações que deverão
ser executadas.
2.8.2 If
Este controle serve para restringir a execução de algumas operações em certas condições. Na Listagem 10 é
exibido um exemplo de uso de if usando todas as suas opções. Assim como em linguagens de programação,
o if também pode ser usado sem o elsif e/ou else.
Listagem 10: If
if ( s a = ’ 1 ’ ) then 1
s a <= ’0 ’; 2
elsif ( s a = ’ 0 ’ ) then 3
s a <= ’1 ’; 4
else 5
s b <= ’1 ’; 6
end i f ; 7
10
2.8.3 Case
O comando case é utilizado para selecionar operações assim como o if, entretanto, para muitas condições
pode torna-se complicado a utilização deste último. Um está constantemente associado à implementação de
máquinas de estado, onde a condição de avaliação é o estado atual da máquina. A Listagem 11 mostra o
exemplo de um multiplexador de 4 entradas utilizando um selecionador de dois bits do tipo std logic. Na
última linha do case observamos a existência do when others, para situações não previstas pelas demais. Vale
lembrar que std logic possui 9 estados por bit, resultando mais que 4 estados possı́veis quando considerados
dois bits.
2.8.4 For
O comando for repete uma sequência de operações por um número especı́fico de vezes. Para isso, utiliza
um contador que é incrementado ou decrementado a cada iteração. O contador não precisa ser declarado,
sendo considerado uma constante existente somente dentro do laço. No uso desta estrutura é interessante
observar que existem algumas construções do laço for que não podem ser sintetizados. Na configuração de
um hardware não existem estruturas definidas para ser possı́vel executar novamente um comando até que
seja atingida uma condição. Esta propriedade é facilmente observável em processadores, mas não ocorrem
naturalmente em FPGAs, por exemplo. Sendo assim, um for em uma descrição VHDL é ’desenrolado’ em
tempo de sı́ntese, gerando uma sequência de N vezes a lista de operações que estão internas ao laço. Em casos
em que não é possı́vel definir a quantidade de vezes que será executado o laço, não será possı́vel desenrolá-lo,
e , portanto, a sı́ntese do componente. Na Listagem 12 temos o exemplo de um laço for.
11
2.9 Componentes
Um componente é uma descrição VHDL de um módulo contendo entity e sua respectiva architecture,
que pode ser invocado dentro da architecture de um outro componente. Na Listagem 13 é possı́vel ver a
declaração de um componente nas linhas 11 até 15, onde é declarada, através do comando component, a entity
do componente desejado. A instanciação do componente acontece entre as linhas 21 e 24. Primeiramente
é dado um nome para a instância, seguida de pois pontos e o nome do componente a ser instanciado. Na
sequência, é feito a conexão dos sinais locais com os sinais do componente através da declaração do port
map. Independente do sentido dos sinais (in, out, inout), a conexão sempre deve ser feita com ¡sinal do
componente¿ =¿ ¡sinal local¿. Um exemplo com o uso de componentes pode ser visto na seção 3.1.
12
3 Exemplo aprimorado: somador de 4 bits
A fim de mostrar o uso de mais recursos da VHDL é apresentado um exemplo mais aprimorado. Neste exem-
plo é apresentada a implementação de duas arquiteturas diferentes um somador de 4 bits com carry. A pri-
meira utiliza uma organização estrutural e reutiliza o componente já implementado no primeiro exemplo (Lis-
tagem 2). A segunda descreve o comportamento do somador utilizando operações do pacote std logic unsigned
da biblioteca ieee. A Listagem 14 apresenta esta implementação.
O mesmo comportamento encontrado com a implementação da architecture estrutural pode ser obtido com
a architecture comportamental. A diferença entre eles está na forma de implementação das operações. Na
comportamental é utilizado a biblioteca std logic unsigned, a qual abstrai a realização de algumas operações
entre sinais. Esta abordagem apesar de resultar em uma menor quantidade de código, não necessariamente
representará menos recursos ocupados no hardware, pois cada soma será transformada em um circuito
somador, provavelmente, muito semelhante ao implementado no somador1bit. Para esta soma com o bit de
carry, foi realizada a operação considerando 5 bits e então ligado o bit mais significativo ao sinal de carry
out.
13
use i e e e . s t d l o g i c u n s i g n e d . a l l ; 3
4
entity s o m a d o r 4 b i t s i s 5
port ( 6
e n t r a d a 0 : in s t d l o g i c v e c t o r ( 3 downto 0 ) ; 7
e n t r a d a 1 : in s t d l o g i c v e c t o r ( 3 downto 0 ) ; 8
cin : in s t d logic ; 9
saida : out s t d l o g i c v e c t o r ( 3 downto 0 ) ; 10
cout : out s t d logic ) ; 11
end entity s o m a d o r 4 b i t s ; 12
13
architecture e s t r u t u r a l of s o m a d o r 4 b i t s i s 14
−− componente s o m a d o r 1 b i t 15
component so m ad o r1b i t i s 16
port ( a : in s t d l o g i c ; 17
b : in s t d l o g i c ; 18
c i n : in s t d l o g i c ; 19
s : out s t d l o g i c ; 20
c o u t : out s t d l o g i c ) ; 21
end component ; 22
23
s i g n a l s c a r r y : s t d l o g i c v e c t o r ( 2 downto 0 ) ; 24
begin 25
−− i n s t a n c i a s do somador de 1 b i t 26
somador1 : s o m ad o r1 b i t 27
port map( a => e n t r a d a 0 ( 0 ) , 28
b => e n t r a d a 1 ( 0 ) , 29
cin => c i n , 30
s => s a i d a ( 0 ) , 31
c o u t => s c a r r y ( 0 ) ) ; 32
somador2 : s o m ad o r1 b i t 33
port map( a => e n t r a d a 0 ( 1 ) , 34
b => e n t r a d a 1 ( 1 ) , 35
cin => s c a r r y ( 0 ) , 36
s => s a i d a ( 1 ) , 37
c o u t => s c a r r y ( 1 ) ) ; 38
somador3 : s o m ad o r1 b i t 39
port map( a => e n t r a d a 0 ( 2 ) , 40
b => e n t r a d a 1 ( 2 ) , 41
cin => s c a r r y ( 1 ) , 42
s => s a i d a ( 2 ) , 43
c o u t => s c a r r y ( 2 ) ) ; 44
somador4 : s o m ad o r1 b i t 45
port map( a => e n t r a d a 0 ( 3 ) , 46
b => e n t r a d a 1 ( 3 ) , 47
cin => s c a r r y ( 2 ) , 48
s => s a i d a ( 3 ) , 49
c o u t => c o u t ) ; 50
end architecture e s t r u t u r a l ; 51
52
53
14
architecture comportamental of s o m a d o r 4 b i t s i s 54
s i g n a l s soma : s t d l o g i c v e c t o r ( 4 downto 0 ) ; 55
begin 56
s soma <= ( ’ 0 ’ & e n t r a d a 0 ) + ( ’ 0 ’ & e n t r a d a 1 ) + ( ” 000 ” & c i n ) ; 57
c o u t <= s soma ( 4 ) ; 58
s a i d a <= s soma ( 3 downto 0 ) ; 59
end architecture comportamental ; 60
4 Máquinas de Estado
Máquinas de estado são frequentemente encontradas em sistemas que precisam alterar seu estado de execução
ou repetir uma quantidade variável de vezes algumas operações. A descrição de uma máquina de estados
envolve a definição de estados através da definição de um type e o uso de case. Outra caracterı́stica quando é
necessário o uso de Máquinas de estado, é a utilização de um sinal de relógio e um sinal de restabelecimento
(reset) para que a máquina de estados volte ao estado inicial. Uma implementação de uma máquina de
estados que implementa a multiplicação através de somas sucessivas2 de dois valores com 4 bits pode ser
vista na Listagem 15.
Listagem 15: Máquina de Estados: multiplicador
li b r a r y i e e e ; 1
use i e e e . s t d l o g i c 1 1 6 4 . a l l ; 2
use i e e e . s t d l o g i c u n s i g n e d . a l l ; 3
4
entity m u l t i p l i c a d o r i s 5
port ( 6
e n t r a d a 0 : in s t d l o g i c v e c t o r ( 3 downto 0 ) ; 7
e n t r a d a 1 : in s t d l o g i c v e c t o r ( 3 downto 0 ) ; 8
clk : in s t d l o g i c ; 9
enable : in s t d l o g i c ; 10
reset n : in s t d l o g i c ; 11
saida : out s t d l o g i c v e c t o r ( 7 downto 0 ) ; 12
done : out s t d l o g i c ) ; 13
end entity m u l t i p l i c a d o r ; 14
15
architecture s i m p l e s of m u l t i p l i c a d o r i s 16
−− e s t a d o s da maquina 17
type e s t a d o s i s ( desocupada , m u l t i p l i c a n d o ) ; 18
19
−−s i n a i s 20
signal s estado : estados ; 21
signal s o p e r a n d o 0 : s t d l o g i c v e c t o r ( 3 downto 0 ) ; 22
signal s o p e r a n d o 1 : s t d l o g i c v e c t o r ( 3 downto 0 ) ; 23
signal s p r o d u t o : s t d l o g i c v e c t o r ( 7 downto 0 ) ; 24
signal s done : std logic ; 25
26
begin 27
2 Existem outros algoritmos para implementar a multiplicação binária de forma mais eficiente.
15
mul proc : process ( r e s e t n , c l k ) 28
begin 29
i f ( r e s e t n = ’ 0 ’ ) then 30
s d o n e <= ’ 0 ’ ; 31
s p r o d u t o <= ( others => ’ 0 ’ ) ; 32
s e s t a d o <= desocupada ; 33
e l s i f ( c l k ’ e v e n t and c l k = ’ 1 ’ ) then 34
−− maquina de e s t a d o 35
case ( s e s t a d o ) i s 36
when desocupada => 37
i f ( e n a b l e = ’ 1 ’ ) then 38
s p r o d u t o <= ( others => ’ 0 ’ ) ; 39
s d o n e <= ’ 0 ’ ; 40
s e s t a d o <= m u l t i p l i c a n d o ; 41
s o p e r a n d o 0 <= e n t r a d a 0 ; 42
s o p e r a n d o 1 <= e n t r a d a 1 ; 43
end i f ; 44
when m u l t i p l i c a n d o => 45
i f ( s o p e r a n d o 1 /= ” 0000 ” ) then 46
s p r o d u t o <= s p r o d u t o + ( ” 0000 ” & s o p e r a n d o 0 ) ; 47
s o p e r a n d o 1 <= s o p e r a n d o 1 − 1 ; 48
else 49
s d o n e <= ’ 1 ’ ; 50
s e s t a d o <= desocupada ; 51
s a i d a <= s p r o d u t o ; 52
end i f ; 53
end case ; 54
end i f ; 55
end process mul proc ; 56
done <= s d o n e ; 57
end architecture s i m p l e s ; 58
Referências
[Cray Inc. 2005] Cray Inc. (2005). Cray XD1 System Overview. Mendota Heights, MN, USA.
[Universidade Federal de Itajubá ] Universidade Federal de Itajubá. Tutorial de vhdl. Tutorial desenvolvido
pelo grupo de microeletrônica.
16