vhdl

95
VHDL Projeto de Iniciação Científica Biblioteca Aritmética Murilo I. Rodrigues www.vhdl.hpg.com.br [email protected] FEI - 1999

Upload: fabio-batista

Post on 26-Jul-2015

129 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Vhdl

VHDLProjeto de Iniciação Científica

Biblioteca Aritmética

Murilo I. [email protected] - 1999

Page 2: Vhdl

INDICE

PARTE I

Apresentação do MaxPlux................................................................................................... 1

Iniciando um Projeto para Descrição em VHDL................................................................. 2

Comandos Principais.............................................................................................. 3

Tipos de Sinais....................................................................................................... 4

Entradas e Saídas do Nosso Projeto - Definindo uma Entidade........................................... 4

Definindo a Arquitetura do Nossa Entidade......................................................................... 5

Definindo um Processo para nossa Arquitetura................................................................... 6

Finalmente vamos escrever o código

Apresentação do Algoritmo da SOMA.................................................................. 8

Em VHDL.............................................................................................................. 8

Código Final........................................................................................................... 10

Agora vamos Copilar o Código Digitado............................................................................. 11

Simulando o Projeto............................................................................................................. 12

Iniciando um Projeto para Desenhar o Circuito (Floorplan)

Símbolos do Floorplan ........................................................................................... 17

Exercícios............................................................................................................................. 21

Page 3: Vhdl

PARTE I

Page 4: Vhdl

MaxPlux

Apresentação do MAX+plus

Este software nos será útil para a simplificação e implementação de circuitos digitais. Particularmentetrabalharemos com a parte aritmética, criando uma biblioteca aritmética para ser usada em aplicações futuras.

Para Iniciar umnovo projeto!

Page 5: Vhdl

Iniciando um Projeto para Descrição em VHDL

Na barra de ferramentas do MAX+plus clique no botão mais a esquerda, após abrir a janela de‘Novo’, você irá informar o que você quer, selecione ‘Text Editor file’ e clique Ok. Abrirá uma janela detexto onde você digitará o seu projeto.

Antes de prosseguir, salve o projeto informado que é um texto que contem uma descrição em VHDL, cliqueno botão salvar . Na janela ‘Salvar’, informe o nome do projeto e indique que a extensão *.VHD, eclique Ok.

Page 6: Vhdl

Comandos Principais

Agora já podemos digitar nosso projeto:

Em primeiro vamos indicar que queremos usar a biblioteca ieee.

LIBRARY ieee;USE ieee.std_logic_1164.all;

Agora vamos declarar uma entidade, que contém a descrição das entradas e saídas do circuito.

Selecione no Menu Templantes, VHDL Templantes..., e selecione Entity Declaration e clique Ok.

Criará o seguinte código em seu projeto.

ENTITY __entity_name ISPORT(

__input_name, __input_name : IN STD_LOGIC;__input_vector_name : IN

STD_LOGIC_VECTOR(__high downto __low);__bidir_name, __bidir_name : INOUT STD_LOGIC;__output_name, __output_name : OUT STD_LOGIC);

END __entity_name;

__entity_name – Nome da entidade, tem que ser obrigatoriamente o mesmo nome do projeto.__input_name – Nome de um sinal de entrada.__output_name - Nome de um sinal de saída.

Page 7: Vhdl

Tipos de Sinais

STD_LOGIC – sinal lógico aceita ‘1’ – nível lógico 1, ‘0’ – nível lógico 0.STD_LOGIC_VECTOR(bit downto 0)– um vetor de sinais lógicos com tamanho de bit-1 bits.

Entradas e Saídas do Nosso Projeto – Definindo uma Entidade

Nosso projeto será um somador de 8 bits, e terá como entrada dois vetor, A e B, que serão os operadores e umvetor de saída S que conterá o resultado da soma de A e B.

Faça as substituições necessárias para que o código fique da seguinte maneira:

LIBRARY ieee;USE ieee.std_logic_1164.all;

ENTITY Algo ISGENERIC(byte_entrada: integer := 8; byte_saida: integer := 16);PORT(

clk : IN STD_LOGIC;A, B : IN STD_LOGIC_VECTOR(byte_entrada-1 downto 0);S : OUT STD_LOGIC_VECTOR(byte_saida-1 downto 0));

END Algo;

Note que:GENERIC – Está instrução serve para declarar constantes na entidade, note que usamos as constantesbyte_entrada e byte_saida para indicar o tamanho dos sinais de entrada e saída respectivamente e as usaremosmais a frente em nosso projeto.

O sinal de entrada clk servirá para acionar o somador, qdo. este sinal for de ‘0’ para ‘1’ o circuito apresentaráa soma do sinal A com o sinal B na saída S.

Qdo. o sinal é declarado como INOUT, ele servirá tanto para entrada como para saída. Ou seja, este sinal desaída será um registrador interno também.

Page 8: Vhdl

Definindo a Arquitetura do Nossa Entidade

Novamente selecione no Menu Templates, VHDL Templantes..., selecione Architecture Body... e clique Ok.

Criará o seguinte código em seu projeto.

ARCHITECTURE a OF __entity_name ISSIGNAL __signal_name : STD_LOGIC;SIGNAL __signal_name : STD_LOGIC;

BEGIN-- Process Statement

-- Concurrent Procedure Call

-- Concurrent Signal Assignment

-- Conditional Signal Assignment

-- Selected Signal Assignment

-- Component Instantiation Statement

-- Generate StatementEND a;

(a) Nome daArquitetura

Nome da Entidadeque a arquiteturadescreve

Declarações de SinaisAuxiliares usados naarquitetura.Descrição dos

processossíncronos eassíncronos

Page 9: Vhdl

Faça as alterações necessárias para que o código fique da seguinte maneira:

LIBRARY ieee;USE ieee.std_logic_1164.all;

ENTITY Algo ISGENERIC(byte_entrada: integer := 8; byte_saida: integer := 16);PORT(

clk : IN STD_LOGIC;A, B : IN STD_LOGIC_VECTOR(byte_entrada-1 downto 0);S : OUT STD_LOGIC_VECTOR(byte_saida-1 downto 0));

END Algo;

ARCHITECTURE Algo OF Algo IS

BEGIN-- Process Statement

END Algo;

Definindo um Processo para nossa Arquitetura

Posicione o cursor na linha seguinte ao comentário ‘-- Process Statement’ , e vá ao Menu Templates,Templates..., e selecione Process (Combinatorial Logic).... Será criado o seguinte código em seu projeto:

__process_label:PROCESS (__signal_name, __signal_name, __signal_name)

VARIABLE __variable_name : STD_LOGIC;VARIABLE __variable_name : STD_LOGIC;

BEGIN-- Signal Assignment Statement

-- Variable Assignment Statement

-- Procedure Call Statement

-- If Statement

-- Case Statement

-- Loop StatementEND PROCESS __process_label;

Nome do Processo

Declarações de VariáveisAuxiliares usadas dentrodo Processo.

Descrição da seqüência deações que descreve oprocesso.

Page 10: Vhdl

Faça as alterações necessárias para que o código fique da seguinte maneira:

LIBRARY ieee;USE ieee.std_logic_1164.all;

ENTITY Algo ISGENERIC(byte_entrada: integer := 8; byte_saida: integer := 16);PORT(

clk : IN STD_LOGIC;A, B : IN STD_LOGIC_VECTOR(byte_entrada-1 downto 0);S : OUT STD_LOGIC_VECTOR(byte_saida-1 downto 0));

END Algo;

ARCHITECTURE Algo OF Algo IS

BEGIN-- Process Statement

Algo_Soma:PROCESS (clk)BEGIN

END PROCESS Algo_Soma;

END Algo;

Note que:PROCESS(clk) – clk como parâmetro indica que o processo só será executado qdo. O sinal de entrada clkmudar de estado lógico.

Page 11: Vhdl

Finalmente vamos escrever o código

Apresentação do Algoritmo da SOMA

SejaA := Operado1 -- NR_MAX_DE_BITSB := Operador2 -- NR_MAX_DE_BITSR := Resultado da soma -- 2 * NR_MAX_DE_BITS

vaium := ‘0’;Para i de 0 até NR_MAX_DE_BITS-1 Faça

R[i]:= A[i] xor B[i] xor vaium;

vaium := ( B[i] and A[i] ) or( B[i] and vaium) or(vaium and A[i] );

Fim;

R[NR_MAX_DE_BITS] := vaium;

Para i de NR_MAX_DE_BITS +1 até 2 * NR_MAX_DE_BITS-1 FaçaR[i]:= ‘0’;

Fim;

Por exemplo: Somar 3H com BH, resultando EH. A e B com 4 bits e R com 8 bits.

carry A(I) B(I) R(O)0 0011 1011 000000001 0011 1011 000000101 0011 1011 000001100 0011 1011 000011100 00001110

000011100000111000001110

Em VHDL

• Na linha abaixo de Process(clk), vamos colocar a declaração da uma variável auxiliar vaium.

--Declara uma variavel auxiliar 'vaium' com tipo: STD_LOGIC--Serão usadas mas adiante no códigoVARIABLE vaium : STD_LOGIC;

• Posicione o cursor entre BEGIN e END PROCESS..., e digite os códigos ou procure no Menu Templates,VHDL Templates... .

• Primeiro vamos informar que nosso circuito só funcionará na borda de subida do clk.

Page 12: Vhdl

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

-- Coloque seu código aqui

END IF;

EVENT – Indica que houve um evento de clk.AND clk = ‘1’ – Indica que clk foi para ‘1’

• Satisfazendo a condição de ser borda de subida do clk, vamos iniciar vaium com ‘0’:--Qdo. o processo começar, inicia a var. vaium com 0vaium := ‘0’;

:= , serve para atribuições em variáveis e<=, serve para atribuições em sinais

• Logo após, vamos fazer o loop da Soma.

--Loop PrincipalloopSoma:FOR i IN A'RANGE LOOP S(i) <= A(i) xor B(i) xor vaium;

vaium := ( B(i) and A(i) ) or( B(i) and vaium) or(vaium and A(i) );

END LOOP loopSoma;

A'RANGE – indica que i vai tomar valores de 0 até o tamanho de bits de A, e executar as ações para cada umdeste valor.

• Depois de ter executado o loop da Soma, vamos colocar vaium na posição ‘byte_entrada’ do sinal S.

--Se o resultado excedeu o tamanho de bits da entradaS(byte_entrada) <= vaium ;

• E zerar as demais posições de S, ou seja os bits de byte_entrada até byte_saida-1.

--Zera os bits mais altos não usados na somaloopZera:FOR i IN byte_entrada+1 TO byte_saida-1 LOOP S(i) <= '0';END LOOP loopZera;

• Pronto o sinal S contém o resultado da soma de A com B.

Em seguida listamos o código final do nosso projeto:

Page 13: Vhdl

Código Final

LIBRARY ieee;USE ieee.std_logic_1164.all;

ENTITY Algo ISGENERIC(byte_entrada: integer := 8; byte_saida: integer := 16);PORT(

clk : IN STD_LOGIC;A, B : IN STD_LOGIC_VECTOR(byte_entrada-1 downto 0);S : OUT STD_LOGIC_VECTOR(byte_saida-1 downto 0));

END Algo;

ARCHITECTURE Algo OF Algo ISBEGIN-- Process Statement

Algo_Soma:PROCESS (clk)

--Declara uma variavel auxiliar 'vaium' com tipo: STD_LOGIC--Serão usadas mas adiante no códigoVARIABLE vaium : STD_LOGIC;

BEGIN

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

--Qdo. o processo começar, inicia a var. vaium com 0vaium := '0';

--Loop PrincipalloopSoma:FOR i IN A'RANGE LOOP S(i) <= A(i) xor B(i) xor vaium;

vaium := ( B(i) and A(i) ) or( B(i) and vaium) or(vaium and A(i) );

END LOOP loopSoma;

--Se o resultado excedeu o tamanho de bits da entradaS(byte_entrada) <= vaium ;

--Zera os bits mais altos não usados na somaloopZera:FOR i IN byte_entrada+1 TO byte_saida-1 LOOP S(i) <= '0';END LOOP loopZera;

END IF;END PROCESS Algo_Soma;

END Algo;

Page 14: Vhdl

Agora vamos Copilar o Código Digitado

Antes vá no Menu de Projetos, File – Project, e selecione Set Project to Current File. Assim você informa queo projeto principal é o que está na janela ativa.

Depois no Menu de Projetos clique em Save & Compile, aparecerá mais duas janelas, uma do copilador, eoutra com as mensagens da compilação. No caso do código estiver com erro de sintaxe, no fim da tentativa decompilação será mostrado uma mensagem informando quantos erros ocorreram.

Setar ProjetoPrincipal

Para Copilarou Simular.

Mensagem de Erro, falta ‘;’ nofinal da linha 33. Dê doiscliques na mensagem e corrijaesse erro.

Page 15: Vhdl

Neste caso, na janela de mensagens são informados o número da linha e o que ocorreu de errado. Dê doiscliques na mensagem de erro e você será levado a linha que foi identificado o erro.Um erro muito comum é o esquecer do ponto e virgula no final da linha.Algumas vezes as mensagens de erro seguinte da primeira são conseqüência dela, ou seja, identificando econcertando o primeiro erro os demais também são consertados. As vezes ocorre o contrario um erro escondeos outros, ou seja, consertando aparentemente o único erro do projeto e copilando novamente, você descobrevários outros.Mas não desista, lembre-se do ditado que diz: aprendemos com nossos próprios erros.

Simulando o Projeto

No Menu MAX+plus II, clique em Waveform Editor. Abrirá a janela do Editor de Forma de Onda. Nela vocêcolocará os sinais de entrada e saída que deseja testar. Seta os sinais de entrada no tempo.Manda simular, e será mostrado os dados de saída em função do tempo.

Page 16: Vhdl

Com a janela Waveform Editor aberta. Vá ao Menu Node e Selecione Insert Node. Abrirá a seguinte janela,na qual você escolherá os sinais de entrada ou saída que desejar.

Selecione clk(I) e clique Ok. Repta o procedimento, inserindo os sinais A(I), B(I) e S(O).Clique duas vezes em cima de A(I), abrirá uma janela de informações do Grupo de sinal A[0..7].

Selecione HEX e clique Ok. Assim os números serão exibidos em hexadecimal. Repita também para B e S.

Listagem de todos osSinais, de entrada esaída do projeto

Nome do Sinal que seráinserido

Lista sinais.

InsereSinal

Tipo do sinal:Entrada ou Saída.

Page 17: Vhdl

Seu Waveform deve estar assim:

Agora, vamos colocar os valores em A e B que queremos somar. Selecione A(I), clicando em cima dele.

Com A(I) selecionado clique em na barra de ferramentas a esquerda. Digite um valor e Ok.

Repita o procedimento com B(I), digitando um valor para ele também.

Com o sinal clk, vamos criar uma borda de subida num tempo qualquer maior que 0, claro.

Com o mouse selecione a faixa de tempo que deseja colocar ‘1’ em clk: por exemplo:

E clique em na barra de ferramentas a esquerda. Isso fará com que a faixa selecionada fique em um.

No exemplo, borda de subida em t=100,0ns, onde ocorrerá a soma de A com B e será apresentado o resultadoem S.

Seu Waveform deve estar assim:

Faixaselecionadacom o mouse!

Page 18: Vhdl

Finalmente com todas as entradas setadas, vamos mandar simular o projeto. Vá ao Menu File, Project, Save &Simulate.

Abrirá uma janela pedindo que você informe um nome para o arquivo WaveForm, clique Ok.

Ele começara o processo de simulação, e se não houver nenhum erro, você verá a seguinte mensagem:

Clique Ok e seu WaveForm deverá estar assim:

Sinais emrelação aotempo

Tempo

CursorNome doSinalI-EntradaO-Saída

Valor dossinais em cimado cursor.

Page 19: Vhdl

Você pode selecionar um intervalo de tempo para a simulação. No Menu View, clique em Time Range.Na janela Time Range coloque o tempo inicial e final, depois clique Ok.

No Menu View clique em Fit in Windows, que redesenha os sinais colocando-os todos dentro da telaAgora faça mais teste com os sinais, por exemplo:

Note que a soma é feita somente qdo. o sinal clk é levado para ‘1’.

Page 20: Vhdl

Iniciando um Projeto para Desenhar o Circuito (Floorplan)

Na barra de ferramentas do MAX+plus clique no botão mais a esquerda, após abrir a janela de‘Novo’, você irá informar o que você quer, selecione ‘Graphic Editor file’ e ‘*.gdf’ e clique Ok. Assim Abriráuma janela na qual você desenhará o seu projeto.

Símbolos do Foorplan

Dê um clique duplo dentro da janela de desenho ou selecione no menu Symbol, Enter Symbol..., e abrirá umdialogo permitindo que selecione um símbolo pré-definido. Por exemplo, para iniciarmos nosso projetovamos selecionar três símbolos de entrada (input) e um de saída (output).

Selecione aquia Biblioteca desímbolos.

Selecioneaqui oSímbolos.

Page 21: Vhdl

Na tela de ‘Lista de Símbolos’, selecione ..\maxplus2\max2lib\prim na biblioteca de símbolo, dando doiscliques nesta opção, será listada os símbolos dessa biblioteca, selecione input., e clique Ok.Será criada em sua janela de trabalho uma porta de entrada:

Para um dar o nome do sinal, selecione este sinal com um clique em cima dele. Clique no botão direito domouse e aparecerá o seguinte menu:

Selecione Edit Pin Name e escolha um nome para este sinal.

Repita este processo mais duas vezes, criando assim três sinais de entradas (A, B e VemUm). E com o mesmoprocesso, só que selecionando output no lugar de input, crie dois sinal de saída (S e VaiUm) para nossoprojeto.

O circuito deverá obedecer as seguintes fórmulas:S := A xor B xor VaiUm;VaiUm := ( B and A ) or ( B and VaiUm) or (VaiUm and A);

RecortarCopiarColarApagar componente

Editar Nome do Sinal

Editar valor Default dosinal (Vcc ou GND)

Roda Componente:Verticalmente,HorizontalmentePor angulo.

Page 22: Vhdl

Repetindo o processo para selecionar os sinais de entrada e saída (input e output), escolha agora as portaslógicas: duas xor, três and2 e uma or3.Para facilitar, quando o cursor estiver em Symbol Files e você quer selecionar xor, digite ‘X’ no teclado, queserá posicionado o cursor no próximo símbolo que comece com a letra ‘X’.Mais uma, se você já tem um componente na tela e deseja outro igual, selecione-o, clique no botão direito domouse, escolha copiar. Depois no local da tela onde deseja copy o componente, clique novamente no botãodo mouse e selecione paste. Ou, segurando o Ctrl, clique no componente e arraste-o que ele será duplicado.

Sua tela deve estar assim:

Agora com o Menu de Ferramentas posicionado mo lado esquerdo da janela, desenhe as linhas necessárias:

Modo Cursor, Serve paraarrastar componentes.

Para escrever alguminformativo no circuito.

Para fazer linhas de ligaçãocom curvas de 90 º.

Linhas de ligação retas.

Amplia ou Diminui avisualização doscomponentes.

Page 23: Vhdl

Seu circuito deve ficar assim:

Agora Salve, Compile e Simule o circuito da mesma maneira que foi descrito na parte anterior deste manual.

Digite Ctrl+L ou vá e, Files, Project, Save & Copile. Se todas as ligações foram feitas corretamente, vocêdeve receber uma mensagem ‘Projeto Compilado com sucesso’.

Crie uma nova janela WaveForm para simular o projeto. Insira nela os sinais A, B, VemUm e VaiUm. Nomenu Node, Insert Node. Na janela Insert Node, clique em List, selecione o sinal e clique Ok. Para maisinformação ver Capitulo Simulando o Projeto.

Informe os valores desejados para os sinais de entrada, no menu selecione, Files, Project, Save & Simule oudigite Ctrl+Shift+L para salvar e simular o projeto obtendo assim os valores de saída a partir dos dados deentrada.

Obtendo assim:

Há vários outros símbolos pré-definidos que você pode usar como também todos os seus projetos já copiladostambém estarão disponíveis.

Page 24: Vhdl

Exercícios:

1) Fazer a descrição em VHDL de um circuito subtrator de n bits. Copilar e Simular.R.:

Apresentação do Algoritmo da Subtração

SejaA := Operado1 -- NR_MAX_DE_BITSB := Operador2 -- NR_MAX_DE_BITSR := Resultado da soma -- NR_MAX_DE_BITS

vaium := ‘0’;Para i de 0 até NR_MAX_DE_BITS-1 Faça

R[i]:= A[i] xor B[i] xor vaium;

vaium := ( B[i] and R[i]) or( B[i] and vaium) or(vaium and R[i]);

Fim;

Por exemplo: Subtrair 3H de BH, resultando 8H. A, B e R com 4 bits.

carry A(I) B(I) R(O)0 0011 1011 00000 0011 1011 00000 0011 1011 00000 0011 1011 1000

Foi feito um flag de erro, que vai para ‘1’ quando o operador B for maior que o operador A. Isso geraria umresultado negativo, não previsto.

Page 25: Vhdl

Em VHDL:

LIBRARY ieee;USE ieee.std_logic_1164.all;-- Subtração S = A - BENTITY Subr IS

GENERIC(byte_entrada: integer := 8; byte_saida: integer := 8);PORT(

clk : IN STD_LOGIC;A, B : IN STD_LOGIC_VECTOR(byte_entrada-1 downto 0);S : OUT STD_LOGIC_VECTOR(byte_saida-1 downto 0);erro : OUT STD_LOGIC);

END Subr;

ARCHITECTURE Subr OF Subr ISBEGIN-- Process Statement

Subr_Soma:PROCESS (clk)

--Declara uma variavel auxiliar 'vaium' e svlAi com tipo: STD_LOGIC--Serão usadas mas adiante no códigoVARIABLE vaium : STD_LOGIC;VARIABLE auxS: STD_LOGIC;

BEGIN

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

--Qdo. o processo começar, inicia a var. vaium com 0vaium := '0';

--Loop PrincipalloopSoma:FOR i IN 0 TO byte_entrada-1 LOOP

auxS := (A(i) xor B(i) xor vaium);S(i) <= (A(i) xor B(i) xor vaium);

vaium := ( B(i) and auxS ) or ( B(i) and vaium) or (vaium and auxS ) ;

END LOOP loopSoma;

--Se o A > B, resultado é negativo.erro <= vaium ;

END IF;END PROCESS Subr_Soma;

END Subr;

Page 26: Vhdl

2) Fazer o desenho em Floorplan de um circuito contador assíncrono. Copilar e Simular.R.

Um contador é um registrador capaz de contar o número de pulsos de relógio que chegaram em suaentrada de relógio.

A fig. Abaixo mostra um contador construído com biestáveis JK.

O Circuito:

A simulação:

Page 27: Vhdl

VHDLProjeto de Iniciação Científica

Biblioteca Aritmética

Murilo I. [email protected] - 1999

Page 28: Vhdl

PARTE II

Subdividindo o Programa em Funções................................................................................ 24Função Soma.......................................................................................................... 24Função para Rotacionar um Sinal: STD_LOGIC_VECTOR................................. 25Função para Setar um bit no Sinal: STD_LOGIC_VECTOR............................... 26Função para ler um bit no Sinal: STD_LOGIC_VECTOR................................... 27Função para Comparar Numericamente dois sinais............................................... 28Função para retornar ‘um’ se o sinal for zero caso contrário ‘zero’...................... 29Função Subtração.................................................................................................... 30

Divisão para n-Bits.............................................................................................................. 31

Padrão de Interface............................................................................................................... 31

Esqueleto do Programa em VHDL contendo um LAÇO..................................................... 32

Forma de Onda dos Sinais de Entrada e Saída de um Divisor de 8 bits............................... 34

Multiplicação de N-bits........................................................................................................ 35

Forma de Onda dos Sinais de Entrada e Saída de um Multiplicador de 8 bits..................... 37

Raiz Quadrada para Operadores de N-bits.......................................................................... 38

Esqueleto do Programa em VHDL contendo dois LAÇO For...Next Aninhado.................. 39

Forma de Onda dos Sinais de Entrada e Saída ( Raiz Quadrada de 6 bits )........................ 42

Conversão de Hexadecimal para Decimal............................................................................ 43

Esqueleto do Programa em VHDL contendo dois LAÇO Aninhado (While..For...Next...Wend)............. 44

Forma de Onda dos Sinais de Entrada e Saída ( Conversor Hexa para Decimal - 8 bits )............... 47

Conversor de Decimal para Hexadecimal............................................................................ 48

Listagem Completa do Process Para Conversão de Decimal para HexaDecimal................ 49

Forma de Onda dos Sinais de Entrada e Saída ( Conversor Decimal para HexaDecimal ).............. 50

Função Multiplicação........................................................................................................... 51

Forma de Onda De uma Chamada a Função S := Multiplic( A, B ) .................................... 51

Exercícios............................................................................................................................. 52Função Divisão....................................................................................................... 52

Observações......................................................................................................................... 54

Page 29: Vhdl

PARTE II

Page 30: Vhdl

Subdividindo o Programa em Funções

Sintaxe:

FUNCTION __function_name(__input_name, MACHINE __state_machine_name)RETURNS (__output_name, __bidir_name, MACHINE __state_machine_name);

Exemplo de Aplicação

Função Soma

----------------------------------------------- S := Soma ( A , B )---------FUNCTION Soma (

A : STD_ULOGIC_VECTOR; B : STD_ULOGIC_VECTOR

)RETURN STD_ULOGIC_VECTOR IS

VARIABLE vaium : STD_ULOGIC;VARIABLE S : STD_ULOGIC_VECTOR(A’Length -1 downto 0);

BEGINvaium := '0';

--Loop PrincipalloopSoma:FOR i IN 0 TO B’Length-1 LOOP

S(i) := A(i) xor B(i) xor vaium;

vaium := ( B(i) and A(i) ) or( B(i) and vaium) or(vaium and A(i) );

END LOOP loopSoma;

LoopSoma2:FOR i IN B’Length TO A’Length -1 LOOP

S(i) := A(i) xor vaium;

vaium := (vaium and A(i) );END LOOP LoopSoma2;

RETURN S;END Soma;

Sinais de Entrada. Ex. A : STD_ULOGIC

Sinal que será retornado

Page 31: Vhdl

Exemplo de Chamada a Função Soma

...

Algo:PROCESS (clk)

--Declara uma variavel auxiliarVARIABLE AUX : STD_ULOGIC_VECTOR(byte_saida-1 downto 0);A : STD_ULOGIC_VECTOR(byte_entrada-1 downto 0);

BEGIN

...AUX := Soma ( AUX, A );..

END Algo;

FUNÇÃO PARA ROTACIONAR UM SINAL: STD_LOGIC_VECTOR

----------------------------------------------- S := rot ( S )---------FUNCTION rot (S_IN : STD_ULOGIC_VECTOR)

RETURN STD_ULOGIC_VECTOR IS

VARIABLE S : STD_ULOGIC_VECTOR(S_IN'length-1 downto 0);BEGIN

loopRot:FOR i IN S_IN'length-1 DOWNTO 1 LOOP

S(i) := S_IN(i-1);END LOOP loopRot;S(0) := '0';

RETURN S;END rot;

Exemplo:

A: 0 0 0 1 1 0 1

A := rot ( A );

A: 0 0 1 1 0 1 0

Page 32: Vhdl

FUNÇÃO PARA SETAR UM BIT NO SINAL: STD_LOGIC_VECTOR

----------------------------------------------- S := set ( S, contador, bitset )---------FUNCTION set (S_IN : STD_ULOGIC_VECTOR;

Index : INTEGER RANGE 0 TO S_IN’Length -1;BitSet : STD_ULOGIC)

RETURN STD_ULOGIC_VECTOR IS

VARIABLE S : STD_ULOGIC_VECTOR(S_IN’Length -1 downto 0);BEGIN

loopRot:FOR i IN 0 TO S_IN’Length -1 LOOP

IF i = Index THEN S(i) := bitset;

ELSES(i) := S_IN(i);

END IF;END LOOP loopRot;

RETURN S;END set;

Exemplo:

A: 0 0 0 1 1 0 1I : 3B: 0

A := set( A, I, B );

A: 0 0 0 0 1 0 1

Page 33: Vhdl

FUNÇÃO PARA LER UM BIT NO SINAL: STD_LOGIC_VECTOR

----------------------------------------------- S := get( S, contador, bitset )---------FUNCTION get (S_IN: STD_ULOGIC_VECTOR;

Index : INTEGER RANGE 0 TO S_IN’Length -1;)

RETURN STD_ULOGIC_VECTOR IS

VARIABLE bitset : STD_ULOGIC;BEGIN

loopRot:FOR i IN 0 TO S_IN’Length -1 LOOP

IF i = Index THEN bitset := S(i);

END IF;END LOOP loopRot;

RETURN bitset;END get;

Exemplo:

A: 0 0 0 1 1 0 1I : 3B: 0

B := get( A, 3, ‘1’ );

B: 1

Page 34: Vhdl

FUNÇÃO PARA COMPARAR NUMERICAMENTE DOIS SINAIS

----------------------------------------------- S := intcmp ( A, B )-- Retorna: 1 – A >= B-- 0 – B > A---------FUNCTION intcmp (A : STD_ULOGIC_VECTOR;

B : STD_ULOGIC_VECTOR )RETURN STD_ULOGIC IS

VARIABLE S : STD_ULOGIC_VECTOR(A’length -1 downto 0);VARIABLE vaium : STD_ULOGIC;

BEGIN

vaium := '0';loopCmp:FOR i IN 0 TO A’length -1 LOOP

S(i) := (A(i) xor B(i) xor vaium);

vaium := ( B(i) and S(i) ) or ( B(i) and vaium) or(vaium and S(i) ) ;

END LOOP loopCmp;vaium := not vaium;

RETURN vaium;END intcmp;

EXAEMPLO:

A: 150

B: 50

IF INTCMP( A, B ) = ‘0’ THEN -- A < B

...

END IF;

Page 35: Vhdl

FUNÇÃO PARA RETORNAR ‘UM’ SE O SINAL FOR ZERO CASO CONTRÁRIO ‘ZERO’

----------------------------------------------- S := IsZero ( A , B )---------FUNCTION IsZero ( A : STD_ULOGIC_VECTOR(byte_width-1 downto 0)

)RETURN STD_ULOGIC IS

VARIABLE retorno : STD_ULOGIC;BEGIN

retorno := '1'; --É zero

--Loop PrincipalloopZero:FOR i IN 0 TO A'Length-1 LOOP

IF A(i) = '1' THENretorno := '0'; --Não é zero

END IF;

END LOOP loopZero;

RETURN retorno;END IsZero;

EXAEMPLO:

IF IsZero( A ) THEN -- A = 0

...

END IF;

Page 36: Vhdl

FUNÇÃO SUBTRAÇÃO

----------------------------------------------- S := Subtracao ( A , B )---------FUNCTION Subtracao (A : STD_ULOGIC_VECTOR;

B : STD_ULOGIC_VECTOR )

RETURN STD_ULOGIC_VECTOR IS

VARIABLE vaium : STD_ULOGIC;VARIABLE S : STD_ULOGIC_VECTOR(A’length -1 downto 0);

BEGIN--Qdo. o processo começar, inicia a var. vaium com 0vaium := '0';

--Loop PrincipalloopSubtr:FOR i IN 0 TO A’length -1 LOOP

S(i) := (A(i) xor B(i) xor vaium);

vaium := ( B(i) and S(i) ) or( B(i) and vaium) or (vaium and S(i) ) ;

END LOOP loopSubtr;RETURN S;

END Subtracao;

Exemplo de Chamada a Função Subtração

...

Algo:PROCESS (clk)

--Declara uma variavel auxiliarVARIABLE AUX : STD_ULOGIC_VECTOR(8 downto 0);A : STD_ULOGIC_VECTOR(8 downto 0);

BEGIN

...AUX := Subtracao( AUX, A );..

END ALGO;

Page 37: Vhdl

DIVISÃO PARA N-BITS

O algoritmo consiste em girar, juntamente com o ‘Carry’ o Dividendo dentro do Resto, estando esteinicialmente zerado. Um contador do número de Bits (tamanho do Dividendo) deverá ser decrementado cadavez que for realizado uma rotação.

Se o resto for Maior ou Igual ao Divisor o ‘Carry’ será igual a um, sendo este valor na próxima rotaçãoposicionado no bit 2º do dividendo. Toda vez que isto acontecer devemos atualizar o valor do Resto,subtraindo o valor do Divisor.

O final da próxima divisão irá ocorrer quando o contador de Bits for igual a zero, porém aindadevemos posicionar o último ‘Carry’ dentro do Dividendo, sem rotacionar o Resto.

A seguir apresentamos a aplicação do algoritmo para operadores de 8 bits

Dividendo -> 45 HDivisor -> 06 HQuociente -> 0B HResto -> 03 H

Carry Resto Dividendo / Quociente Divisor Contador0 0000 0000 0100 0101 0000 0110 080 0000 0000 1000 1010 0000 0110 070 0000 0001 0001 0100 0000 0110 060 0000 0010 0010 1000 0000 0110 050 0000 0100 0101 0000 0000 0110 040

1

0000 1000-0000 01100000 0010

1010 0000 0000 0110 03

0 0000 0101 0100 0001 0000 0110 020

1

0000 1010-0000 01100000 0100

1000 0010 0000 0110 01

0

1

0000 1001-0000 01100000 0011

0000 0101 0000 0110 00

0 0000 0011 0000 1011 Posiciona o último ‘Carry’0000 0011 0000 1011 Resultado

Padrão de Interface

Faremos três sinais de controle:clk – que será o clock;rst – que será o reset;str – que será o start.prt – vai para um quando o resultado já estiver pronto para leitura

Page 38: Vhdl

Esqueleto do Programa em VHDL contendo um LAÇO

LIBRARY ieee;USE ieee.std_logic_1164.all;

ENTITY Divi ISGENERIC(width_byte: integer := 8);PORT(

clk,str,rst : IN STD_ULOGIC;A, B : IN STD_ULOGIC_VECTOR(width_byte-1 downto 0);Q, R, prt : OUT STD_ULOGIC_VECTOR(width_byte-1 downto 0));

END Divi;

ARCHITECTURE Divi OF Divi IS-- Declaração das Funções Auxiliares

BEGIN-- Process Statement

Algo_Divi:PROCESS (clk)

--Declara das variáveis auxiliares--Contador, servira para controle de passagem--Como dentro de um laço For..NextVARIABLE Contador : INTEGER RANGE 0 TO width_byte+1;

BEGIN

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

IF rst = '1' THENContador := 0;prt <= ‘0’;--Zera variaveis de auxiliares--Copia sinais de entrada para variavies auxiliares, qdo. necessario

ELSEIF str = '1' THEN

IF Contador < width_byte THENContador := Contador + 1;-- Declaração dos Processos

ELSIF Contador = width_byte THENContador := Contador + 1;prt <= ‘1’;

--Copia o resultado para Saída Apropriada

END IF;END IF;

END IF;END IF;

END PROCESS Algo_Divi;END Divi;

Page 39: Vhdl

Variáveis Auxiliares

VARIABLE AUX_Q, AUX_R : STD_ULOGIC_VECTOR(width_byte-1 downto 0);VARIABLE vaiumQuoc, restoMaior : STD_ULOGIC;

AUX_Q - Guardara o Quociente da OperaçãoAUX_R – Guardara o Resto da DivisãovaiumQuoc – Carry, que recebe o bit de maior ordem qdo. rotacionar o QuocienterestoMaior – Vai para ‘1’ se o Resto for maior que o Divisor

Valores Iniciais para Variáveis Auxiliares ( reset )

loopZera:FOR i IN 0 TO width_byte-1 LOOP

AUX_R(i) := '0';END LOOP loopZera;AUX_Q := A;vaiumQuoc := '0';restoMaior := '0';

AUX_Q – recebe o Dividendo e guardara o QuocienteAUX_R – zera a variável que recebera o Resto da divisãoVaiumQuoc, restoMaior – zera variáveis auxiliares

Algoritmo principal que será executado em laço

vaiumQuoc := AUX_Q(width_byte-1);AUX_Q := rotSaida( AUX_Q );AUX_Q(0) := restoMaior;

AUX_R := rotSaida( AUX_R );AUX_R(0) := vaiumQuoc;restoMaior := intcmp( AUX_R, B );

IF restoMaior = '1' THENAUX_R := Subtracao( Aux_R, B );

END IF;

Esse algoritmo será executado a cada pulso de clock depois de começado a operação, conformequantidade de bits dos operadores.

Parte Final: Copia o Resultado para a Saída

AUX_Q := rotSaida( AUX_Q );AUX_Q(0) := restoMaior;loopCopy:FOR i IN 0 TO width_byte-1 LOOP

Q(i) <= AUX_Q(i);R(i) <= AUX_R(i);

END LOOP loopCopy;

Page 40: Vhdl

Forma de Onda dos Sinais de Entrada e Saída de um Divisor de 8 bits

Com os sinais em Binario

Continuação

Page 41: Vhdl

Multiplicação de N-bits

O algoritmo consiste em acrescentar zeros a esquerda (shift) do Multiplicador e do Produtoinicialmente zerado, até que o ‘Carry’seja um. Quando isto acontecer soma-se o Multiplicador ao Produtocolocando-se o resultado obtido no próprio Produto. Volta-se a rotacionar o Produto bem como oMultiplicador, até que o contador do número de bits (tamanho do Multiplicador) seja zero.

A seguir apresentamos a aplicação do algoritmo para operadores de 8 Bits:

Multiplicado à 03 HMultiplicador à 05 HResultado à 0F H

Carry Multiplicador Multiplicando Produto Contador0 0000 0101 0000 0011 0000 0000 0000 0000 080 0000 1010 0000 0011 0000 0000 0000 0000 070 0001 0100 0000 0011 0000 0000 0000 0000 060 0010 1000 0000 0011 0000 0000 0000 0000 050 0101 0000 0000 0011 0000 0000 0000 0000 040 1010 0000 0000 0011 0000 0000 0000 0000 031 0100 0000 0000 0011 + 0000 0000 0000 0000

0000 0011 0000 0000 0000 0011

02

0 1000 0000 0000 0011 0000 0000 0000 0000 011 0000 0000 0000 0011 0000 0000 0000 0000

+ 0000 0011 0000 0000 0000 1111

00

Resultado 0000 0000 0000 1111

Usando o Esqueleto já Apresentado Anteriormente. Vamos apresentar as partes adicionais:

Entradas e Saídas

ENTITY Mult ISGENERIC(byte_entrada: integer := 8; byte_saida: integer := 16);PORT(

clk,str,rst : IN STD_ULOGIC;A, B : IN STD_ULOGIC_VECTOR(byte_entrada-1 downto 0);S : OUT STD_ULOGIC_VECTOR(byte_saida-1 downto 0));

END Mult;

Page 42: Vhdl

Variáveis Auxiliares

VARIABLE AUX : STD_ULOGIC_VECTOR(byte_saida-1 downto 0);VARIABLE AUX_A : STD_ULOGIC_VECTOR(byte_entrada-1 downto 0);VARIABLE vaium : STD_ULOGIC;

AUX – Guardara o Produto da OperaçãoAUX_A – Guardara o Multiplicador para usar na função rotacionarvaium – Carry, que recebe o bit de maior ordem qdo. rotacionar o Multiplicador

Valores Iniciais para Variáveis Auxiliares ( reset )

loopZera:FOR i IN 0 TO byte_saida-1 LOOP

AUX(i) := '0';END LOOP loopZera;loopZera2:FOR i IN 0 TO byte_entrada-1 LOOP AUX_A(i) := A(i);END LOOP loopZera2;vaium := '0';

AUX_A – recebe o Multiplicador e guardara o QuocienteAUX – zera a variável que recebera o Produtovaium – zera variável auxiliar

Algoritmo principal que será executado dentro do laço

AUX := rotSaida( AUX );vaium := AUX_A(byte_entrada-1);IF vaium = '1' THEN

AUX := Soma( AUX, B );END IF;

AUX_A := rotEntrada( AUX_A );

Esse algoritmo será executado a cada pulso de clock depois de começado a operação, conformequantidade de bits dos operadores.

Parte Final: Copia o Resultado para a Saída

loopCopy:FOR i IN 0 TO byte_saida-1 LOOP

S(i) <= AUX(i);END LOOP loopCopy;

Page 43: Vhdl

Forma de Onda dos Sinais de Entrada e Saída de um Multiplicador de 8 bits

Com os sinais em Binario

Continuação

Page 44: Vhdl

Raiz Quadrada para Operadores de N-bits

Consiste em fazermos o Bit de maior ordem do local onde ficará o resultado, inicialmente igual a um,mantendo-se o valor dos Bits restantes iguais a zero.

Eleva-se o valor do resultado ao quadrado e subtraímos o valor que desejamos extrair a RaizQuadrada. Se a subtração for bem sucedida ou seja ‘Carry’ Maior ou Igual a zero, mantemos este Bit em nívellógico um. Caso contrário deverá ser trocado para nível zero.

Este processo deverá ser feito com todos os Bits que irão compor o resultado. A seguir apresentamosa implementação do algoritmo para um resultado máximo de 8 Bits.

Valor da Raiz à √(ABCD H) = D1 H

Resultado Resultado ao Quadrado Subtração Carry Bit(1000 0000) = (80) 2 16

(4000) 16

ABCD – 4000 > 0 27= 1

(1100 0000) = (80) 2 16

(9000) 16

ABCD – 9000 > 0 26= 1

(1110 0000) = (80) 2 16

(C400) 16

ABCD – C400 < 0 25= 0

(1101 0000) = (80) 2 16

A900) 16

ABCD – A900 > 0 24= 1

(1101 1000) = (80) 2 16

(B640) 16

ABCD – B640 < 0 23= 0

(1101 0100) = (80) 2 16

(AF90) 16

ABCD – AF90 < 0 22= 0

(1101 0010) = (80) 2 16

(AC44) 16

ABCD – AC44 < 0 21= 0

(1101 0001) = (80) 2 16

(AAA1) 16

ABCD – AAA1 > 0 20= 1

Resultado è 1101 0001 = D1 H

Neste caso há dois LAÇOS a serem executados: o LAÇO principal do algoritmos da extração da Raizque usa uma Multiplicação a cada passagem.

Esta Multiplicação será executado em outro LAÇO secundário.

Então nosso esqueleto será alterado para que possamos executar um LAÇO dentro do outro.

Page 45: Vhdl

Esqueleto do Programa em VHDL contendo dois LAÇO For...Next Aninhado

BEGIN-- Process Statement

Algo_Raiz:PROCESS (clk)

--Declara as variáveis auxiliares--Contador, servira para controle de passagem--Como dentro de dois laço Aninhado For.For..Next.Next

VARIABLE Contador : INTEGER RANGE 0 TO byte_width+1;VARIABLE ContMult : INTEGER RANGE 0 TO byte_width+1;

BEGIN--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

IF rst = '1' THENContador := 0;ContMult := byte_width;prt <= ‘0‘;

--Zera variaveis auxiliares para primeiro LAÇO--Copia sinais de entrada para variavies auxiliares, qdo. necessario

ELSEIF str = '1' THEN

IF Contador < byte_width THENIF ContMult = byte_width THEN

-- Declaração dos Processos do 1º LAÇO

--Seta variaveis auxiliares para segundo LAÇOContMult := 0;

ELSEContMult := ContMult + 1;-- Aqui coloca os Processo para segundo LAÇOIF ContMult = byte_width THEN

-- Último passo do segundo LAÇO-- Seta valores de retorno de LAÇOContador := Contador + 1;

END IF;

END IF;

ELSIF Contador = byte_width THENContador := Contador + 1;prt <= ‘1’;-- Copia Resultado para sinal de Saida

END IF;END IF;

END IF;END IF;

END PROCESS Algo_Raiz;

Page 46: Vhdl

Sinais de Entradas e Saídas

ENTITY Raiz ISGENERIC(byte_width: integer := 8);PORT(

clk,str,rst : IN STD_ULOGIC;A : IN STD_ULOGIC_VECTOR(byte_with-1 downto 0);prt : OUT STD_ULOGIC;S : OUT STD_ULOGIC_VECTOR(byte_with-1 downto 0));

END Raiz;

Variáveis Auxiliares

VARIABLE AUX : STD_ULOGIC_VECTOR(2*byte_width-1 downto 0);VARIABLE AUX_R : STD_ULOGIC_VECTOR(byte_width-1 downto 0);VARIABLE ContMult : INTEGER RANGE 0 TO byte_width+1;

AUX_R – Guardará o resultado da Operação, e os valores intermediários.Variáveis usadas no segundo LAÇO, eleva o número ao Quadrado.

AUX – Guardará o Operador para eleva-lo ao quadrado. Servirá também para guardar o resultado.ContMult – Contador para o LAÇO da Multiplicação. Este LAÇO está dentro do LAÇO Principal.

Valores Iniciais para Variáveis Auxiliares ( reset )

ContMult := byte_width;loopZera:FOR i IN 0 TO byte_width-1 LOOP AUX(i) := '0';

AUX_R(i) := '0';END LOOP loopZera;

Algoritmo principal que será executado dentro do LAÇO Principal

AUX_R := set(AUX_R, (byte_width-1-Contador), '1');

loopZera2:FOR i IN 0 TO byte_width-1 LOOP

AUX(i) := AUX_R(i);END LOOP loopZera2;

loopZera3:FOR i IN byte_width TO (2*byte_width)-1 LOOP

AUX(i) := '0';END LOOP loopZera3;

ContMult := 0;

Page 47: Vhdl

Esse algoritmo será executado a cada pulso de clock depois de começado a operação, conformequantidade de bits dos operadores.

Este Laço coloca ‘0’ na variável ContMult, com isso os próximos pulsos de clocks executaram osegundo LAÇO até o fim, e depois novamente volta a executar o LAÇO Principal.

Algoritmo secundário que será executado dentro do segundo LAÇO

AUX := rot( AUX );

IF get( AUX_R, (byte_width-ContMult) ) = '1' THENAUX := Soma( AUX, AUX_R );

END IF;

IF ContMult = byte_width THENAUX_R := set(AUX_R, (byte_width-1-Contador), intcmp( A, AUX ));Contador := Contador + 1;

END IF;

LAÇO da Multiplicação, é executado dentro de LAÇO Principal. Ex.:

For PRINCIPAL...For MULTIPLICACAO...NEXT

NEXT

Parte Final: Copia o Resultado para a Saída

loopCopy:FOR i IN 0 TO byte_width-1 LOOP

S(i) <= AUX_R(i);END LOOP loopCopy;

Page 48: Vhdl

Forma de Onda dos Sinais de Entrada e Saída ( Raiz Quadrada de 6 bits )

Continuação

Page 49: Vhdl

Conversão de Hexadecimal para Decimal

Este tipo de conversão é muito utilizado, pois os valores medidos são manipulados internamente, porém paraque possa ser representados em mostradores, há a necessidade de converte-los afim de que o operador possainterpretá-los.

Sendo assim o algoritmo consiste em efetuar divisões sucessivas, mantendo o divisor constante igual a 0AH(10D), e o dividendo igual ao quociente obtido anteriormente, teremos o valor em decimal visualizado naseqüências dos restos das divisões.

Abaixo mostramos um exemplo de aplicação do algoritmo para números de 16 Bits.

Resultado è ABCD H = 43.981 D

Para implementar esse algoritmo em VHDL usaremos o esqueleto do programa mostradoanteriormente com uma pequena alteração, porque o LAÇO principal agora é uma LAÇO while ‘Enquanto<condição for satisfeita> Faça’ que executa um LAÇO For...Next aninhado. Pois há o laço de divisão paracada passagem.

Os algarismos serão lidos da direita para esquerda ou do menos significativo para o maissignificativo. Quando o digito estiver pronto na saída o sinal de pronto (prt) será levado a nível lógico alto.

Page 50: Vhdl

Esqueleto do Programa em VHDL contendo dois LAÇO Aninhado (While..For...Next...Wend)

PROCESS (clk)--Declara as variaveis auxiliares

--Contador, servira para controle de passagem--Como dentro de um laço While...For..Next..WendVARIABLE ContFor : INTEGER RANGE 0 TO byte_width+1;VARIABLE CondicaoWhile : STD_ULOGIC;

BEGIN--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

IF rst = '1' THENCondicaoWhile := '1';prt <= '0';ContFor := byte_width;

--Zera variaveis auxiliares e--Copia sinais de entrada para variavies auxiliares, qdo. necessario

ELSEIF str = '1' THEN

IF CondicaoWhile = '1' THENIF ContFor = byte_width THEN

ContFor := 0;--Declaração dos Processos Antes do For..Next

ELSE--Processos dentro do For...Next

ContFor := ContFor + 1;

IF ContFor = byte_width THEN--Processos Executados no fim do LACO For..Next

--Testa o Fim do Laco While...WendIF <Condicao para SAIR do Laço> THEN

CondicaoWhile := '0';END IF;

END IF;

END IF;ELSE

prt <= '1';--Copia o resultado para Saída Apropriada

END IF;END IF;

END IF;END IF;

END PROCESS

Page 51: Vhdl

Sinais de Entradas e Saídas

ENTITY HtoD ISGENERIC(byte_width: integer := 8);PORT(

clk,str,rst : IN STD_ULOGIC;H : IN STD_ULOGIC_VECTOR(byte_with-1 downto 0);prt : OUT STD_ULOGIC;D : OUT STD_ULOGIC_VECTOR(4 downto 0));

END HtoD;

H – Entrada HexadecimalD – Saída Decimal

Variáveis Auxiliares

variáveis usadas no LAÇO da divisãoVARIABLE AUX_Q, AUX_R : STD_ULOGIC_VECTOR(width_byte-1 downto 0);VARIABLE vaiumQuoc, restoMaior : STD_ULOGIC;

AUX_Q - Guardara o Quociente da Operação de DivisãoAUX_R – Guardara o Resto da DivisãovaiumQuoc – Carry, que recebe o bit de maior ordem qdo. rotacionar o Quociente da DivisãorestoMaior – Vai para ‘1’ se o Resto for maior que o Divisor

VARIABLE AUX _H : STD_ULOGIC_VECTOR(2*byte_width-1 downto 0);

AUX_H – Guardará o Dividendo em Hexa .

Valores Iniciais para Variáveis Auxiliares ( reset )

loopIninc:FOR i IN 0 TO byte_width-1 LOOP AUX_H(i) := H(i);END LOOP loopInic;

Copia sinal de entrada em Hexadecimal para uma variável auxiliar.

Page 52: Vhdl

Algoritmo principal que será executado dentro do LAÇO Principal

prt <= '0';

loopZera: -- zera a var. que receberá o resto:FOR i IN 0 TO byte_width-1 LOOP

AUX_R(i) := '0';END LOOP loopZera;

--AUX_Q = "0A";AUX_Q(0) := '0';AUX_Q(1) := '1';AUX_Q(2) := '0';AUX_Q(3) := '1';

vaiumQuoc := '0';restoMaior := '0';

-- AUX_Q - recebe o Dividendo e guardara o Quociente-- AUX_R - zera a variável que recebera o Resto da divisão-- VaiumQuoc, restoMaior - zera variáveis auxiliares

Este Laço (while) é executado no primeiro pulso de clock se a condição for verdadeira, os pulsos declock subsequentes serão executados pelo LAÇO aninhado For...Next, incrementando um na variável quecontrola o LAÇO até o limite especificado. Quando o limite especificado para o LAÇO é alcançado, éexecutado ainda um bloco de verificação da condição inicial que valida o primeiro LAÇO, assim, no próximoclock novamente volta a executar o LAÇO Principal se a condição for verdadeira.

Algoritmo secundário que será executado dentro do segundo LAÇO (Divisão)

--Processos dentro do For...NextvaiumQuoc := AUX_H(byte_width-1);AUX_H := rot( AUX_H );AUX_H(0) := restoMaior;AUX_R := rot( AUX_R );AUX_R(0) := vaiumQuoc;restoMaior := intcmp( AUX_R, AUX_Q );

IF restoMaior = '1' THENAUX_R := Subtracao( AUX_R, AUX_Q );

END IF;

Este laço divide o valor em AUX_H por 10D que está em AUX_Q e coloca o resto em AUX_R e oquociente em AUX_H.

Page 53: Vhdl

Bloco Que Verifica se o Processo já Acabou

Se ainda não acabou, posiciona o resto para ser dividido novamente e assim obter o(s) digito(s) quefalta(m).

--Processos Executados no fim do LACO For..NextAUX_H := rot( AUX_H );AUX_H(0) := restoMaior;

loopSaida:FOR i IN 0 TO 3 LOOP

D(i) <= AUX_R(i);END LOOP loopSaida;

--Testa o Fim do Laco While...WendIF IsZero(AUX_H) = '1' THEN

CondicaoWhile := '0';END IF;

prt <= '1';

A condição que é feita para testar o enquanto é AUX_H = 0, ou seja, quando o quociente da divisãofor zero, não há mas nenhum digito e a operação é encerrada. Caso contrario é processada nova divisão.

Sempre que é obtido um digito o sinal de pronto (prt) é levado a um lógico.

Forma de Onda dos Sinais de Entrada e Saída ( Conversor Hexa para Descimal - 8 bits )

F5H = 245D Leitura é feita do algarismo menos significativo ao mais sgnificativo.

Page 54: Vhdl

Conversor de Decimal para Hexadecimal

Este tipo de conversão embora menos usual que o anterior se torna necessário quando omicrocontrolador recebe dados externos em forma decimal e tem que utilizá-los para cálculos internamente,ora como sua arquitetura apenas suporta manipulações binárias, devemos converter o dado para a basehexadecimal.

O algoritmo consiste em multiplicar cada dígito do dado decimal por uma constante K=Am, onde mserá função do digito em questão como ilustrado abaixo.

(43981) 10 = 4 x A4 + 3 x A3 + 9 x A2 + 8 x A1 + 1 x A0 =

= 4 x 2710 + 3 x 3E8 + 9 x 64 + 8 x A + 1 x 1

= 9C40 + BB8 + 384 + 50 + 1 = (ABCD) 16

Usaremos para implementar este algoritmo uma função de multiplicação, que realiza a multiplicaçãoem um único clock, por questões de simplicidade.

A função que faz a multiplicação foi deixada para ser apresentada por último.Sua sintaxe é:

P := Multiplic( A, B ); -- P = A * B

Sinais de Entradas e Saídas

ENTITY DtoH ISGENERIC(byte_width: integer := 8);PORT(

clk,str,rst : IN STD_ULOGIC;D : IN STD_ULOGIC_VECTOR(4 downto 0);H : OUT STD_ULOGIC_VECTOR(byte_with-1 downto 0));

END DtoH;

D – Entrada DecimalH – Saída Hexadecimal

Variáveis Auxiliares

--Declara as variaveis auxiliaresVARIABLE K, AUX_H, AUX_D, resParc, AUX_0A : STD_ULOGIC_VECTOR(byte_width-1 downto 0);

--K - Constante A elevado a i (i=posicao do digito decimal)--resParc - Resultados Parciais em Hexadecimal.--AUX_D - Espelho da Entrada Decimal D.--AUX_H - Resultado em Hexadecimal--AUX_0A - Contera o valor constante 0AH.

Page 55: Vhdl

Valores Iniciais para Variáveis Auxiliares ( reset )

--Zera variaveis de auxiliares--Copia sinais de entrada para variavies auxiliares, qdo. necessarioloopZera:FOR i IN 0 TO byte_width-1 LOOP K(i) := '0';

resParc(i) := '0';AUX_H(i) := '0';AUX_0A(i) := '0';AUX_D(i) := '0';

END LOOP loopZera;

K(0) := '1';AUX_0A(1) := '1'; -- 1010AUX_0A(3) := '1'; -- 1010

Algoritmo principal que será executado dentro do LAÇO

-- Declaração dos Processos-- Faz o Espelho da Entrada D

AUX_D(3 downto 0) := D;resParc := Multiplic( AUX_D, K );AUX_H := Soma( AUX_H, resParc );K := Multiplic2( K, AUX_0A );

--Copia o resultado para Saída ApropriadaloopCopia:FOR i IN 0 TO byte_width-1 LOOP H(i) <= AUX_H(i);END LOOP loopCopia;

Listagem Completa do Process Para Conversão de Decimal para HexaDecimal

-- Process Statement

Algo_DtoH:PROCESS (clk)

--Declara as variaveis auxiliaresVARIABLE K, AUX_H, AUX_D, resParc, AUX_0A : STD_ULOGIC_VECTOR(byte_width-1

downto 0);

--K - Constante A elevado a i (i=posicao do digito decimal)--resParc - Resultados Parciais em Hexadecimal.--AUX_D - Espelho da Entrada Decimal D.--AUX_H - Resultado em Hexadecimal--AUX_0A - Contera o valor constante 0AH.

BEGIN

Page 56: Vhdl

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN IF rst = '1' THEN --Zera variaveis de auxiliares --Copia sinais de entrada para variavies auxiliares, qdo. necessario LoopZera: FOR i IN 0 TO byte_width-1 LOOP K(i) := '0'; resParc(i) := '0'; AUX_H(i) := '0'; AUX_0A(i) := '0'; AUX_D(i) := '0'; END LOOP loopZera;

K(0) := '1'; AUX_0A(1) := '1'; -- 1010 AUX_0A(3) := '1'; -- 1010ELSE IF str = '1' THEN -- Declaração dos Processos -- Faz o Espelho da Entrada D AUX_D(3 downto 0) := D; resParc := Multiplic( AUX_D, K ); AUX_H := Soma( AUX_H, resParc ); K := Multiplic2( K, AUX_0A ); --Copia o resultado para Saída Apropriada loopCopia: FOR i IN 0 TO byte_width-1 LOOP H(i) <= AUX_H(i); END LOOP loopCopia; END IF;END IF;

END IF;END PROCESS Algo_DtoH;

Forma de Onda dos Sinais de Entrada e Saída ( Conversor Decimal para HexaDecimal )

O sinal H está sendo mostrado na base 10.

Page 57: Vhdl

Função Multiplicação

Recebe como parâmetro duas variáveis STD_ULOGIC_VECTOR e retorna uma variável queconterá o resultado da multiplicação no formato STD_ULOGIC_VECTOR.

----------------------------------------------- S := Mutiplic ( A , B )---------FUNCTION Multiplic ( A : STD_ULOGIC_VECTOR(byte_entrada-1 downto 0);

B : STD_ULOGIC_VECTOR(byte_entrada-1 downto 0) )RETURN STD_ULOGIC_VECTOR IS

VARIABLE S : STD_ULOGIC_VECTOR(byte_saida-1 downto 0);BEGIN

loopZera:FOR i IN 0 TO byte_saida-1 LOOP

S(i) := '0';END LOOP loopZera;

loopMult:FOR i IN 0 TO byte_entrada-1 LOOP

S := rotSaida( S );

IF A( byte_entrada-1 - i ) = '1' THENS := Soma( S, B );

END IF;

END LOOP loopMult;

RETURN S;END Multiplic;

Forma de Onda De uma Chamada a Função S := Multiplic( A, B )

Executa a chamada quando for borda de subida do sinal clk.

Page 58: Vhdl

Exercício:

1) Fazer a descrição em VHDL de uma função que faz a Divisão entre dois sinais e sua chamada. Copilar eSimular.

R.:

Função Divisão

----------------------------------------------- S := Divisao ( A, B )---------FUNCTION Divisao (A, B : STD_ULOGIC_VECTOR(width_byte-1 downto 0)

)RETURN STD_ULOGIC_VECTOR IS

VARIABLE AUX_Q, AUX_R : STD_ULOGIC_VECTOR(width_byte-1 downto 0);VARIABLE Retorno : STD_ULOGIC_VECTOR(2*width_byte-1 downto 0);VARIABLE vaiumQuoc, restoMaior : STD_ULOGIC;

BEGINloopZera:FOR i IN 0 TO width_byte-1 LOOP

AUX_Q(i) := A(i);AUX_R(i) := '0';

END LOOP loopZera;vaiumQuoc := '0';restoMaior := '0';

-- Copia Resultado para sinal de SaidaloopMain:FOR i IN 0 TO width_byte-1 LOOP

vaiumQuoc := AUX_Q(width_byte-1);AUX_Q := rotSaida( AUX_Q );AUX_Q(0) := restoMaior;

AUX_R := rotSaida( AUX_R );AUX_R(0) := vaiumQuoc;restoMaior:= intcmp( AUX_R, B );

IF restoMaior = '1' THENAUX_R := Subtracao( Aux_R, B );

END IF;END LOOP loopMain;

AUX_Q := rotSaida( AUX_Q );AUX_Q(0) := restoMaior;

Retorno(width_byte-1 downto 0) := AUX_Q(width_byte-1 downto 0);Retorno(2*width_byte-1 downto width_byte) := AUX_R(width_byte-1 downto 0);

RETURN Retorno;END Divisao;

Page 59: Vhdl

Chamada a Função Divisão

BEGIN-- Process Statement

Algo_Divi:PROCESS (clk)

--Declara uma variavel auxiliar 'vaium' e svlAi com tipo: STD_ULOGIC--Serão usadas mas adiante no códigoVARIABLE AUX : STD_ULOGIC_VECTOR(2*width_byte-1 downto 0);

BEGIN

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

AUX := Divisao ( A, B );

loopCopy:FOR i IN 0 TO width_byte-1 LOOP

Q(i) <= AUX(i);R(i) <= AUX(width_byte+i);

END LOOP loopCopy;

END IF;

END PROCESS Algo_Divi;

Simulação:

Page 60: Vhdl

Observações

Você pode estar se perguntando porque fazer um algoritmo para multiplicação mais complexo e maislento se como mostrado acima, pode se fazer um mais simples e de execução mais rápido (em um único ciclode clock), enquanto o outro demoraria n ciclos de clock (n: número de bits).

O problema é que executar a multiplicação em um único clock se gasta mais hardware que dividindo-a em vários clocks.

Funções como get e set que pegam um sinal de uma variável vetor, poderiam ser substituídas por:A:=AUX(3) em vez de A := get( AUX, 3 ) e AUX(3) := ‘1’ em vez de AUX := set( AUX, 3, ‘1’).

O problema é quando o argumento 3 é um variável declarada, nesta situação o compilador não aceitao comando e reporta um erro. Talvez outro compilador não apresente problema.

No programa para conversão de Decimal para Hexadecimal é preciso fazer duas chamadas a funçãoMultiplic. Novamente o compilador gerou um erro neste caso e por isso foi gerada duas funções Multiplic eMultiplic2, uma para cada chamada.

Até aqui é suposto que o compilador faça todas as minimizações possíveis para o algoritmoindependente da ordem dos comandos passados, ou seja, que ele utilize o menos de portas lógicas paraexecutar o processo. Assim a chamada da função set comentada acima e sua forma alternativa gastaria omesmo hardware pois executa a mesma função.

Quando foi utilizada uma função no projeto, foi preciso especificar o tamanho dos sinais de entrada.Por exemplo na Multiplicação A e B têm byte_entrada bits. ‘byte_entrada’ é uma constante declarada

dentro da Entidade (inicio do programa).

FUNCTION Multiplic ( A : STD_ULOGIC_VECTOR(byte_entrada-1 downto 0); B : STD_ULOGIC_VECTOR(byte_entrada-1 downto 0)

Foi descrito os Algoritmos para implementar laços numa seqüência de clocks. Pode-se utiliza-lospara converter qualquer algoritmo em laço ou em laços aninhados para resolver o problema comentado acima.

A sintaxe dos comandos são descritos no apêndice A.

O programa completo dos algoritmos descritos acima e seus modelos são listados no apêndice B.

Page 61: Vhdl

VHDLProjeto de Iniciação Científica

Biblioteca Aritmética

Murilo I. [email protected] - 1999

Page 62: Vhdl

PARTE III

Ponto Flutuante..................................................................................................................... 55

PADRÃO DE PONTO-FLUTUANTE IEEE 754............................................................... 56

Variáveis auxiliares.............................................................................................................. 57

Separando os dados de entrada para representação interna.................................................. 57

Soma em Ponto Flutuante (32 bits)...................................................................................... 57

Condições para Adição........................................................................................... 60

Soma de dois números Normalizados.................................................................... 65

Soma de dois números Não-Normalizados............................................................ 68

Retornar a Resultado da Soma em Ponto Flutuante............................................... 69

Multiplicação em Ponto Flutuante (32 bits)......................................................................... 70

Condições para Multiplicação S = A * B............................................................... 72

Função para Regra de Sinal.................................................................................... 73

Simulação: Multiplicação em Ponto Flutuante...................................................... 78

Divisão em Ponto Flutuante (32 bits)................................................................................... 80

Condições para Divisão S = A / B......................................................................... 81

Page 63: Vhdl

PARTE III

Page 64: Vhdl

Ponto Flutuante

Nas partes anteriores deste manual, foi apresentados algoritmos de aritmética com números de pontofixo, ou seja, números inteiros. Incluem aí também números com casas decimais exatas, por exemplo:

A multiplicação 3,02 * 4,04 = 12,20 é equivalente a multiplicação: 302 * 404 = 122008.Dividindo o Resultado 122008 por 10000 e respeitando o limite de duas casas decimais nó

chegaremos no resultado 12,20.

Usando este raciocínio é possível aplicar os algoritmos apresentados até aqui para operando dequantas casa decimais desejar.

O problema aparece quando temos que trabalhar com números com quantidade de casas decimaismuito diferentes, . Por exemplo:

A multiplicação e * c, e = massa do elétron 1,8*10-19; c = velocidade da luz no vácuo 3,8*108.Neste caso a matemática com ponto fixo fica quase impossível, pois teria que alocar espaço em

hardware para representar um número com até oito dígitos a esquerda da virgula e mais 19 dígitos a direita davirgula para cada operando, isso seria um desperdício enorme de hardware.

Quando trabalhamos com esses números usamos a notação cientifica: e = 1,8E-19; c = 3,8E8.Nós chamaremos essa representação de ponto flutuante.

Nós também poderemos mostrar em notação científica números binários. Por exemplo:1,0 * 2-1;1,101 * 2-5;1,xxx * 2yyy

A representação de um ponto flutuante na forma binária está a seguir, onde “s” é o sinal do pontoflutuante (negativo igual a 1), expoente é o valor de 8 bits, e a mantissa é um número de 32 bits.

s y y y y y y y Y x x x x x x x x x X x x x x x x x x x x x x xs – é a representação do sinal ( 0 para positivo e 1 para negativo);yyyyyyyy – expoente de base 2 mais o valor do expoente na base binária ( 127 + expoente );xxxxxxxxxxxxxxxxxxxxxxx –significante, é a parte fracionaria na base dois, sendo que esta é

inserida da esquerda para direita.

Representando assim: 1,xxxxxxxxxxxxxxxxxxxxxxx * 2yyyyyyyy.Este número varia de 1,00 * 2-126 a 1,00 * 2126, usando apenas 32 bits para representa-lo.

A expressão abaixo é utilizada para chegar ao resultado de um número na base dois.(-1) s * ( 1 + Significante ) * 2 E

e também temos uma fórmula genérica que pode ser utilizada:(-1) s * [ 1 + (s1*2-1) + (s2+2-2) + ... ] * 2E

A seguir tem-se um exemplo para transformar um número decimal fracionário (real) no formatocompreendido pelo computador.

-0,75 = -3/4 = -(11)2 * 2 2 = -(0,11)2 normalizando fica: -(1,1)2 * 2-1

(-1) s * ( 1 + Significante ) * 2 (bias+exp) bias = 127

Expoente + 127 = -1 + 127 = 126 :

(-1)1 * ( 1 + ,100 0000 0000 0000 0000 0000 ) * 2 126

1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

2-12-23

-

-126

Este '1' antes da virgula. Érepresentado implicitamente

Page 65: Vhdl

PADRÃO DE PONTO-FLUTUANTE IEEE 754

Item Precisão simples Precisão DuplaBits de Sinal 1 1Bits de expoente 8 11Bits de mantissa 23 52Total de bits 32 64Sistema do expoente Excesso de 127 Excesso de 1023Intervalo do expoente -126 a +127 -1022 a 1023O menor, normalizado 2 -126 2 -1022

O maior, normalizado Aprox. 2 +128 Aprox. 2 +1024

Intervalo decimal Aprox. 10-38 a 10 +38 Aprox. 10 -308 a 10 +308

O menor, não normalizado Aprox. 10 -45 Aprox. 10 -324

Normalizado± 0 < Exp < Max Qualquer padrão de bits

Não-Normalizado± 0 Qualquer padrão de bits Diferente de zero

Zero± 0 0

Infinito± 11111...1 0

Not-a-Number ( Não é um número )± 11111...1 Qualquer padrão de bits diferente de zero

Um dos problemas tradicionais com números em ponto flutuante é como lidar com underflow,overflow e números não-inicializados. O padrão IEEE lida com estes problemas explicitamente, com aabordagem parcialmente do tipo CDC 6600. Além dos números normalizados, o padrão provê quatro outrostipos vistos acima.

Em números não-normalizados, o bit 1 implícito à esquerda do ponto binário agora se torna um 0.Números não-normalizados podem distinguir-se dos normalizados, porque não se permite aos normalizadoster um expoente de 0s.

Dois zeros estão presentes neste esquema, positivo e negativo determinado pelo bit de sinal. Ambospossuem um expoente igual a zero e uma mantissa igual a zero. Aqui também o bit a esquerda do pontobinário é implicitamente 0 em vez de 1.

Quando ocorre um overflow é fornecido uma representação especial para infinito, que consiste emum expoente com todos os bits 1 (não permitido para números normalizados) e uma mantissa igual a zero.Este número pode ser usado como operando que se comporta como as regras matemática usuais de infinito.Por exemplo, infinito mais qualquer coisa é infinito. Similarmente qualquer número dividido por zero dainfinito.

E infinito dividido por infinito ? O resultado é indefinido. Para tratar deste caso usa-se outro formatoespecial, denominado NaN (Not a Number). Este pode também ser tratado como operando com resultadosprevisíveis.

Page 66: Vhdl

Soma em Ponto Flutuante (32 bits)

Operandos de entrada:A, B : IN STD_LOGIC_VECTOR(31 downto 0);

Operandos de Saída:S : OUT STD_LOGIC_VECTOR(31 downto 0));

Bit 31 : bit de sinalBits de 30 à 23 : representam o expoente com excesso de 127Bits de 22 à 0 : representam a mantissa

Variáveis auxiliares

Serão criadas três conjuntos de variáveis para representar internamente um número em ponto flutuante.SinalX : contem o sinal da variável XExpX : contém o expoente da variável XMantX : contém a mantissa de variável X

VARIABLE SinalA, SinalB, SinalR : STD_LOGIC;VARIABLE ExpA, ExpB, ExpR : STD_LOGIC_VECTOR(7 downto 0);VARIABLE MantA, MantB : STD_LOGIC_VECTOR(23 downto 0);VARIABLE MantR : STD_LOGIC_VECTOR(24 downto 0);

Obs: O 25º bit de MantR foi colocado para evitar overflow na soma. Caso este bit for '1' depois de uma soma,desloca-se todos os bits de MantR para direita e soma 1 em ExpR.

Separando os dados de entrada para representação interna

Em primeiro separa o bit de sinal '31', em seguida separamos o expoente, e por último retiramos a mantissa,não esquecendo de verificar se o número é normalizado, '1' no primeiro bit implícito, ou se é não-normalizado, '0' no primeiro bit implícito.

-- Separa os dados de ASinalA := A(31);ExpA(7 downto 0) := A(30 downto 23);-- Explicita sinal implicitoif A(30 downto 23) = "00000000" then

MantA(23) := '0'; -- Numero nao normalizado exp=-126else

MantA(23) := '1'; -- Numero Normalizados 1,xxxend if;MantA(22 downto 0):= A(22 downto 0);

-- Separa os dados de BSinalB := B(31);ExpB(7 downto 0) := B(30 downto 23);if B(30 downto 23) = "00000000" then

MantB(23) := '0';else

MantB(23) := '1';end if;MantB(22 downto 0):= B(22 downto 0);

Page 67: Vhdl

Representação Interna dos Números em Ponto Flutuante

Simulação do algoritmo descrito acima, que pega a entrada (A), que representa um número em pontoflutuante, decompondo-a em três variáveis interna: SinalA, ExpA, MantA, respectivamente: sinal da entrada,seu expoente e sua mantissa.

Esta simulação também vale para a entrada B, sendo que as variáveis serão, SinalB, ExpB e MantB.

Número Normalizado

Número Não-Normalizado

Representação do Zero

ExpA = 10110011MantA =1,11100011100011100011100

A = -1,88888883591 * 2 ^52A ~ -8,5068E15

ExpA = 00000000MantA =0,11100011100011100011100

A = -0,88888883591 * 2 ^ -127A ~ -5,22442E-39

Page 68: Vhdl

Representação Interna dos Números em Ponto Flutuante (Continuação)

Representação de Infinito

Representação de um Not-a-Number

Page 69: Vhdl

Condições para Adição

Condição A B S01 Not-a-Number Qualquer Not-a-Number02 Qualquer Not-a-Number Not-a-Number03 +/- Infinito -/+ Infinito Zero04 Infinito Qualquer A05 Qualquer Infinito B06 Zero Qualquer B07 Qualquer Zero A08 Não-Normalizado Normalizado B09 Normalizado Não-Normalizado A10 Normalizado Normalizado A + B11 Não-Normalizado Não-Normalizado A + B

Testar Condição 01

--Testa se A e NaNif ExpA(7 downto 0) = "11111111" and

not (MantA(22 downto 0) = "00000000000000000000000") then

--A e NaN a saida e NaNSinalR := '0';ExpR := "11111111";MantR := "0111111111111111111111111";

Testar Condição 02

--Testa se B e NaNelsif ExpB(7 downto 0) = "11111111" and

not (MantB(22 downto 0) = "00000000000000000000000") then

--A e NaN a saida e NaNSinalR := '0';ExpR := "11111111";MantR := "0111111111111111111111111";

Page 70: Vhdl

Testar Condição 03

--Testa se A e B são Infinito com sinais trocadoselsif ExpA(7 downto 0) = "11111111" and MantA(22 downto 0) = "00000000000000000000000"and ExpB(7 downto 0) = "11111111" and MantB(22 downto 0) = "00000000000000000000000"and not SinalA = SinalB then

--Saida e Zero, Sinal Adotaremos PositivoSinalR := '0';ExpR := "00000000";MantR := "0000000000000000000000000";

Testar Condição 04

--Testa se A e Infinitoelsif ExpA(7 downto 0) = "11111111" and

MantA(22 downto 0) = "00000000000000000000000" then

--Saida e Infinito com mesmo sinal de ASinalR := SinalA;ExpR := "11111111";MantR := "0000000000000000000000000";

Page 71: Vhdl

Testar Condição 05

--Testa se B e Infinitoelsif ExpB(7 downto 0) = "11111111" and

MantB(22 downto 0) = "00000000000000000000000" then

--Saida e Infinito com mesmo sinal de BSinalR := SinalB;ExpR := "11111111";MantR := "0000000000000000000000000";

Testar Condição 06

--Testa se A e Zeroelsif ExpA(7 downto 0) = "00000000" and

MantA(22 downto 0) = "00000000000000000000000" then

--Saida e BSinalR := SinalB;ExpR := ExpB;MantR(23 downto 0) := MantB;MantR(24) := '0'';

Testar Condição 07

--Testa se B e Zeroelsif ExpB(7 downto 0) = "00000000" and

MantB(22 downto 0) = "00000000000000000000000" then

--Saida e BSinalR := SinalA;ExpR := ExpA;MantR(23 downto 0) := MantA;MantR(24) := '0'';

Page 72: Vhdl

Testar Condição 08

--Testa se A e Não-Normalizado e B Normalizadoelsif ExpA(7 downto 0) = "00000000" and

not ( MantA(22 downto 0) = "00000000000000000000000" ) andnot ( ExpB(7 downto 0) = "00000000" ) then

--Saida e o Normalizado BSinalR := SinalB;ExpR := ExpB;MantR(23 downto 0) := MantB;MantR(24) := '0'';

Testar Condição 09

--Testa se B e Não-Normalizado e A Normalizadoelsif ExpB(7 downto 0) = "00000000" and

not ( MantB(22 downto 0) = "00000000000000000000000" ) andnot ( ExpA(7 downto 0) = "00000000" ) then

--Saida e o Normalizado ASinalR := SinalA;ExpR := ExpA;MantR(23 downto 0) := MantA;MantR(24) := '0'';

Page 73: Vhdl

Testar Condição 10

--Testa se A e B são Normalizadoelsif not ( ExpA(7 downto 0) = "00000000" ) then

--Saida e a soma dos Normalizado A + B

A Soma dos normalizados A + B está descrita mais à abaixo.

Condição 11

--A e B são Não-Normalizado, foi o que restouelse

--Saida e a soma dos Não-Normalizado A + B

A Soma dos não-normalizados A + B está descrita mais à abaixo.

End if; -- Final das condicoes

Page 74: Vhdl

Soma de dois números Normalizados

1º Passo:Igualar os expoentes, permanecendo o expoente maior. Aqui um dos números poderá ficar com o

digito zero a esquerda da virgula ao invés de um. Por isso da importância do bit implícito ser representadoexplicitamente para cálculos interno.

2º Passo:Se os sinais forem iguais somam-se as mantissas, caso contrario, subtrai o menor do maior.O expoente e o sinal será igual ao do maior número. Se o número for igual de sinais trocados, o

resultado será zero.

3º Passo:Normaliza o resultado.

Em VHDL

1º Passo:--ExpA > ExpBif ExpA > ExpB then

--Iguala Expoente de B ao de ALoopIgualaExpB:while ( ExpB < ExpA ) loop

MantB(0 downto 22) := MantB(1 downto 23);MantB(23) := '0';ExpB := ExpB + 1;

end loop LoopIgualaExpB;

else--Iguala Expoente de A ao de B, se já não for igualLoopIgualaExpA:while ( ExpA < ExpB ) loop

MantA(0 downto 22) := MantA(1 downto 23);MantA(23) := '0';ExpA := ExpA + 1;

end loop LoopIgualaExpA;

end if;

2º Passo:if SinalA = SinalB then

MantR := MantA + MantB;SinalR := SinalA;ExpR := ExpA;

elsif MantA > MantB thenMantR := A - B;SinalR := SinalA;ExpR := ExpA;

elsif MantB > MantA thenMantR := B - A;

Page 75: Vhdl

SinalR := SinalB;ExpR := ExpB;

Else --Se são numeros iguais de sinais trocadosSinalR := '1';MantR := "0000000000000000000000000";ExpR := "00000000";

end if;

3º Passo:

Testar o 'bit implícito', o bit que fica à esquerda da virgula, enquanto esse não valer um e o expoentefor diferente de zero, executar os passos descritos abaixo e voltar a testa-lo, até ele se tornar um ou o númerovirar um Não-Normalizado.

Deslocar os bits da mantissa uma posição à esquerda e subtrair uma unidade do expoente.

-- Testa overflowif ( MantR(24) = '1' ) then

MantR(23 downto 0) := MantR(24 downto 1);MantR(24) := '0';ExpR := ExpR + 1;

-- Testa se Foi para Infinitoif ExpR = "11111111" then

MantR := "0100000000000000000000000";end if;

end if;

--Normaliza sinal de saidaloop_Normaliza1:while not ( MantR(23) = '1' or ExpR = "00000000" ) loop

MantR(23 downto 1) := MantR(22 downto 0);MantR(0) := '0';ExpR := ExpR - 1;

end loop loop_Normaliza1;

-- Testa se eh Não-Normalizadoesta e esta proximo ao menor Normalizadoif MantR(23 downto 21) = "111" and ExpR = "00000000" then

--Menor numero normalizadoExpR := "00000001";MantR := "0100000000000000000000000";

end if;

Page 76: Vhdl

Simulação da Soma entre dois Numeros Normalizados

A = 1.03125 * 2-126

B = 1.5 * 2-113

S =1.50012588501 * 2-113

A = +(1+2-1+2-2 ) * 2 (16-127)

B = -(1+2-1+2-3 ) * 2 (16-127)

S = +(1) * 2 (13-127)

A = 2 (16-127)

B = 2 (16-127)

S = 2 (17-127)

Page 77: Vhdl

Soma de dois números Não-Normalizados

1º Passo:Se os sinais forem iguais somam-se as mantissas, caso contrario, subtrai o menor do maior.O sinal será igual ao do maior número. Se o número for igual de sinais trocados, o resultado será

zero.

2º Passo:Se o bit implícito do resultado for igual a um, houve OVERFLOW e o resultado é

NORMALIZADO.

Em VHDL

1º Passo:if SinalA = SinalB then

MantR := MantA + MantB;SinalR := SinalA;

elsif MantA > MantB thenMantR := A - B;SinalR := SinalA;

elsif MantB > MantA thenMantR := B - A;SinalR := SinalB;

else --Se são numeros iguais de sinais trocadosSinalR := '1';MantR := "0000000000000000000000000";

end if;

2º Passo:

-- Testa overflowif ( MantR(24) = '1' ) then

MantR(23 downto 0) := MantR(24 downto 1);MantR(24) := '0';ExpR := "00000001";

end if;

Page 78: Vhdl

Simulação da Soma entre dois Numeros Não-Normalizados

Retornar a Resultado da Soma em Ponto Flutuante

O processo de soma já foi feito, precisamos colocar os dados de nossas variáveis interna para a saída 'S'.

Apenas copiaremos os dados das variáveis para suas respectivas posições na saída 'S'.

S(31) <= SinalR;S(30 downto 23) <= ExpR(7 downto 0);S(22 downto 0) <= MantR(22 downto 0);

E pronto.

A = (2-3 + 2-4 ) * 2-127

B = (2-3 + 2-5 ) * 2-127

S = (2-2 + 2-4 + 2-5 ) * 2-127

A=(2-1+2-2+2-3+2-4+2-5+2-6) * 2-127

B = -(2-1 + 2-5 + 2-6) * 2-127

S = (2-2 + 2-3 + 2-4) * 2-127

A=(2-1+2-2+2-3+2-4+2-5+2-6) * 2-127

B=(2-1+2-2+2-3+2-4+2-5+2-6) * 2-127

S = 2-126

Page 79: Vhdl

Multiplicação em Ponto Flutuante (32 bits)

Implementarémos o algoritmo para multiplicação em ponto flutuante, usando um contador de estadosinternos. No algoritmo anterior, todos os processos erão realizados em um único ciclo de clock. Isto tornou-omuito rápido, porém, consome muitas células lógicas, hardware.

Para usar um contador de estados, dividirémos o algoritmo em blocos, que chamaremos de estado. No final decada bloco, precisamos falar para o contador de estado qual será o próximo estado que será executado nopróximo ciclo de clock. Cada estado é realizado em um ciclo de clock.

Definindo Estados

Type Testado Is (estEspera, -- aguarda sinal str ficar ativoestSeparaDadosA, -- Separa os dados de AestSeparaDadosB, -- Separa os dados de BestTestarCondicao01, --Testa se A e NaNestTestarCondicao02, --Testa se B e NaNestTestarCondicao03, --Testa se A e ZeroestTestarCondicao04, --Testa se B e ZeroestTestarCondicao05, --Testa se A e InfinitoestTestarCondicao06, --Testa se B e InfinitoestSomaExpoente,estTestaUnderflow,estTestaOverflow,estRetira127,estMultMantissa,estNormalizaEsq,estNormalizaDir,estRetornaResultado);

No código usaremos a condição Case…End Case para separarmos os Blocos de Código em Estados.Exemplo:

Case Estado IsWhen Estado01

-- Executa ação para primeiro estado...Estado := Estado 02;

When Estado02...

End Case;

Page 80: Vhdl

Sinais de Entrada e Saída

Usaremos o padrão de interface descrita na parte II deste manual, com três sinais de controle:clk – que será o clock;rst – que será o reset;str – que será o start.

prt – vai para um quando o resultado já estiver pronto para leitura

Operandos de entrada:A, B : IN STD_LOGIC_VECTOR(31 downto 0);

Operandos de Saída:S : OUT STD_LOGIC_VECTOR(31 downto 0));

Bit 31 : bit de sinalBits de 30 à 23 : representam o expoente com excesso de 127Bits de 22 à 0 : representam a mantissa

Variáveis auxiliares

Serão criadas três conjuntos de variáveis para representar internamente um número em ponto flutuante.SinalX : contem o sinal da variável XExpX : contém o expoente da variável XMantX : contém a mantissa de variável X

VARIABLE SinalA, SinalB, SinalR : STD_LOGIC;VARIABLE ExpA, ExpB : STD_LOGIC_VECTOR(7 downto 0);VARIABLE ExpR : STD_LOGIC_VECTOR(8 downto 0); -- Para Teste de overflowVARIABLE MantA, MantB : STD_LOGIC_VECTOR(23 downto 0);VARIABLE MantR : STD_LOGIC_VECTOR(47 downto 0);VARIABLE Estado : TEstado;

Obs: Forão colocados o dobro de bits em MantR para evitar overflow na multiplicação.

Esqueleto do Algoritimo para Controle dos Estados

--Só executar a soma se clk for borda de subidaIF clk'EVENT AND clk = '1' THEN

IF rst = '1' THENEstado := estEspera; -- Proximo estadoprt <= ‘0’;

ELSECase Estado IsWhen estEspera =>

IF str = '1' THENEstado := estSeparaDadosA; -- Proximo estado

END IF;

When …When …When …End Case;

END IF;END IF;

Page 81: Vhdl

Separando os dados de entrada para representação interna

Em primeiro separa o bit de sinal '31', em seguida separamos o expoente, e por último retiramos a mantissa,não esquecendo de verificar se o número é normalizado, '1' no primeiro bit implícito, ou se é não-normalizado, '0' no promeiro bit implícito.

When estSeparaDadosA =>-- Separa os dados de ASinalA := A(31);ExpA(7 downto 0) := A(30 downto 23);-- Explicita sinal implicitoif A(30 downto 23) = "00000000" then

MantA(23) := '0'; -- Numero nao normalizado exp=-126else

MantA(23) := '1'; -- Numero Normalizados 1,xxxend if;MantA(22 downto 0):= A(22 downto 0);Estado := estSeparaDadosB; -- Proximo estado

When estSeparaDadosB =>-- Separa os dados de BSinalB := B(31);ExpB(7 downto 0) := B(30 downto 23);if B(30 downto 23) = "00000000" then

MantB(23) := '0';else

MantB(23) := '1';end if;MantB(22 downto 0):= B(22 downto 0);Estado := estTestarCondicao01; -- Proximo estado

Condições para Multiplicação S = A * B

Condição A B S01 Not-a-Number Qualquer Not-a-Number02 Qualquer Not-a-Number Not-a-Number03 Zero Quaquer Zero04 Qualquer Zero Zero05 Infinito Qualquer R.S. Infinito06 Qualquer Infinio R.S. Infinito07 Não-Normalizado ou

NormalizadoNão-Normalizado ouNormalizado

R.S.Soma os ExpoentesMultipl. Mantissa

R.S. = Regra de Sinal

Page 82: Vhdl

Função para Regra de Sinal

FUNCTION RegraSinal ( SinalA : STD_ULOGIC; SinalB : STD_ULOGIC

)RETURN STD_ULOGIC IsVARIABLE Sinal : STD_ULOGIC;

BEGINIF SinalA = SinalB THEN

Sinal := '0'; -- POSITIVOELSE

Sinal := '1'; -- NEGATIVOEND IF;

RETURN Sinal;END RegraSinal;

Testar Condição 01

When estTestarCondicao01 =>--Testa se A e NaNif ExpA(7 downto 0) = "11111111" and

not (MantA(22 downto 0) = "00000000000000000000000") then

--A e NaN a saida e NaNExpR := "011111111";MantR := "011111111111111111111111100000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao02; -- Proximo estado

end if;

Page 83: Vhdl

Testar Condição 02

When estTestarCondicao02 =>--Testa se B e NaNif ExpB(7 downto 0) = "11111111" and

not (MantB(22 downto 0) = "00000000000000000000000") then

--A e NaN a saida e NaNExpR := "011111111";MantR := "001111111111111111111111110000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao03; -- Proximo estado

end if;

Testar Condição 03

When estTestarCondicao03 =>--Testa se A e Zeroif ExpA(7 downto 0) = "00000000" and

MantA(22 downto 0) = "00000000000000000000000" then

--Saida e ZeroExpR := "000000000";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao04; -- Proximo estado

end if;

Page 84: Vhdl

Testar Condição 04

When estTestarCondicao04 =>--Testa se B e Zeroif ExpB(7 downto 0) = "00000000" and

MantB(22 downto 0) = "00000000000000000000000" then

--Saida e ZeroExpR := "000000000";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao05; -- Proximo estado

end if;

Testar Condição 05

When estTestarCondicao05 =>--Testa se A e Infinitoif ExpA(7 downto 0) = "11111111" and

MantA(22 downto 0) = "00000000000000000000000" then

--Saida e InfinitoExpR := "011111111";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao06; -- Proximo estado

end if;

Page 85: Vhdl

Testar Condição 06

When estTestarCondicao06 =>--Testa se B e Infinitoif ExpB(7 downto 0) = "11111111" and

MantB(22 downto 0) = "00000000000000000000000" then

--Saida e InfinitoExpR := "011111111";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estSomaExpoente; -- Proximo estado

end if;

Condição 07

When estSomaExpoente =>--Soma expoenteExpR := ExpA + ExpB;Estado := estTestaUnderflow; -- Proximo estado

When estTestaUnderflow =>--Testa underflowIf ExpR < 127 then

--Saida e ZeroExpR := "000000000";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestaOverflow; -- Proximo estado

end if;

Page 86: Vhdl

When estTestaOverflow =>-- Testa Overflowif ExpR > 382 then

--Saida e InfinitoExpR := "011111111";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estRetira127; -- Proximo estado

end if;

When estRetira127 =>-- A + 127 + B + 127 = R + 254-- Retira 127ExpR := ExpR - 127;Estado := estMultMantissa; -- Proximo estado

When estMultMantissa =>-- Multiplica Mantissa A(24) * B(24) = R(48)MantR := MantA * MantB;Estado := estNormalizaEsq; -- Proximo estado

When estNormalizaEsq =>--Normaliza sinal de saida--Verif. o segundo bit a esquerda da virgulaif MantR(47) = '1' then

-- Verifica overflowif ExpR = "1111111110" then

--Saida e InfinitoExpR := "011111111";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseMantR(46 downto 0) := MantR(47 downto 1);MantR(47) := '0';ExpR := ExpR + 1;

End if;End if;Estado := estNormalizaDir; -- Proximo estado

When estNormalizaDir =>--Verif. o primeiro bit a esquerda da virgulaloop_Normaliza1:

Page 87: Vhdl

while not ( MantR(46) = '1' or ExpR = "000000000" ) loopMantR(46 downto 1) := MantR(45 downto 0);MantR(0) := '0';ExpR := ExpR - 1;

end loop loop_Normaliza1;Estado := estRetornaResultado; -- Proximo estado

Retornar o Resultado da Multiplicação em Ponto Flutuante

O processo de soma já foi feito, precisamos colocar os dados de nossas variáveis interna para a saída 'S'.

Apenas copiaremos os dados das variáveis para suas respectivas posições na saída 'S'.

When estRetornaResultado =>S(31) <= RegraSinal (SinalA, SinalB );S(30 downto 23) <= ExpR(7 downto 0);S(22 downto 0) <= MantR(45 downto 23);prt <= ‘1’;Estado := estEspera; -- Proximo estado

E pronto.

Simulação: Multiplicação em Ponto Flutuante

A = -1,75 * 2

B = -1,75 * 2

S = A * B = 1,53125 * 23

S = (1+ 2-1 + 2-5) * 23

A = (1 + 2-1 + 2-2) * 2(2^7 + 2^6 - 127)

B = (1 + 2-1 + 2-2) * 2(2^7 - 127)

S= A * BS = (1+2-1 + 2-5) * 2(2^7 + 2^6 + 2^1- 127)

Page 88: Vhdl

Simulação: Multiplicação em Ponto Flutuante (continuação)

Multiplicação entre um número não-normalizado e outro normalizado, gerando o resultado, um númeronormalizado:

Multiplicação entre um número não-normalizado e outro normalizado, dando como resultado um número não-normalizado:

Caso especial: Multiplicação entre um número não-normalizado e outro normalizado, dando como resultadoum número entre o menor normalizado e o maior não-normalizado, neste caso foi arredondado:

A = (2-1 + 2-2) * 2-127

B = (1 + 2-1 + 2-2) * 2(192-127)

S = (1 + 2-2 + 2-4) * 2(65-127)

Page 89: Vhdl

Divisão em Ponto Flutuante (32 bits)

Implementarémos o algoritmo para divisão em ponto flutuante, usando um contador de estados internos,conforme usado no algoritmo anterior.

A estrutura usada anteriormente será aproveitada, mudando apenas alguns estados e algumas variáveis,descritos abaixo:

Definindo Estados

Type Testado Is (estEspera, -- aguarda sinal str ficar ativoestSeparaDadosA, -- Separa os dados de AestSeparaDadosB, -- Separa os dados de BestTestarCondicao01, --Testa se A e ZeroestTestarCondicao02e03, --Testa se A e NaN ou B e NaNestTestarCondicao04, --Testa se B e ZeroestTestarCondicao05, --Testa se A = BestTestarCondicao06, --Testa se A e InfinitoestSoma127, --Soma 127 ao Resultado antes de Subtrair por BestTestaUnderflow, --se (ExpA+127) >= ExpB, caso negativo UnderflowestSubtraiExpoente, -- Subtrai expoenteestTestaOverflow, -- Testa OverflowestDivMantissa, --Divide Mantissa A(24) / B(24) = R(24)estDivMantissa01,estSomaExpDivisao, -- Soma expoente da divisao com ExpRestTestaOverflowDivisao, -- Testa OverflowestNormalizaDir, --Verif. o primeiro bit a esquerda da virgulaestRetornaResultado);

Sinais de Entrada e Saída

Os sinais de controle permanecem iguais:clk – que será o clock;rst – que será o reset;str – que será o start.

prt – vai para um quando o resultado já estiver pronto para leitura

Operandos de entrada:A, B : IN STD_LOGIC_VECTOR(31 downto 0);

Operandos de Saída:S : OUT STD_LOGIC_VECTOR(31 downto 0));

Bit 31 : bit de sinalBits de 30 à 23 : representam o expoente com excesso de 127Bits de 22 à 0 : representam a mantissa

Variáveis auxiliares

Serão criadas três conjuntos de variáveis para representar internamente um número em ponto flutuante.SinalX : contem o sinal da variável XExpX : contém o expoente da variável X

Page 90: Vhdl

MantX : contém a mantissa de variável X

VARIABLE SinalA, SinalB, SinalR : STD_LOGIC;VARIABLE ExpA, ExpB : STD_LOGIC_VECTOR(7 downto 0);VARIABLE ExpR : STD_LOGIC_VECTOR(8 downto 0); -- Para Teste de overflowVARIABLE MantA, MantB : STD_LOGIC_VECTOR(23 downto 0);VARIABLE MantR : STD_LOGIC_VECTOR(24 downto 0);VARIABLE Estado : TEstado;

--Variaveis auxiliares para DivisaoVARIABLE Dividendo : STD_LOGIC_VECTOR(23 downto 0);VARIABLE PosVirgula : STD_LOGIC_VECTOR(8 downto 0);VARIABLE ContDiv : STD_LOGIC_VECTOR(8 downto 0);

Obs: Forão colocados o dobro de bits em MantR para evitar overflow na multiplicação.

Condições para Divisão S = A / B

Condição A B S01 Zero Qualquer Zero02 Not-a-Number Qualquer Not-a-Number03 Qualquer Not-a-Number Not-a-Number04 Qualquer Zero R.S. Infinito05 A = B R.S. Um06 Infinito Qualquer R.S. Infinito07 Qualquer Infinito R.S. Zero08 Não-Normalizado ou

NormalizadoNão-Normalizado ouNormalizado

R.S.Subtrai ExpoentesDivide Mantissa

R.S. = Regra de Sinal

A função para calcular a Regra de Sinal, é a mesma descrita na multiplicação.

Testar Condição 01

When estTestarCondicao01 =>--Testa se A e Zeroif ExpA(7 downto 0) = "00000000" and

MantA(22 downto 0) = "00000000000000000000000" then

--Saida e ZeroExpR := "000000000";MantR := "0000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao02e03; -- Proximo estado

end if;

Page 91: Vhdl

Testar Condição 02 e 03

When estTestarCondicao02e03 =>--Testa se A e NaN ou B e NaNif (ExpA(7 downto 0) = "11111111" and

not (MantA(22 downto 0) = "00000000000000000000000")) or (ExpB(7 downto 0) = "11111111" and

not (MantB(22 downto 0) = "00000000000000000000000"))then

--A ou B e NaN a saida e NaNExpR := "011111111";MantR := "0000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao04; -- Proximo estado

end if;

Testar Condição 04

When estTestarCondicao04 =>--Testa se B e Zeroif ExpB(7 downto 0) = "00000000" and

MantB(22 downto 0) = "00000000000000000000000" then

--Saida e Infinito

Page 92: Vhdl

ExpR := "011111111";MantR := "0000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao05; -- Proximo estado

end if;

Testar Condição 05

When estTestarCondicao05 =>--Testa se A = Bif (ExpA(7 downto 0) = ExpB(7 downto 0)) and

(MantA(22 downto 0) = MantB(22 downto 0)) then

--Saida e HumExpR := "001111111";MantR := "0100000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estTestarCondicao06; -- Proximo estado

end if;

Testar Condição 06

When estTestarCondicao06 =>--Testa se A e Infinitoif ExpA(7 downto 0) = "11111111" and

MantA(22 downto 0) = "00000000000000000000000" then

--Saida e InfinitoExpR := "011111111";MantR := "0000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

else

Page 93: Vhdl

Estado := estSoma127; -- Proximo estado

end if;

Condição 07

When estSoma127 =>--Soma 127 ao Resultado antes de Subtrair por B--R = A + 127ExpR := ExpA + 127;Estado := estTestaUnderflow; -- Proximo estado

When estTestaUnderflow =>--Testa se (ExpA+127) >= ExpB, caso negativo UnderflowIf ExpR < ExpB then

--Saida e ZeroExpR := "000000000";MantR := "0000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estSubtraiExpoente; -- Proximo estado

end if;

When estSubtraiExpoente =>-- Subtrai expoenteExpR := ExpR - ExpB;Estado := estTestaOverflow; -- Proximo estado

When estTestaOverflow =>-- Testa Overflowif ExpR > 255 then

--Saida e InfinitoExpR := "011111111";MantR := "0000000000000000000000000";

Page 94: Vhdl

Estado := estRetornaResultado; -- Proximo estado

elseEstado := estDivMantissa; -- Proximo estado

end if;

When estDivMantissa =>--Divide Mantissa A(24) / B(24) = R(24)--MantR := MantA / MantB

Dividendo:= MantA;Divisor:= MantB;MantR:= "0000000000000000000000000";PosVirgula := "000000000";;ContDiv:= "000000000";;Estado := estDivMantissa01; -- Proximo estado

When estDivMantissa01 =>

while (ContDiv<24 and not Dividendo=0)If Dividendo >= MantB then

MantR(24-ContDiv) := '1';Dividendo := Dividendo - MantB;ContDiv := ContDiv + 1;

elseIf PosVirgula = 0 then

PosVirgula := ContDiv + 1;else

MantR(24-ContDiv) := '0';ContDiv := ContDiv + 1;

end if;Dividendo (23 downto 1) := Dividendo(22 downto 0);Dividendo (0) := '0';

end if;wend;If PosVirgula = 0 then

PosVirgula := ContDiv + 1;end if;

Estado := estSomaExpDivisao; -- Proximo estado

When estSomaExpDivisao =>-- Soma expoente da divisao com ExpRExpR:= > ExpR + PosVirgula -1;Estado := estTestaOverflowDivisao; -- Proximo estado

Page 95: Vhdl

When estTestaOverflowDivisao =>-- Testa Overflowif ExpR > 255 then

--Saida e InfinitoExpR := "011111111";MantR := "000000000000000000000000000000000000000000000000";Estado := estRetornaResultado; -- Proximo estado

elseEstado := estNormalizaDir; -- Proximo estado

end if;

When estNormalizaDir =>--Verif. o primeiro bit a esquerda da virgulaloop_Normaliza1:while not ( MantR(24) = '1' or ExpR = "000000000" ) loop

MantR(24 downto 1) := MantR(23 downto 0);MantR(0) := '0';ExpR := ExpR - 1;

end loop loop_Normaliza1;Estado := estRetornaResultado; -- Proximo estado

When estRetornaResultado =>S(31) <= RegraSinal (SinalA, SinalB );S(30 downto 23) <= ExpR(7 downto 0);S(22 downto 0) <= MantR(22 downto 0);prt <= ‘1’;Estado := estEspera; -- Proximo estado

E pronto.