Você está na página 1de 57

UNIVERSIDADE POSITIVO

NÚCLEO DE CIÊNCIAS EXATAS E TECNOLÓGICAS


CURSO DE ENGENHARIA DA COMPUTAÇÃO

ANSELMO FERREIRA BITTENCOURT


FLÁVIA HERRMANN MENEZES

Ferramenta de Edição e Tradução de


Equações Matemáticas para VHDL

Trabalho de Conclusão de Curso.

Prof. Valfredo Pilla Junior


Orientador

Curitiba, Novembro de 2011


UNIVERSIDADE POSITIVO
Reitor: José Pio Martins
Pró-Reitor de Administração: Arno Antonio Gnoatto
Pró-Reitora Acadêmica: Márcia Sebastiani
Coordenador do Curso de Engenharia da Computação: Leandro Henrique de
Souza

iii
RESUMO

A maioria dos sistemas e processos conhecidos pode ser descrita por meio de equações
matemáticas e muitas dessas equações podem ser obtidas e aplicadas fisicamente por
meio de circuitos eletrônicos. O projeto desenvolvido trata-se de um ambiente para
representação de equações matemáticas em hardware digital reconfigurável para
aplicações em sistemas embarcados. O sistema assim desenvolvido pode ser utilizado
em inúmeras áreas, como processamento de sinais, automação, entre outras. O trabalho
consiste em uma ferramenta de Edição e Tradução de equações matemáticas para
VHDL, a qual analisa uma equação matemática e obtêm a sua representação em
linguagem VHDL, sendo esta representação utilizada para a síntese das equações em
circuitos eletrônicos. O resultado alcançado pelo desenvolvimento proporciona rapidez
na obtenção de código VHDL. Para a utilização do programa é necessário um
computador pessoal, uma interface de comunicação USB e um dispositivo lógico
programável. O código gerado deve ser utilizado em um ambiente de descrição de
circuitos lógicos com suporte à linguagem VHDL. Neste projeto foi utilizado o
ambiente de desenvolvimento Quartus® II, da Altera®, por meio do qual é gerado o
código-objeto que é gravado em CPLD ou FPGA. Os dados são enviados e recebidos do
computador por comunicação serial para a interface de comunicação, que envia e recebe
dados do kit de lógica programável de forma paralela. O software de tradução recebe
uma equação matemática constituída por funções do tipo exponencial, trigonométrica,
além de operações básicas como adição, subtração, multiplicação e divisão, que podem
ser agrupadas de acordo com as regras e então analisa a expressão, verificando os
operadores e as variáveis, quebrando as expressões para depois montar em código, de
acordo com a precedência das operações. Após a geração do código, podemos efetuar a
gravação na FPGA, para realização dos testes por meio da interface de testes, para poder
verificar a eficiência do sistema de acordo com a aplicação a ser desenvolvida.
Pretende-se, assim, facilitar o projeto de circuitos digitais utilizando a linguagem VHDL
e proporcionando uma forma rápida de se obter circuitos digitais correspondentes a
funções matemáticas, automatizar parte do processo de geração de código e ampliar a
aplicação da lógica programável nos mais diversos sistemas.

Palavras-chave: Tradutor de Equações Matemáticas para VHDL, Sistemas


Embarcados, Coprocessadores.

v
ABSTRACT

The most of the known systems and process can be described using mathematical
equations and many of these equations can be obtained and applied physically using
electronic circuits. The developed project is an environment for representation of
mathematical equations on reconfigurable digital hardware for embedded systems
applications. The system thus developed can be used at numerous areas, as signal
processing, automation, and others. The work consists of a tool for editing and
translation of mathematical equations to VHDL, which analyzes a mathematical
equation and achieve its representation in VHDL language, this representation being
used for the synthesis of the equations in electronic circuits. The result reached by the
development provides quick obtaining VHDL code. To use the program, a personal
computer, an USB communication interface and a programmable logic device are
needed. The generated code should be used in an environment of logic circuits
description with support for VHDL. In this project, the development environment used
was the Quartus® II, Altera®, through which is generated object code which is written
in CPLD or FPGA. The data is sent and received from the computer by serial
communication using the communication interface, which sends and receives data from
the kit of programmable logic in parallel. The translation software receives a
mathematical equation consisting of exponential functions, trigonometry, and basic
operations such as addition, subtraction, multiplication and division, which can be
grouped according to the rules, and then analyzes the expression and checking operators
and variables, and then breaking the expressions, building it in code after that,
according to the precedence of operations. After code generation, recording in the
FPGA can be made to perform the tests using the testing interface, in order to verify the
efficiency of the system according to the application being developed. It is intended,
thus facilitating the design of digital circuits using VHDL language and providing a
quick way to get digital circuits corresponding mathematical functions, automate part of
the code generation to expand the application of programmable logic in various
systems.

Keywords: Mathematical Equations to VHDL Translator, Embedded Systems,


Co-processors.

vii
LISTA DE ABREVIATURAS E SIGLAS

CPLD – Complex Programmable Logic Device (Dispositivo Lógico Complexo


Programável)
FPGA – Field Programmable Gate Array (Arranjo de Portas Programável em Campo)
GB - Gigabyte
HD – Hard Disk (Disco Rígido)
LSB – Least Significant Bit (Bit Menos Significativo)
MB - Megabyte
MSB – Most Significant Bit (Bit Mais Significativo)
RAM – Random Access Memory (Memória de Acesso Aleatório)
VHDL – VHSIC Hardware Description Language (Linguagem de Descrição de
Hardware VHSIC)
VHSIC – Very High Speed Integrated Circuits (Circuitos Integrados de Velocidade
Muito Alta)

ix
LISTA DE FIGURAS

Figura 3.1: Arquitetura do Projeto.................................................................................... 8


Figura 3.2: Software de tradução ...................................................................................... 8
Figura 3.3: Software de testes........................................................................................... 9
Figura 3.4: Diagrama de hardware ................................................................................. 10
Figura 3.5: Diagrama de firmware ................................................................................. 10
Figura 3.6: Testes do módulo de comunicação .............................................................. 11
Figura 4.1: Tradutor: inserção da equação ..................................................................... 13
Figura 4.2: Tradutor: código correspondente à equação inserida ................................... 14
Figura 4.3: Software de testes......................................................................................... 18
Figura 4.4: Software de testes com resultados ............................................................... 18
Figura 4.5: Módulo de controle ...................................................................................... 19
Figura 4.6: Módulo de escrita ......................................................................................... 20
Figura 4.7: Módulo de leitura ......................................................................................... 20
Figura 4.8: Kit Altera DE2 ............................................................................................. 21

xi
LISTA DE TABELAS

Tabela 2.1: Representação de ponto flutuante IEEE 754 ................................................. 4


Tabela 3.1: Cronograma inicial do projeto ..................................................................... 12
Tabela 4.1: Resultados para o cálculo do seno ............................................................... 16
Tabela 4.2: Parte 1 – Resultados para o cálculo do cosseno .......................................... 16
Tabela 4.2: Parte 2 – Resultados para o cálculo do cosseno .......................................... 17
Tabela 4.3: Resultados para o cálculo da tangente ......................................................... 17
Tabela 4.4: Resultados para o cálculo da função exponencial ....................................... 17

xiii
SUMÁRIO

RESUMO ...................................................................................................... V

ABSTRACT ................................................................................................ VII

LISTA DE ABREVIATURAS E SIGLAS ...................................................... IX

LISTA DE FIGURAS .................................................................................... XI

LISTA DE TABELAS ................................................................................. XIII

1. INTRODUÇÃO AO PROJETO ............................................................ 1

1.1 Circuitos de Lógica Programável ........................................................................................... 1

1.2 Objetivos .................................................................................................................................. 2

2. REVISÃO BIBLIOGRÁFICA ............................................................... 3

2.1 Funções Trigonométricas e Exponencial ............................................................................... 3

2.1.1 Séries de Taylor .................................................................................................................. 3

2.2 Representação Numérica ........................................................................................................ 4

3. PROJETO ............................................................................................ 7

3.1 Requisitos ................................................................................................................................. 7

3.2 Arquitetura .............................................................................................................................. 7

3.2.1 Software ............................................................................................................................... 8

3.2.2 Hardware............................................................................................................................. 9

3.3 Testes do Sistema ................................................................................................................... 10

3.4 Planejamento do Projeto ....................................................................................................... 11

3.4.1 Recursos............................................................................................................................. 11

3.4.2 Cronograma ...................................................................................................................... 12

4. RESULTADOS .................................................................................. 13

xv
4.1 Software.................................................................................................................................. 13

4.1.1 Software de Tradução ...................................................................................................... 13

4.1.2 Software de Testes ............................................................................................................ 18

4.2. Hardware..................................................................................................................................... 18

5. CONCLUSÃO ......................................................................................... 22

6. REFERÊNCIAS....................................................................................... 23

ANEXO A: CÓDIGO VHDL DA FUNÇÃO SENO ....................................... 25

ANEXO B: CÓDIGO VHDL DA FUNÇÃO COSSENO ............................... 27

ANEXO C: CÓDIGO VHDL DA FUNÇÃO TANGENTE ............................. 29

ANEXO D: CÓDIGO VHDL DA FUNÇÃO EXPONENCIAL ....................... 31

ANEXO E: CÓDIGO VHDL DA OPERAÇÃO DE ADIÇÃO ........................ 33

ANEXO F: CÓDIGO VHDL DA OPERAÇÃO DE SUBTRAÇÃO ............... 35

ANEXO G: CÓDIGO VHDL DA OPERAÇÃO DE MULTIPLICAÇÃO ........ 37

ANEXO H: CÓDIGO VHDL DA OPERAÇÃO DE DIVISÃO ....................... 39

ANEXO I: CÓDIGO VHDL DA OPERAÇÃO DE POTENCIAÇÃO ............. 41

xvi
1

1. INTRODUÇÃO AO PROJETO

A aplicação da eletrônica para o controle de processos e sistemas tem se tornado


cada vez mais freqüente e necessária em diversas áreas do conhecimento humano. Com
a constante evolução tecnológica, é cada vez maior a capacidade de se controlar ações e
fenômenos, antes feitos ou produzidos de forma manual ou natural, e agora
reproduzíveis e dirigidos de acordo com a necessidade das aplicações. Da mesma
forma, a complexidade destes sistemas tem crescido e, muitas vezes, é um obstáculo
difícil de ser superado quando se utilizam formas convencionais para projeção dos
circuitos eletrônicos necessários.
O surgimento da eletrônica digital e, mais tarde, dos circuitos de lógica
programável, contribuiu para a melhoria dos processos e da construção dos sistemas de
controle, mas ainda assim, projetar estes tipos de sistema continua sendo uma tarefa
trabalhosa, exigindo um alto nível de conhecimento técnico, tanto em eletrônica digital
quanto em linguagem para descrição dos circuitos de lógica programável.
Dessa forma, possuir uma ferramenta capaz de auxiliar o desenvolvimento de
sistemas que se utilizem da lógica programável, por meio da automatização de parte do
processo de projeto destes circuitos, é de grande utilidade, uma vez que isto contribui
para redução de tempo e custos dos projetos, e torna mais prática a execução e
manutenção dos mesmos.
O objetivo deste trabalho é desenvolver uma ferramenta que, dada uma equação
matemática, forneça o código VHDL correspondente a essa equação, a fim de que este
código seja compilado e utilizado em CPLDs ou FPGAs, que neste caso podem ser
utilizados como coprocessadores matemáticos para diversas aplicações.

1.1 Circuitos de Lógica Programável


A aplicação de sistemas que tem por base a lógica digital programável tem se
tornado cada vez mais ampla. Podemos encontrá-los em filtros digitais, sistemas de
controle, sistemas automotivos, nas telecomunicações, equipamentos de simulação e
teste, entre outros.
Essa disseminação ocorre por vários fatores (DAMORE, 2005), entre os quais:
a) Ausência de um sistema operacional e consequentemente inexistência de processos
concorrentes disputando os recursos de um processador;
b) Possibilidade de alteração das funcionalidades do circuito sem a necessidade de
substituição de componentes;
c) Alta velocidade de processamento, que depende apenas da velocidade (clock) do
chip e não de uma série de cálculos de um processador;
2

d) Proteção da propriedade intelectual, uma vez que não é possível obter o código-
fonte gravado no chip;
e) Baixo custo e economia de energia com a produção em larga escala (utilização de
ASICs).
Infelizmente, projetar um circuito digital para tais aplicações nem sempre é uma
tarefa fácil, pois exige conhecimento de circuitos e linguagem de descrição de hardware.
Além disso, quanto mais complexo um sistema, maior e mais trabalhosa a composição
do código equivalente.
Por isso, a necessidade de uma ferramenta capaz de automatizar a geração de código
em linguagem apropriada, que seja capaz de sintetizar circuitos já conhecidos e compor
circuitos complexos por meio da junção de circuitos menores.

1.2 Objetivos
Os A seguir são descritos os objetivos do projeto:
a) Desenvolver ferramenta de captura de equações matemáticas;
b) Gerar código VHDL correspondente à descrição dos circuitos para os seguintes
cálculos:
(i) Soma e subtração;
(ii) Multiplicação e divisão;
(iii)Potenciação;
(iv) Seno, Cosseno e Tangente;
(v) Função exponencial;
c) Analisar a equação inserida e fazer a tradução para código VHDL, utilizando um ou
mais dos circuitos citados no item anterior;
d) Utilizar uma ferramenta já existente para compilação do código gerado e gravação
no dispositivo de lógica programável;
e) Desenvolver uma interface de hardware para testes do código gravado no
dispositivo, com as seguintes funções:
(i) Receber do computador os valores de entrada das funções;
(ii) Transmitir os valores ao dispositivo de lógica programável;
(iii)Receber os resultados do dispositivo e transmiti-los ao computador;
f) Desenvolver uma interface de software para testes, com as seguintes funções:
(i) Comunicação de dados com dispositivo de hardware citado no item anterior;
(ii) Comparação dos valores recebidos com os valores esperados para as funções
utilizadas.
3

2. REVISÃO BIBLIOGRÁFICA

Existem outros projetos nos quais o objetivo é transformar equações matemáticas


em código VHDL. Um deles, chamado FELIX, utiliza diversos recursos para a
simplificação das expressões matemáticas, além da reescrita da expressão em linguagem
C++ para posterior geração do código VHDL (MORRA, 2005), o que torna a
abordagem bastante complexa e difere da utilizada na ferramenta aqui desenvolvida.

2.1 Funções Trigonométricas e Exponencial


Funções trigonométricas são utilizadas no estudo de triângulos e na modelagem de
fenômenos descritos por sinais periódicos, enquanto a função exponencial é utilizada
quando o valor de uma função cresce ou decresce muito rapidamente, sendo a alteração
do valor na variável dependente sempre proporcional, em termos percentuais, ao da
variável independente.
As funções trigonométricas seno, cosseno e tangente, assim como a função
exponencial são desenvolvidas neste trabalho por meio da utilização das Séries de
Taylor.

2.1.1 Séries de Taylor


A Série de Taylor ou Série de Potências é uma série de funções na forma
𝑓 (𝑛) (𝑎)
𝑓(𝑥) = ∑∞ 𝑛
𝑛=0 𝑎𝑛 (𝑥 − 𝑎) , na qual 𝑎𝑛 = .
𝑛!
Nesta função, se a = 0, a série também é chamada de Série de Maclaurin
(SWOKOWSKI, 1995; WIKIPEDIA, 2011).
As funções desenvolvidas neste trabalho e suas respectivas séries são vistas abaixo.
(−1)𝑛
𝑠𝑒𝑛(𝑥) = ∑∞
𝑛=0 (2𝑛+1)! 𝑥
2𝑛+1
Equação 2.1

(−1)𝑛
𝑐𝑜𝑠(𝑥) = ∑∞
𝑛=0 (2𝑛)!
𝑥 2𝑛 Equação 2.2

𝐵2𝑛 (−4)𝑛 (1−4𝑛 )


𝑡𝑎𝑛(𝑥) = ∑∞
𝑛=1 (2𝑛)!
𝑥 2𝑛−1 Equação 2.3

𝑥𝑛
𝑒 𝑥 = ∑∞
𝑛=0 Equação 2.4
𝑛!
4

Por se tratarem de funções com infinitos termos e, portanto, impossíveis de serem


representadas como são descritas, estas foram adaptadas, para que o número de termos
pudesse ser minimizado, alcançando resultados satisfatórios.

2.2 Representação Numérica


A forma de se representar os números leva em consideração a precisão e a faixa de
valores necessários para os cálculos utilizados. As Séries de Taylor exigem a utilização
de uma faixa de valores que vai de números fracionários, menores que 1, a valores
muito altos, o que impossibilita a utilização da representação por números inteiros.
Dessa forma, a representação numérica é feita utilizando-se o conceito da aritmética de
ponto flutuante (ROTH JR., 1998).
A Tabela 2.1 ilustra a representação dos bits normalmente utilizada para números de
ponto flutuante, conhecida como padrão IEEE 754 (TANENBAUM, 2007).
Tabela 2.1 – Representação de ponto flutuante IEEE 754

Sinal: 1 bit (MSB) Expoente: 8 bits Mantissa: 23 bits (LSB)

Neste padrão, o número que se está representando é obtido pela Equação 2.5, vista
abaixo.
𝑀𝑎𝑛𝑡𝑖𝑠𝑠𝑎
𝑁 = (−1)𝑆𝑖𝑛𝑎𝑙 × 2𝐸𝑥𝑝𝑜𝑒𝑛𝑡𝑒−127 × 1, Equação 2.5
223
na qual
- Sinal: 0 ou 1;
- Expoente: inteiro variando de 0 a 255;
- Mantissa: inteiro variando de 0 a 8.388.607.
Neste trabalho, porém, optou-se por utilizar uma forma diferente para o cálculo do
número representado, mostrada na Equação 2.6, mas que utiliza a mesma estrutura vista
na Tabela 2.1.
𝑀𝑎𝑛𝑡𝑖𝑠𝑠𝑎
𝑁 = (−1)𝑆𝑖𝑛𝑎𝑙 × 2𝐸𝑥𝑝𝑜𝑒𝑛𝑡𝑒 × Equação 2.6
223
na qual
- Sinal: 0 ou 1;
- Expoente: inteiro variando de -128 a 127;
- Mantissa: inteiro variando de 0 a 8.388.607.
O número 10, por exemplo, seria representado neste formato da seguinte maneira:
[0 00000100 10100000000000000000000] (binário) ou
[0 4 5.242.880] (decimal).
Esta forma de representação torna mais rápido o cálculo dos resultados, por não
exigir nenhum tipo de adaptação de expoente e mantissa, como seria necessário no caso
anterior. Por exemplo, utilizando a representação IEEE 754, quando a parte fracionária
𝑀𝑎𝑛𝑡𝑖𝑠𝑠𝑎
( ) é 0,5, o valor de multiplicação é na verdade 1,5. Para utilizar este valor nos
223
5

cálculos, seria necessário utilizar uma variável interna ao sistema, que receberia o valor
da mantissa, fazer o deslocamento de bits dessa variável à direita e inserir um bit com
valor 1 no bit mais significativo da mantissa. Considerando que o expoente inicial seja
127, este passaria para 128 e teríamos então o valor 0,75, que pode então ser utilizado
para o cálculo. Seria necessária também uma variável adicional que receberia o valor do
expoente menos 127.
Utilizando o formato escolhido para este projeto, não são necessários circuitos de
adaptação de expoente e mantissa, o que contribui para redução da utilização dos
recursos do dispositivo. No caso de haver necessidade de utilização do padrão IEEE
754, o circuito pode ser adaptado, havendo pequeno comprometimento de desempenho
e aumento na utilização de recursos do hardware.
6
7

3. PROJETO

A Ferramenta de Edição e Tradução de equações matemáticas para VHDL destina-


se à síntese de equações matemáticas em circuitos eletrônicos digitais. Esta ferramenta
analisa uma equação matemática e utiliza estruturas correspondentes em linguagem
VHDL para descrição dos circuitos necessários ao desempenho da função.
O objetivo do projeto é proporcionar uma forma rápida de se obter código VHDL, e
assim circuitos digitais, correspondentes a funções matemáticas para aplicação nas
diversas áreas que se utilizam de dispositivos de lógica programável.
O sistema é composto por:
a) Interface para inserção de equações e visualização dos resultados;
b) Possibilidade de carregamento da equação e geração de resultado em arquivo de
texto;
c) Software de testes para envio de valores, recebimento de resultados da FPGA por
meio da interface de hardware, e comparação dos valores recebidos com os valores
esperados;
d) Interface de hardware para recebimento dos valores do computador de forma serial e
passagem dos valores à FPGA de forma paralela (32 bits), assim como leitura da
resposta de forma paralela e transmissão ao computador de forma serial;

3.1 Requisitos
Os requisitos mínimos para o funcionamento do sistema são descritos a seguir:

a) Computador com sistema operacional Windows XP, interface USB, 512 MB de


RAM, 5 GB de espaço livre em HD;
b) Ferramenta de desenvolvimento Quartus-II;
c) Kit de lógica programável DE2 da Altera;
d) Interface de hardware USB para testes, desenvolvida no projeto.

3.2 Arquitetura
A Figura 3.1 dá uma visão geral do projeto, o qual é dividido em software e
hardware, explicados em maiores detalhes nas sessões seguintes.
8

Figura 3.1 – Arquitetura do Projeto

3.2.1 Software
O tradutor analisa uma equação inserida pelo usuário, verificando os operadores e
variáveis. Após isso, faz a quebra da expressão e o código é gerado por meio da
combinação de funções em VHDL, correspondentes a cada fragmento da expressão.
O ciclo de tradução executado pelo programa é mostrado na Figura 3.2.

Figura 3.2 – Software de tradução


Além do tradutor, é utilizado o software de comunicação, que é responsável pelo
envio dos valores das variáveis utilizadas para os testes do código gravado no
9

dispositivo de lógica programável e consequente leitura das respostas a esses dados,


fazendo a posterior comparação dos valores enviados com os valores esperados para os
sistemas analisados.
O ciclo executado pelo software de testes é mostrado na Figura 3.3.

Figura 3.3 – Software de testes

3.2.2 Hardware
O hardware necessário ao projeto é composto por:
a) Computador pessoal, no qual o tradutor é instalado e por meio do qual é feita a
comunicação com a interface de hardware para testes;
b) Kit de lógica programável, utilizando FPGA ou CPLD, onde o circuito
correspondente ao código gerado é gravado;
c) Interface de hardware para testes, que recebe os valores das variáveis do
computador, envia estes dados ao dispositivo de lógica programável, recebe a
resposta do dispositivo e a envia ao computador.
Os dados, que correspondem aos valores das variáveis utilizadas na equação, são
enviados pelo computador por meio de comunicação serial (USB) para a interface de
hardware, a qual faz a aquisição dos valores de forma serial e disponibiliza estes valores
de forma paralela, para que possam ser processados pelo dispositivo de lógica
programável. As saídas da interface são então ligadas às entradas do kit.
As respostas aos dados enviados, ou seja, o cálculo feito pelo dispositivo de lógica
programável, são obtidas de forma inversa, coletando os dados paralelamente nas saídas
do kit e enviando-os de forma serial ao computador.
A Figura 3.4 ilustra a comunicação de dados entre os dispositivos. Na Figura 3.5,
temos o princípio de funcionamento do firmware utilizado.
10

Figura 3.4 – Diagrama de hardware

Figura 3.5 – Diagrama de firmware

3.3 Testes do Sistema


O módulo de comunicação possui três componentes principais:
a) Canal de comunicação com o computador (canal A);
b) Dispositivo para envio de valores (dispositivo B);
c) Dispositivo para leitura de valores (dispositivo C);
Os testes do módulo são feitos por meio do envio de valores (32 bits) do
computador para o módulo pelo canal A. O dispositivo B é então verificado, e deve
exibir o mesmo valor enviado pelo computador. De forma inversa, são inseridos valores
no dispositivo C, que são enviados ao computador pelo canal A. Os valores recebidos
pelo computador são então verificados, e devem ser os mesmos inseridos no dispositivo
C.
A descrição do sistema pode ser visualizada na Figura 3.6.
11

Figura 3.6 – Testes do módulo de comunicação


A interface de tradução é testada separadamente, cada módulo recebe valores de
entrada e deve fornecer as saídas esperadas de acordo com sua funcionalidade. Após o
teste de cada módulo é feita a integração do sistema e novos testes são realizados.
Para esta interface são verificadas as seguintes funções:
a) Análise da equação: verificação de operadores e variáveis;
b) Quebra da expressão: separação em partes;
c) Geração de código: análise das partes da equação, geração de código
correspondente;
d) Junção de código: junção dos trechos de código, correspondência com a equação
completa.
A interface de testes, software que faz envio, recepção e comparação dos valores, é
testada após os testes do módulo de comunicação. Com o módulo funcionando
corretamente, também é possível verificar o correto funcionamento da interface.

3.4 Planejamento do Projeto


O planejamento do projeto é dividido em cronograma e recursos necessários.

3.4.1 Recursos
Os seguintes recursos são necessários para a execução do projeto:
a) Equipamentos:
(i) Computador pessoal (PC);
(ii) Kit de lógica programável Nios-II;
(iii)Instrumentos de medição (osciloscópio, voltímetro, etc.);
(iv) Gravador para microcontroladores;
b) Ambientes de programação:
(i) Para desktop (Visual Studio);
(ii) Para lógica programável (Quartus-II);
(iii)Para microcontroladores (CCS);
c) Componentes:
(i) Microcontrolador;
(ii) Componentes eletrônicos diversos para interface de comunicação.
12

3.4.2 Cronograma

A seguir temos o cronograma inicial do projeto:


Tabela 3.1 – Cronograma inicial do projeto

Atividade Início Término


Proposta inicial 14/2/2011 17/2/2011
Retorno do orientador 17/2/2011 28/2/2011
Especificação 28/2/2011 21/3/2011
Projeto 24/3/2011 18/4/2011
Implementação parcial 18/4/2011 20/6/2011
Qualificação 20/6/2011 15/8/2011
Requalificação 15/8/2011 29/8/2011
Relatório 29/8/2011 5/9/2011
Devolução Banca 5/9/2011 3/10/2011
Monografia 5/9/2011 31/10/2011
Mostra 31/10/2011 7/11/2011
Defesa final 7/11/2011 21/11/2011
Monografia II 7/11/2011 21/11/2011
Entrega final 5/12/2011 5/12/2011
13

4. RESULTADOS

4.1 Software
O software do projeto é composto pela interface de tradução e pela interface de
testes para comunicação com o módulo de hardware.

4.1.1 Software de Tradução


O software de tradução é capaz de traduzir equações que contenham as operações de
soma, subtração, multiplicação, divisão e potenciação, além das funções seno, cosseno,
tangente e exponencial. A interface do software é mostrada nas figuras 4.1 e 4.2.

Figura 4.1 – Tradutor: inserção da equação


14

Figura Erro! Use a guia Página Inicial para aplicar 0 ao texto que deverá
aparecer aqui.4.2 – Tradutor: código correspondente à equação inserida
A seguir temos o código VHDL gerado para a equação cos(x)+2*x**3/25-0,5*x,
utilizada como exemplo.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package Teste is
component Cosseno
port (x: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end component;
component Multiplicacao
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end component;
component Divisao
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end component;
component Potenciacao
port (x1: in std_logic_vector (31 downto 0);
x2: in integer range 0 to 7;
y: out std_logic_vector (31 downto 0));
end component;
component Soma
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end component;
component Subtracao
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end component;
end Teste;
15

library work;
use work.Teste.all;
library ieee;
use ieee.std_logic_1164.all;

entity TCC is
port (x: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end TCC;

architecture Equacao of TCC is


signal Cte1: std_logic_vector(31 downto 0);
signal Cte2: std_logic_vector(31 downto 0);
signal Cte3: std_logic_vector(31 downto 0);
signal x1: std_logic_vector (31 downto 0);
signal x2: std_logic_vector (31 downto 0);
signal x3: std_logic_vector (31 downto 0);
signal x4: std_logic_vector (31 downto 0);
signal x5: std_logic_vector (31 downto 0);
signal x6: std_logic_vector (31 downto 0);
signal x7: std_logic_vector (31 downto 0);
signal x8: std_logic_vector (31 downto 0);
begin
Cte1 <= "00000001010000000000000000000000";
Cte2 <= "00000010111001000000000000000000";
Cte3 <= "01111111111111111111111111111111";
x1 <= x;
Op2: Cosseno port map (x => x1, y => x2);
Op3: Potenciacao port map (x1 => x, x2 => 3, y => x3);
Op4: Multiplicacao port map (x1 => Cte1, x2 => x3, y => x4);
Op5: Divisao port map (x1 => x4, x2 => Cte2, y => x5);
Op6: Multiplicacao port map (x1 => Cte3, x2 => x, y => x6);
Op7: Subtracao port map (x1 => x5, x2 => x6, y => x7);
Op8: Soma port map (x1 => x2, x2 => x7, y => x8);
y <= x8;
end Equacao;

Os códigos VHDL correspondentes a cada component utilizado neste código podem


ser vistos no anexos.
As Séries de Taylor utilizadas tiveram o número de termos limitados, sendo n = 3
para as funções trigonométricas e n = 10 para a função exponencial. A precisão é
satisfatória para algumas aplicações, e adequada à limitação do hardware, que, por
utilizar lógica combinacional tem um número limitado de estruturas, o que impede um
número muito grande de iterações nos cálculos.
Para a compilação do código gerado, faz-se necessária a utilização de componentes
(bibliotecas), gerados em linguagem VHDL, correspondentes a cada função da
expressão matemática utilizada.
A seguir encontram-se os resultados das simulações das funções desenvolvidas,
levando em consideração o primeiro quadrante do círculo trigonométrico (0 a π/2
radianos), a partir do qual é possível mapear os demais, utilizando inversão do sinal na
resposta.
16

Tabela 4.1 – Resultados para o cálculo do seno

Seno
Ângulo (radianos) Resultado Obtido Resultado Esperado Erro %
0,078539816 0,078461051 0,078459096 0,0024920
0,157079633 0,156449556 0,156434465 0,0096470
0,235619449 0,233495057 0,233445364 0,0212866
0,314159265 0,309139609 0,309016994 0,0396790
0,392699082 0,382922649 0,382683432 0,0625104
0,471238898 0,454402447 0,4539905 0,0907391
0,549778714 0,523142338 0,522498565 0,1232104
0,628318531 0,588768959 0,587785252 0,1673581
0,706858347 0,650848866 0,649448048 0,2156934
0,785398163 0,709028482 0,707106781 0,2717695
0,86393798 0,762963772 0,760405966 0,3363737
0,942477796 0,812336922 0,809016994 0,4103655
1,021017612 0,856859684 0,852640164 0,4948769
1,178097245 0,930355072 0,923879533 0,7009073
1,256637061 0,958909035 0,951056516 0,8256626
1,335176878 0,981777668 0,97236992 0,9675070
1,413716694 0,998838902 0,987688341 1,1289554
1,49225651 1,010004044 0,996917334 1,3127176

Tabela 4.2 – Parte 1 – Resultados para o cálculo do cosseno

Cosseno
Ângulo (radianos) Resultado Obtido Resultado Esperado Erro %
0,078539816 0,996917963 0,996917334 6,31241E-05
0,157079633 0,987687349 0,987688341 0,00010036
0,235619449 0,97236228 0,97236992 0,00078576
0,314159265 0,951056004 0,951056516 5,39111E-05
0,392699082 0,923878908 0,923879533 6,75796E-05
0,471238898 0,891006231 0,891006524 3,28707E-05
0,549778714 0,852639675 0,852640164 5,73763E-05
0,628318531 0,809015989 0,809016994 0,00012423
0,706858347 0,76040411 0,760405966 0,00024403
0,785398163 0,707102776 0,707106781 0,00056647
0,86393798 0,649439812 0,649448048 0,00126825
0,942477796 0,587769508 0,587785252 0,00267851
1,021017612 0,522469044 0,522498565 0,00564996
1,099557429 0,453938007 0,4539905 0,01156244
1,178097245 0,382592201 0,382683432 0,02383984
1,256637061 0,308864594 0,309016994 0,04931795
1,335176878 0,23319912 0,233445364 0,10548262
17

Tabela 4.2 – Parte 2 – Resultados para o cálculo do cosseno

Cosseno
Ângulo (radianos) Resultado Obtido Resultado Esperado Erro %
1,413716694 0,156046867 0,156434465 0,24776999
1,49225651 0,077863216 0,078459096 0,75947769

Tabela 4.3 - Resultados para o cálculo da tangente

Tangente
Ângulo (radianos) Resultado Obtido Resultado Esperado Erro %
0,078539816 0,078701854 0,078701707 0,00018668
0,157079633 0,158384562 0,15838444 7,65316E-05
0,235619449 0,240084887 0,240078759 0,00255227
0,314159265 0,324918747 0,324919696 0,00029216
0,392699082 0,414207458 0,414213562 0,00147360
0,471238898 0,509497166 0,509525449 0,00555101
0,549778714 0,612685204 0,612800788 0,01886169
0,628318531 0,726143837 0,726542528 0,05487511
0,706858347 0,852870941 0,854080685 0,14164285
0,785398163 0,996682167 1 0,33178329
0,86393798 1,162441254 1,170849566 0,71813772
0,942477796 1,356330872 1,37638192 1,45679397
1,021017612 1,586177826 1,631851687 2,79889781
1,099557429 1,861858368 1,962610506 5,13357781
1,178097245 2,19568634 2,414213562 9,05169391
1,256637061 2,602973938 3,077683537 15,4242498
1,335176878 3,10256958 4,16529977 25,5138945
1,413716694 3,717525482 6,313751515 41,1201807
1,49225651 4,475837708 12,70620474 64,7743932

Tabela 4.4 - Resultados para o cálculo da função exponencial

Exponencial
Expoente Resultado Obtido Resultado Esperado Erro %
0,1 1,100692272 1,105170918 0,40524463
0,2 1,206698656 1,221402758 1,20387005
0,3 1,327107906 1,349858808 1,68542821
0,4 1,475142002 1,491824698 1,11827452
0,5 1,668208838 1,648721271 1,18198067
0,6 1,927670002 1,8221188 5,79277276
0,7 2,27977705 2,013752707 13,2103779
0,8 2,754839897 2,225540928 23,7829357
0,9 3,387824535 2,459603111 37,7386668
1 4,218265533 2,718281828 55,1813167
18

4.1.2 Software de Testes


Este software envia os valores correspondentes às variáveis para o módulo de
hardware, lê a resposta para o valor enviado. Armazena os valores e compara com
valores esperados. A interface do software de testes é mostrada nas figuras 4.3 e 4.4.

Figura Erro! Use a guia Página Inicial para aplicar 0 ao texto que deverá
aparecer aqui.4.3 – Software de testes

Figura 4.4 – Software de testes com resultados

4.2. Hardware
A interface de hardware proporciona uma forma rápida de testar combinações de
valores de entrada no dispositivo de lógica programável. Apesar de os resultados
poderem ser simulados por meio do Quartus II, com a interface de testes é possível
19

enviar uma grande quantidade de valores ao dispositivo e verificar se as respostas estão


de acordo com o esperado, com variações aceitáveis para a aplicação.
Por se tratar de um componente com grande número de entradas e saídas,
totalizando 64 pinos, a interface de hardware foi dividida em três partes, sendo uma
para controle, uma para escrita e outra para leitura dos dados. As figuras 4.5, 4.6 e 4.7
mostram, respectivamente, os módulos citados. A Figura 4.8 mostra o kit DE2 da
Altera, utilizado para os testes.

Figura 4.5 – Módulo de controle


20

Figura 4.6 – Módulo de escrita

Figura 4.7 – Módulo de leitura


21

Figura 4.8 – Kit Altera DE2


22

5. CONCLUSÃO

O tradutor funcionou de acordo com as expectativas. As traduções ocorrem


corretamente para as funções desenvolvidas, sendo possível combinar essas funções,
assim como utilizar as operações básicas de adição, subtração, multiplicação e divisão,
além da potenciação.
Os métodos utilizados para representação das Séries de Taylor em linguagem
VHDL se mostram confiáveis e as variações ocorridas entre os valores obtidos e os
valores esperados para as equações já eram esperados, uma vez que as séries foram
limitadas levando em consideração o hardware necessário para construção dos circuitos.
Observa-se que estes métodos não são recomendados para as funções tangente e
exponencial, por apresentarem, exceto para números muito pequenos, erros percentuais
muito altos.
Havendo a necessidade, é possível customizar as funções e operações para que
retornem um resultado mais preciso, o que tem como efeito a utilização de um número
maior de unidades lógicas no dispositivo programável e perda no desempenho,
aumentando o tempo de resposta para as funções.
Os próximos passos para o projeto devem consistir no desenvolvimento de um
maior número de funções matemáticas e a possibilidade de se trabalhar com números
inteiros e de ponto flutuante paralelamente, além do aprimoramento da interface de
testes para que seja possível uma avaliação estatística dos resultados para os circuitos
gerados. Além disso, como a utilização de lógica puramente combinacional (por meio
da qual foram desenvolvidas todas as funções deste projeto) tem um grande custo em
termos de hardware necessário, é interessante que sejam desenvolvidas funções
utilizando também a lógica seqüencial, que diminui este custo em troca de uma redução
no desempenho, mas que, para algumas aplicações, pode ser uma alternativa mais
vantajosa, podendo ser utilizada principalmente nas funções que exigem um maior
número de iterações, como no caso das funções tangente e exponencial, reduzindo os
erros encontrados com a abordagem atual.
23

6. REFERÊNCIAS

1. D’AMORE, R., VHDL: Descrição e Síntese de Circuitos Digitais. São Paulo:


LTC, 2005.
2. Microchip Tecnology Inc.: DS39632E, 2009.
3. Altera Corporation: DE2 Development and Education Board User Manual,
2006.
4. ROTH JR., Charles H. Digital Systems Design Using VHDL. Boston: PWS
Publishing, c1998.
5. TANENBAUM, Andrew S. Organização Estruturada de Computadores. 5.
ed. São Paulo: Pearson Prentice Hall, c2007
6. SWOKOWSKI, Earl William. Cálculo com Geometria Analítica. 2. ed. São
Paulo: Makron Books, 1995.
7. WIKIPEDIA. Taylor Series. Disponível em:
<http://en.wikipedia.org/wiki/Taylor_series>. Acesso em: 09/2011
8. C. Morra, J. Becker, M. Ayala-Rincon, and R. Hartenstein. FELIX: Using
rewriting-logic for generating functionally equivalent implementations, in Proc.
International Conference on Field Programmable Logic and Applications (FPL
2005), vol. 1, Aug. 2005, pp. 25–30.
24
25

ANEXO A: CÓDIGO VHDL DA FUNÇÃO SENO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Seno is
port (x: in std_logic_vector (31 downto 0); -- mantissa
y: out std_logic_vector (31 downto 0));
end Seno;

architecture PtoFte of Seno is


type vetor is array (4 downto 0) of std_logic_vector (23 downto 0);
type vetor2 is array (4 downto 0) of std_logic_vector (7 downto 0);
signal fator: vetor;
signal expoente: vetor2;
begin
fator(0) <= "010011101100000000000000"; -- [5.040]
fator(1) <= "100110011000000000000000"; -- [-840]
fator(2) <= "010101000000000000000000"; -- [42]
fator(3) <= "110000000000000000000000"; -- [-1]
fator(4) <= "011010000000011010000000"; -- [1/5.040]
expoente(0) <= "00001101";
expoente(1) <= "00001010";
expoente(2) <= "00000110";
expoente(3) <= "00000001";
expoente(4) <= "11110100";

process(x)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (47 downto 0);
variable exp2: std_logic_vector (15 downto 0);
begin
exp1 := (others => '0');
mant1 := (others => '0');
for i in 0 to 3 loop
exp2(15 downto 8) := x(30 downto 23);
mant2(46) := x(31);
mant2(45 downto 23) := x(22 downto 0);
for j in 2 to ((2 * i) + 1) loop
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + signed(x(30
downto 23)));
mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(x(31) & x(22 downto
0)));
end loop;

mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(fator(i)));


exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) +
signed(expoente(i)));
if signed(exp1) > signed(exp2(15 downto 8)) then
for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
exit when exp1 = exp2(15 downto 8);
end loop;
elsif signed(exp2(15 downto 8)) > signed(exp1) then
for i in 0 to 15 loop
mant1 := std_logic_vector(signed(mant1) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exit when exp1 = exp2(15 downto 8);
end loop;
end if;
if (signed(mant1) + signed(mant2(46 downto 23))) > 8388607 or (signed(mant1) +
signed(mant2(46 downto 23))) < -8388608 then
mant1 := std_logic_vector(signed(mant1) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
26

exp1 := std_logic_vector(signed(exp1) + 1);


exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
end if;
mant1 := std_logic_vector(signed(mant1) + signed(mant2(46 downto 23)));
end loop;
mant2 := std_logic_vector(signed(mant1) * signed(fator(4)));
exp1 := std_logic_vector(signed(exp1) + signed(expoente(4)));
y(31) <= mant2(46);
y(30 downto 23) <= exp1;
y(22 downto 0) <= mant2(45 downto 23);
end process;
end PtoFte;
27

ANEXO B: CÓDIGO VHDL DA FUNÇÃO COSSENO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Cosseno is
port (x: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Cosseno;

architecture PtoFte of Cosseno is


type vetor is array (4 downto 1) of std_logic_vector (23 downto 0);
type vetor2 is array (4 downto 1) of std_logic_vector (7 downto 0);
signal fator: vetor;
signal expoente: vetor2;
begin
fator(1) <= "101001100000000000000000"; -- [-360]
fator(2) <= "011110000000000000000000"; -- [30]
fator(3) <= "110000000000000000000000"; -- [-1]
fator(4) <= "010110110000010110110000"; -- [1/720]
expoente(1) <= "00001001";
expoente(2) <= "00000101";
expoente(3) <= "00000001";
expoente(4) <= "11110111";
process(x)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (47 downto 0);
variable exp2: std_logic_vector (15 downto 0);
begin
exp1 := "00001010";
mant1 := "010110100000000000000000"; -- [720]
for i in 1 to 3 loop
exp2(15 downto 8) := x(30 downto 23);
mant2(46) := x(31);
mant2(45 downto 23) := x(22 downto 0);
for j in 2 to (2 * i) loop
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + signed(x(30
downto 23)));
mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(x(31) & x(22 downto
0)));
end loop;

mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(fator(i)));


exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) +
signed(expoente(i)));
if signed(exp1) > signed(exp2(15 downto 8)) then
for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
exit when exp1 = exp2(15 downto 8);
end loop;

elsif signed(exp2(15 downto 8)) > signed(exp1) then


for i in 0 to 15 loop
mant1 := std_logic_vector(signed(mant1) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
28

exit when exp1 = exp2(15 downto 8);


end loop;

end if;
if (signed(mant1) + signed(mant2(46 downto 23))) > 8388607 or (signed(mant1) +
signed(mant2(46 downto 23))) < -8388608 then
mant1 := std_logic_vector(signed(mant1) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
end if;
mant1 := std_logic_vector(signed(mant1) + signed(mant2(46 downto 23)));
end loop;

mant2 := std_logic_vector(signed(mant1) * signed(fator(4)));


exp1 := std_logic_vector(signed(exp1) + signed(expoente(4)));
y(31) <= mant2(46);
y(30 downto 23) <= exp1;
y(22 downto 0) <= mant2(45 downto 23);
end process;
end PtoFte;
29

ANEXO C: CÓDIGO VHDL DA FUNÇÃO TANGENTE

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Tangente is
port (x: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Tangente;

architecture PtoFte of Tangente is


type vetor is array (3 downto 0) of std_logic_vector (23 downto 0);
type vetor2 is array (3 downto 0) of std_logic_vector (7 downto 0);
signal fator: vetor;
signal expoente: vetor2;
begin
fator(0) <= "010101010101010101010101"; -- [1/3]
fator(1) <= "010001000100010001000100"; -- [2/15]
fator(2) <= "011011101000011011101000"; -- [17/315]
fator(3) <= "010110011001001111010001"; -- [79.360/3.628.800]
expoente(0) <= "11111111";
expoente(1) <= "11111110";
expoente(2) <= "11111100";
expoente(3) <= "11111011";
process(x)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (47 downto 0);
variable exp2: std_logic_vector (15 downto 0);
begin
exp1 := x(30 downto 23);
mant1 := x(31) & x(22 downto 0);
for i in 1 to 3 loop
exp2(15 downto 8) := x(30 downto 23);
mant2(46) := x(31);
mant2(45 downto 23) := x(22 downto 0);
for j in 2 to ((2 * i) + 1) loop
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + signed(x(30
downto 23)));
mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(x(31) & x(22 downto
0)));
end loop;

mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(fator(i - 1)));


exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + signed(expoente(i
- 1)));
if signed(exp1) > signed(exp2(15 downto 8)) then
for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
exit when exp1 = exp2(15 downto 8);
end loop;

elsif signed(exp2(15 downto 8)) > signed(exp1) then


for i in 0 to 15 loop
mant1 := std_logic_vector(signed(mant1) / 2);
30

exp1 := std_logic_vector(signed(exp1) + 1);


exit when exp1 = exp2(15 downto 8);
end loop;
end if;
if (signed(mant1) + signed(mant2(46 downto 23))) > 8388607 or (signed(mant1) +
signed(mant2(46 downto 23))) < -8388608 then
mant1 := std_logic_vector(signed(mant1) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
end if;
mant1 := std_logic_vector(signed(mant1) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2(15 downto 8) := std_logic_vector(signed(exp2(15 downto 8)) + 1);
mant1 := std_logic_vector(signed(mant1) + signed(mant2(46 downto 23)));
end loop;
y(31) <= mant1(23);
y(30 downto 23) <= exp1;
y(22 downto 0) <= mant1(22 downto 0);
end process;
end PtoFte;
31

ANEXO D: CÓDIGO VHDL DA FUNÇÃO EXPONENCIAL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Exponencial is
port (x: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Exponencial;

architecture PtoFte of Exponencial is


type vetor is array (8 downto 0) of std_logic_vector (23 downto 0);
type vetor2 is array (8 downto 0) of std_logic_vector (7 downto 0);
signal fator: vetor;
signal expoente: vetor2;
begin
fator(8) <= "010010011111100100111110";
expoente(8) <= "11101011";
fator(7) <= "010111000111011110001110";
expoente(7) <= "11101110";
fator(6) <= "011010000000011010000000";
expoente(6) <= "11110001";
fator(5) <= "011010000000011010000000";
expoente(5) <= "11110100";
fator(4) <= "010110110000010110110000";
expoente(4) <= "11110111";
fator(3) <= "010001000100010001000100";
expoente(3) <= "11111010";
fator(2) <= "010101010101010101010101";
expoente(2) <= "11111100";
fator(1) <= "011010101010101010101010";
expoente(1) <= "00000001";
fator(0) <= "011111111111111111111111";
expoente(0) <= "11111111";

process(x)
variable mant1: std_logic_vector (47 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (23 downto 0);
variable exp2: std_logic_vector (7 downto 0);
begin
exp2 := "00000001";
mant2 := "010000000000000000000000";
exp1 := x(30 downto 23);
mant1(46) := x(31);
mant1(45 downto 23) := x(22 downto 0);

if signed(exp1) > signed(exp2) then


for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2 := std_logic_vector(signed(exp2) + 1);
exit when exp1 = exp2;
end loop;
elsif signed(exp2) > signed(exp1) then
for i in 0 to 15 loop
mant1(46 downto 23) := std_logic_vector(signed(mant1(46 downto 23)) / 2);
32

exp1 := std_logic_vector(signed(exp1) + 1);


exit when exp1 = exp2;
end loop;
end if;
if (signed(mant2) + signed(mant1(46 downto 23))) > 8388607 or (signed(mant2) +
signed(mant1(46 downto 23))) < 0 then
mant1(46 downto 23) := std_logic_vector(signed(mant1(46 downto 23)) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2 := std_logic_vector(signed(exp2) + 1);
end if;
mant2 := std_logic_vector(signed(mant1(46 downto 23)) + signed(mant2));

for i in 0 to 8 loop
exp1 := x(30 downto 23);
mant1(46) := x(31);
mant1(45 downto 23) := x(22 downto 0);
for j in 0 to (i + 1) loop
exp1 := std_logic_vector(signed(exp1) + signed(x(30 downto 23)));
mant1 := std_logic_vector(signed(mant1(46 downto 23)) * signed(x(31) & x(22 downto
0)));
end loop;
exp1 := std_logic_vector(signed(exp1) + signed(expoente(i)));
mant1 := std_logic_vector(signed(mant1(46 downto 23)) * signed(fator(i)));

if signed(exp1) > signed(exp2) then


for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2 := std_logic_vector(signed(exp2) + 1);
exit when exp1 = exp2;
end loop;
elsif signed(exp2) > signed(exp1) then
for i in 0 to 15 loop
mant1(46 downto 23) := std_logic_vector(signed(mant1(46 downto 23)) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exit when exp1 = exp2;
end loop;
end if;
if (signed(mant2) + signed(mant1(46 downto 23))) > 8388607 or (signed(mant2) +
signed(mant1(46 downto 23))) < 0 then
mant1(46 downto 23) := std_logic_vector(signed(mant1(46 downto 23)) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2 := std_logic_vector(signed(exp2) + 1);
end if;
mant2 := std_logic_vector(signed(mant1(46 downto 23)) + signed(mant2));
end loop;

y(31) <= mant2(23);


y(30 downto 23) <= exp2;
y(22 downto 0) <= mant2(22 downto 0);
end process;
end PtoFte;
33

ANEXO E: CÓDIGO VHDL DA OPERAÇÃO DE ADIÇÃO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Soma is
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Soma;

architecture PtoFte of Soma is


begin
process(x1, x2)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (23 downto 0);
variable exp2: std_logic_vector (7 downto 0);
begin
exp1 := x1(30 downto 23);
mant1 := x1(31) & x1(22 downto 0);
exp2 := x2(30 downto 23);
mant2 := x2(31) & x2(22 downto 0);
if signed(exp1) > signed(exp2) then
for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2 := std_logic_vector(signed(exp2) + 1);
exit when exp1 = exp2;
end loop;
elsif signed(exp2) > signed(exp1) then
for i in 0 to 15 loop
mant1 := std_logic_vector(signed(mant1) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exit when exp1 = exp2;
end loop;
end if;
if ((signed(mant1) + signed(mant2)) > 8388607) or (signed(mant1) < 0 and
signed(mant2) < 0 and (signed(mant1) + signed(mant2) + 8388608) < 0) then
mant1 := std_logic_vector(signed(mant1) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2 := std_logic_vector(signed(exp2) + 1);
end if;
mant2 := std_logic_vector(signed(mant1) + signed(mant2));
y(31) <= mant2(23);
y(30 downto 23) <= exp1;
y(22 downto 0) <= mant2(22 downto 0);
end process;
end PtoFte;
34
35

ANEXO F: CÓDIGO VHDL DA OPERAÇÃO DE


SUBTRAÇÃO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Subtracao is
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Subtracao;

architecture PtoFte of Subtracao is


begin
process(x1, x2)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (23 downto 0);
variable exp2: std_logic_vector (7 downto 0);
begin
exp1 := x1(30 downto 23);
mant1 := x1(31) & x1(22 downto 0);
exp2 := x2(30 downto 23);
mant2 := x2(31) & x2(22 downto 0);
if signed(exp1) > signed(exp2) then
for i in 0 to 15 loop
mant2 := std_logic_vector(signed(mant2) / 2);
exp2 := std_logic_vector(signed(exp2) + 1);
exit when exp1 = exp2;
end loop;
elsif signed(exp2) > signed(exp1) then
for i in 0 to 15 loop
mant1 := std_logic_vector(signed(mant1) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exit when exp1 = exp2;
end loop;
end if;
if (signed(mant1) > 0 and (signed(mant1) - signed(mant2)) > 8388607) or
(signed(mant1) < 0 and (signed(mant1) - signed(mant2) + 8388608) < 0) then
mant1 := std_logic_vector(signed(mant1) / 2);
mant2 := std_logic_vector(signed(mant2) / 2);
exp1 := std_logic_vector(signed(exp1) + 1);
exp2 := std_logic_vector(signed(exp2) + 1);
end if;
mant2 := std_logic_vector(signed(mant1) - signed(mant2));
y(31) <= mant2(23);
y(30 downto 23) <= exp1;
y(22 downto 0) <= mant2(22 downto 0);
end process;
end PtoFte;
36
37

ANEXO G: CÓDIGO VHDL DA OPERAÇÃO DE


MULTIPLICAÇÃO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Multiplicacao is
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Multiplicacao;

architecture PtoFte of Multiplicacao is


begin
process(x1, x2)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (47 downto 0);
variable exp2: std_logic_vector (7 downto 0);
begin
exp1 := x1(30 downto 23);
mant1 := x1(31) & x1(22 downto 0);
exp2 := x2(30 downto 23);
mant2(46 downto 23) := x2(31) & x2(22 downto 0);
exp2 := std_logic_vector(signed(exp2) + signed(exp1));
mant2 := std_logic_vector(signed(mant2(46 downto 23)) * signed(mant1));

y(31) <= mant2(46);


y(30 downto 23) <= exp2;
y(22 downto 0) <= mant2(45 downto 23);
end process;
end PtoFte;
38
39

ANEXO H: CÓDIGO VHDL DA OPERAÇÃO DE DIVISÃO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Divisao is
port (x1: in std_logic_vector (31 downto 0);
x2: in std_logic_vector (31 downto 0);
y: out std_logic_vector (31 downto 0));
end Divisao;

architecture PtoFte of Divisao is


begin
process(x1, x2)
variable mant1: std_logic_vector (23 downto 0);
variable exp1: std_logic_vector (7 downto 0);
variable mant2: std_logic_vector (23 downto 0);
variable exp2: std_logic_vector (7 downto 0);
begin
exp1 := x1(30 downto 23);
mant1 := x1(31) & x1(22 downto 0);
exp2 := x2(30 downto 23);
mant2 := x2(31) & x2(22 downto 0);
exp2 := std_logic_vector(signed(exp2) - 12);
exp1 := std_logic_vector(signed(exp1) - signed(exp2));
mant1 := std_logic_vector(signed(mant1) / signed(mant2(23 downto 11)));

y(31) <= mant1(23);


y(30 downto 23) <= exp1;
y(22 downto 0) <= mant1(22 downto 0);
end process;
end PtoFte;
40
41

ANEXO I: CÓDIGO VHDL DA OPERAÇÃO DE


POTENCIAÇÃO

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Potenciacao is
port (x1: in std_logic_vector (31 downto 0); -- mantissa
x2: in integer range 0 to 7;
y: out std_logic_vector (31 downto 0));
end Potenciacao;

architecture PtoFte of Potenciacao is


begin
process(x1, x2)
variable mant1: std_logic_vector (47 downto 0);
variable exp1: std_logic_vector (7 downto 0);
begin
if x2 = 0 then
exp1 := "00000001";
mant1(46 downto 23) := "010000000000000000000000";
else
exp1 := x1(30 downto 23);
mant1(46) := x1(31);
mant1(45 downto 23) := x1(22 downto 0);
for i in 2 to 7 loop
exit when i > x2;
exp1 := std_logic_vector(signed(exp1) + signed(x1(30 downto 23)));
mant1 := std_logic_vector(signed(mant1(46 downto 23)) * signed(x1(31) & x1(22
downto 0)));
end loop;
end if;
y(31) <= mant1(46);
y(30 downto 23) <= exp1;
y(22 downto 0) <= mant1(45 downto 23);
end process;
end PtoFte;

Você também pode gostar