Prezado leitor, no presente tópico iremos discutir como podemos representar números reais, de ponto fixo e ponto flutuante, em binário e listar alguns métodos utilizados pelo projetista moderno para trabalhar com essas representações. O assunto é extenso e de suma importância, por isso convido o leitor a explorar mais o assunto em livros como [1] e a própria especificação do padrão Verilog IEEE 754-1985.
Sendo assim seguem algumas considerações interessantes:
- Números podem ser representados em decimal, hexadecimal, octal e em formato binário;
- Devemos sempre considerar que números negativos são representados internamente na forma de complemento de dois;
- O caractere “?” é utilizado em um número como alternativa para alta-impedância;
- O caractere “_” (underscore) pode ser utilizado como separador e qualquer em posição do número, exceto na primeira, o qual é ignorado.
Representação de números inteiros
Em um primeiro momento devemos considerar que números inteiros em Verilog seguem o seguinte formato:
<sinal><tamanho – conforme a base> ‘ valor
Com o sinal podemos representar números negativos pelo prefixo “–” (menos) e pela ausência de qualquer prefixo número positivos. Vale ratificar que Verilog representa internamente números negativos no formato de complemento de dois. Ex.: -14’h1234; // número negativo com sinal
O tamanho será sempre definido como um número decimal e define a quantidade em bits. Caso não tenha sido definido, será considerado 32 bits ou conforme as configurações do sistema. As bases utilizadas em Verilog são as seguintes:
- ‘b ou ‘B – binário. Ex.: 2’b11; // número 3 decimal representado com dois bit
- ‘h ou ‘H – hexadecimal. Ex.: 8’hAF; // número 175 decimal representado em hexadecimal com 8 bits
- ‘d ou ‘D – decimal, esta base é considerada default em Verilog. Ex.: 3; // número 3 decimal – será armazenado com 32 bits
- ‘o ou ‘O – octal. Ex.: 10’o222; // número 146 decimal representado em octal com 10 bits
O valor consiste nos dígitos entre: 0-9, A-F, a-f, x ou X e z ou Z. Sendo x ou X correspondente a valores desconhecidos e z ou Z a valores em alta-impedância. Exemplos:
- 3’bz; // corresponde a 3 bits em Z;
- 8’bx; // corresponde a 8 bits em X.
Representação de números reais
Algumas considerações:
- Verilog suporta constantes reais e variáveis;
- Converte número real em inteiro por arredondamento;
- Números reais não podem assumir valores com “Z” e “X”;
- Números reais quando atribuídos a variáveis inteiras arredondam para o inteiro mais próximo do seu valor.
Segundo [2], como manipulamos número decimais a toda hora, podemos estender o mesmo conceito à parte fracionária. Vamos tomar como exemplo o número “923.501” da página 526 do mesmo livro. Os dígitos “923.501” podem ser representados da seguinte forma:
9*10² + 2*101+3*100+5*10-1+0*10-2+1*10-3
Com esse exemplo conseguimos observar que a representação de números reais segue o seguinte formato:
<valor a esquerda>.<valor a direita>
Nesse sentido os valor a esquerda recebe o tratamento convencional em binário, entretanto o valor a direita recebem valores binários negativos. O exemplo a seguir ilustra essa afirmação, tomemos o valor 2,8125, ele é igual a: 1*21 + 0*20 + 1*2-1 + 1*2-2 + 0*2-3 + 1*2-4
A tabela 1 ilustra melhor a sequência de potências em binário.
| Tabela 1 – Potências de dois | ||||||||||||||||||||||||||||||||||||
| Potência | Valor | 22 | 4 | 21 | 2 | 20 | 1 | 2-1 | 0,5 | 2-2 | 0,25 | 2-3 | 0,125 | 2-4 | 0,0625 | 2-5 | 0,03125 | ||||||||||||||||||
| Potência | Valor | |||||||||||||||||||||||||||||||||||
| 22 | 4 | |||||||||||||||||||||||||||||||||||
| 21 | 2 | |||||||||||||||||||||||||||||||||||
| 20 | 1 | |||||||||||||||||||||||||||||||||||
| 2-1 | 0,5 | |||||||||||||||||||||||||||||||||||
| 2-2 | 0,25 | |||||||||||||||||||||||||||||||||||
| 2-3 | 0,125 | |||||||||||||||||||||||||||||||||||
| 2-4 | 0,0625 | |||||||||||||||||||||||||||||||||||
| 2-5 | 0,03125 |
A aritmética de ponto fixo
A soma e a subtração de ponto fixo não difere da soma e da subtração quando fixamos a vírgula em uma dada posição. Um bom exemplo é dado por [2], se quisermos somar 9,125 com 3,9375 basta somarmos como se os dois números fossem inteiros. Em binário a soma seria da seguinte forma (figura 1):
Em Verilog são declarados das seguintes formas valores inteiros e reais:
// Exemplo de declaração de tipos inteiros e reais
// Rodrigo Pereira - 03/05/2015
module int_pfix;
integer valor_inteiro_sinal;
integer unsigned valor_inteiro_ssinal;
real valor_real_a;
real valor_real_b;
initial begin
valor_inteiro_sinal = -14'1234;
$display ("Valor Inteiro com sinal - %h", valor_inteiro_sinal);
valor_inteiro_ssinal = 14'1234;
$display ("Valor Inteiro sem sinal - %h", valor_inteiro_ssinal);
valor_real_a = 9.125;
$display ("Valor Real A - %h", valor_real_a);
valor_real_b = 3.9375;
$display ("Valor Real B - %h", valor_real_b);
$display ("Valor Real A + B - %h", valor_real_a + valor_real_b);
end
endmodule
Representação em ponto flutuante
O padrão 754 – 1985 da IEEE é o padrão da indústria que regulamenta a representação de números com ponto flutuante. O assunto é vasto e diversas são as abordagens utilizadas na manipulação desses valores (soma/subtração/divisão/multiplicação). Sugiro ao leitor uma leitura cuidadosa quando for executar qualquer operação com esses valores.
Algumas considerações
Primeiramente , a combinação da mantissa (ou significando) multiplicado pela base na potência de 10 representa um número com ponto flutuante (figura 2). Dessa forma, um número está escrito em notação científica se a parte inteira da mantissa estiver normalizada, ou seja, se a parte inteira for maior que zero e menor que a base.
O padrão adotado pela IEEE para representar um número de 32 bits (também chamada de representação de PRECISÃO SIMPLES) é descrito na figura 3 abaixo.
Na figura 1 podemos observar que o bit 31 representa o sinal do número, seguido de mais 8 bits para o expoente da base (número inteiro) e por fim 23 bits que são reservados para a mantissa.
As operações em pontos flutuantes possuem diversos algoritmos e estudos, cada um delineado para uma aplicação específica. Em [1] na página 163 existem algoritmos e exemplos de diagramas que podem ser utilizados como um início para uma implementação. Convido novamente o leitor a uma leitura mais aprofundada do assunto. Na segunda parte deste artigo iremos tratar algumas implementações utilizando Verilog e ponto flutuante.
Referências
[1] Organização e Projeto de Computadores – 4 ª Ed. 2014. Hennessy, John L.; Patterson, David A. [2] Sistemas Digitais – Projeto, Otimização e Hdls. Vahid, Frank.










O assunto de operações com ponto flutuante é interessante porque boa parte dos códigos e discussões tratam apenas de operações com números inteiros. Parabéns pela escolha. Pretendo ler a segunda parte quando vc publicar!
me ajudou muito , obrigado
Estou com um problema no pic 18f4550. Tenho que medir uma corrente alternada e já configurei a biblioteca math.h e a minha variável é float e configurei o ad do pic certo. Porém quando quando vai até 0 ele não mostra – 1em diante. Alguém pode me ajudar? Será que o mplabx xc8 não faz isso. Já baixei o documento da microchip AN 575 MAS NÃO ME AJUDOU MUITO
Rodrigo, importante destacar que os tipos em ponto flutuante não são sintetizáveis.