53 / 63 · Conceito
Ponto fixo, arredondamento e saturação
Defina intervalos com W,F e implemente arredondamento para o par com guard/sticky e saturação posterior.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
Pré-requisitos: larguras de soma e multiplicação signed, deslocamento aritmético à direita e overflow.
Estabeleça a posição fracionária dos bits
Em ponto fixoPonto fixo Representação que fixa previamente a posição do separador fracionário e aplica uma escala constante a uma sequência de bits inteira. É preciso definir largura, sinal e número de bits fracionários., o inteiro X representa . Não se armazena um «bit de vírgula». Aqui W é a largura signed completa, incluindo o sinal, e F é a quantidade de bits fracionários. A notação Q varia conforme inclua o sinal na parte inteira; indicar W,F na interface evita ambiguidade.
Com W=8,F=4, o passo é 1/16 e o intervalo vai de −8 a 7.9375. 0x18 representa 1.5 nesse contrato, não o inteiro 24; com F=3, representaria 3. Conectar fios não garante coerência numérica: documente a escala de cada porta.
Antes de somar, alinhe as posições fracionárias. Se F diferir, estenda suficientemente o operando de menor F e desloque-o à esquerda, ou reduza o de maior F com o arredondamento escolhido. A soma exata de dois valores com o mesmo W,F exige W+1 bits e o mesmo F. Na multiplicação, multiplicam-se os inteiros raw e somam-se seus bits fracionários:
O produto completo de dois operandos de oito bits F=4 é signed de 16 bits F=8. Para devolver oito bits F=4, reduza quatro bits fracionários e confira depois o intervalo signed de oito bits. Truncar primeiro o produto para oito bits destrói a magnitude de que a saturação precisaria.
Truncamento e arredondamento
Um deslocamento aritmético à direita de d bits calcula , arredondando para baixo também no caso de valores negativos. Com , o quociente exato é −1.5 e q=−2, diferente de truncar em direção a zero. Selecionar apenas os bits superiores não tem necessariamente o mesmo comportamento de erro para positivos e negativos.
Vamos projetar arredondamento ao mais próximo com empates para o par. Seja g o bit superior descartado (guard), t a OR dos restantes (sticky) e l o bit inferior do q mantido.
Com g=0, a fração é menor que a metade e q é mantido. Com g=1,t=1, supera a metade e é incrementado. Com g=1,t=0, é exatamente metade e soma-se 1 somente se q for ímpar. A regra também vale para negativos: com o quociente inferior q, o resto sempre satisfaz .
Assim, −24/16=−1.5 arredonda para −2 porque q=−2 é par; −40/16=−2.5 arredonda para −2 porque q=−3 é ímpar. Uma regra adicional de «sempre subtrair 1 dos negativos» seria incorreta. Sem saturação, o erro final não supera meio LSBLSB Bit de menor peso. É preciso conferir em conjunto o sentido da notação e as regras de indexação. Saiba mais da saída. Empates para o par reduzem o viés de resolver todos os empates para um lado, mas não garantem erro médio zero para toda distribuição.
Na conversão de raw P=2040, 16 bits F=8 para oito bits F=4, 127.5 arredonda para o par 128 e depois é limitado a 127. Preserve a largura ampla até o armazenamento final.
- Entrada P=2040: 16 bits · F=8
- Reduza a escala: 2040 / 16 = 127.5
- Empates para o par: Raw arredondado = 128
- Armazene após saturar: raw 127 → 7.9375
Sature depois de concluir o arredondamento
Saturar limita o valor ao máximo ou ao mínimo quando esses limites são excedidos. Ao contrário do retorno modular, um positivo grande não vira negativo. Um valor já truncado e com wrap não permite saturar corretamente.
O módulo combinacional abaixo converte signed de 16 bits F=8 para oito bits F=4. Com d=4, guard=p[3] e sticky=p[2:0]. Incremento e comparação são feitos em signed de 17 bits e apenas ao final são mantidos oito bits.
module requantize (
input logic signed [15:0] p,
output logic signed [7:0] y,
output logic saturated
);
logic signed [16:0] wide, q, rounded;
logic inc;
always_comb begin
wide = {p[15], p};
q = wide >>> 4;
inc = p[3] & ((|p[2:0]) | q[0]);
rounded = q + (inc ? 17'sd1 : 17'sd0);
saturated = 1'b0;
if (rounded > 17'sd127) begin
y = 8'sh7f;
saturated = 1'b1;
end else if (rounded < -17'sd128) begin
y = 8'sh80;
saturated = 1'b1;
end else begin
y = rounded[7:0];
end
end
endmoduleP=2040 produz 127.5, arredonda para 128 e satura em 127: valor final 7.9375. Verificar apenas q=127 antes de arredondar perde esse excesso. saturated indica limitação pelo intervalo, não apenas perda de bits fracionários.
Ao generalizar, separe d=0, sem bits descartados, e d=1, sem região sticky. Esconder uma seleção inválida num condicional pode não evitar erro de elaboração.
Arredondamento e saturação acrescentam somadores, comparadores, MUXMultiplexador Circuito combinacional que conecta uma dentre várias entradas à saída conforme um sinal de seleção. É preciso especificar a correspondência entre os bits de seleção e os números das entradas. Saiba mais e atraso, e são escolhidos como políticas independentes; veja os formatos de ponto fixo da AMD. Ao acumular vários termos, decida se mantém largura intermediária e converte uma única vez ao final. Saturar a cada passo pode quebrar a associatividade; arredondar a cada passo pode acumular pequenos erros.
Experimente
Converta P signed de 16 bits F=8 para signed de 8 bits F=4 para 24,40,−24,−40,2040. Calcule quociente para baixo q, guard/sticky, inteiro arredondado, raw final e valor real. O que falha ao verificar saturação antes de arredondar 2040?
Ler a explicação
Os quatro bits baixos são sempre 1000: guard=1, sticky=0. P=24: q=1 ímpar→2, raw=2, valor 0.125. P=40: q=2 par→2, raw=2, 0.125. P=−24: q=−2 par→−2, raw=−2, −0.125. P=−40: q=−3 ímpar→−2, raw=−2, −0.125. P=2040: q=127 ímpar→128; excede signed de 8 bits, portanto raw=127, valor 7.9375, saturated=1. Conferir apenas q=127 e depois somar em oito bits pode retornar a 0x80 e produzir −8. Termine incremento e comparação num signed largo.