Unidade lógica aritmética - Arithmetic logic unit

Uma representação simbólica de uma ALU e seus sinais de entrada e saída, indicados por setas apontando para dentro ou para fora da ALU, respectivamente. Cada seta representa um ou mais sinais. Os sinais de controle entram pela esquerda e os sinais de status saem pela direita; os dados fluem de cima para baixo.

Na computação , uma unidade lógica aritmética (ALU) é um circuito digital combinacional que realiza operações aritméticas e bit a bit em números binários inteiros . Isso está em contraste com uma unidade de ponto flutuante (FPU), que opera em números de ponto flutuante . É um bloco de construção fundamental de muitos tipos de circuitos de computação, incluindo a unidade de processamento central (CPU) de computadores, FPUs e unidades de processamento gráfico (GPUs).

As entradas de uma ALU são os dados a serem operados, chamados operandos , e um código que indica a operação a ser executada; a saída da ALU é o resultado da operação realizada. Em muitos projetos, a ALU também possui entradas ou saídas de status, ou ambas, que transmitem informações sobre uma operação anterior ou a operação atual, respectivamente, entre a ALU e os registradores de status externos .

Sinais

Uma ALU tem uma variedade de redes de entrada e saída , que são os condutores elétricos usados ​​para transmitir sinais digitais entre a ALU e os circuitos externos. Quando uma ALU está operando, os circuitos externos aplicam sinais às entradas da ALU e, em resposta, a ALU produz e transmite sinais aos circuitos externos por meio de suas saídas.

Dados

Uma ALU básica tem três barramentos de dados paralelos que consistem em dois operandos de entrada ( A e B ) e uma saída de resultado ( Y ). Cada barramento de dados é um grupo de sinais que transporta um número inteiro binário. Normalmente, as larguras dos barramentos A, B e Y (o número de sinais que compõem cada barramento) são idênticas e correspondem ao tamanho da palavra nativa do circuito externo (por exemplo, a CPU de encapsulamento ou outro processador).

Código de operação

A entrada do opcode é um barramento paralelo que transmite à ALU um código de seleção de operação, que é um valor enumerado que especifica a operação aritmética ou lógica desejada a ser executada pela ALU. O tamanho do opcode (sua largura de barramento) determina o número máximo de diferentes operações que a ALU pode realizar; por exemplo, um opcode de quatro bits pode especificar até dezesseis operações ALU diferentes. Geralmente, um opcode ALU não é o mesmo que um opcode em linguagem de máquina , embora em alguns casos ele possa ser codificado diretamente como um campo de bits dentro de um opcode em linguagem de máquina.

Status

Saídas

As saídas de status são vários sinais individuais que transmitem informações suplementares sobre o resultado da operação da ALU atual. ALUs de uso geral geralmente têm sinais de status como:

  • Carry-out , que transmite o carry resultante de uma operação de adição, o empréstimo resultante de uma operação de subtração ou o bit de estouro resultante de uma operação de deslocamento binário.
  • Zero , que indica que todos os bits de Y são zero lógico.
  • Negativo , que indica que o resultado de uma operação aritmética é negativo.
  • Overflow , que indica que o resultado de uma operação aritmética excedeu o intervalo numérico de Y.
  • Paridade , que indica se um número par ou ímpar de bits em Y é um lógico.

Após a conclusão de cada operação da ALU, os sinais de saída de status são geralmente armazenados em registros externos para torná-los disponíveis para futuras operações da ALU (por exemplo, para implementar aritmética de precisão múltipla ) ou para controlar ramificações condicionais . A coleção de registradores de bits que armazenam as saídas de status é freqüentemente tratada como um único registrador de vários bits, que é referido como "registro de status" ou "registro de código de condição".

Entradas

As entradas de status permitem que informações adicionais sejam disponibilizadas para a ALU ao executar uma operação. Normalmente, este é um único bit "carry-in" que é o carry-out armazenado de uma operação ALU anterior.

Operação do circuito

O circuito lógico combinacional do circuito integrado 74181 , que é uma ALU simples de quatro bits

Uma ALU é um circuito lógico combinacional , o que significa que suas saídas mudarão de forma assíncrona em resposta às mudanças de entrada. Em operação normal, sinais estáveis ​​são aplicados a todas as entradas da ALU e, quando tempo suficiente (conhecido como " atraso de propagação ") tiver passado para os sinais se propagarem através dos circuitos da ALU, o resultado da operação da ALU aparece na ALU saídas. O circuito externo conectado à ALU é responsável por garantir a estabilidade dos sinais de entrada da ALU ao longo da operação e por permitir tempo suficiente para que os sinais se propaguem através da ALU antes de amostrar o resultado da ALU.

Em geral, os circuitos externos controlam uma ALU aplicando sinais às suas entradas. Normalmente, o circuito externo emprega lógica sequencial para controlar a operação da ALU, que é estimulada por um sinal de relógio de frequência suficientemente baixa para garantir tempo suficiente para que as saídas da ALU se acomodem nas piores condições.

Por exemplo, uma CPU inicia uma operação de adição da ALU roteando operandos de suas fontes (que geralmente são registros) para as entradas de operandos da ALU, enquanto a unidade de controle aplica simultaneamente um valor à entrada do opcode da ALU, configurando-a para realizar a adição. Ao mesmo tempo, a CPU também encaminha a saída do resultado da ALU para um registrador de destino que receberá a soma. Os sinais de entrada da ALU, que são mantidos estáveis ​​até o próximo relógio, podem se propagar através da ALU e para o registrador de destino enquanto a CPU espera pelo próximo relógio. Quando o próximo relógio chega, o registrador de destino armazena o resultado da ALU e, uma vez que a operação da ALU foi concluída, as entradas da ALU podem ser configuradas para a próxima operação da ALU.

Funções

Uma série de funções aritméticas básicas e lógicas bit a bit são comumente suportadas por ALUs. ALUs básicas de uso geral geralmente incluem essas operações em seus repertórios:

Operaçoes aritimeticas

  • Adicionar : A e B são somados e a soma aparece em Y e carry-out.
  • Adicionar com carry : A, B e carry-in são somados e a soma aparece em Y e carry-out.
  • Subtrair : B é subtraído de A (ou vice-versa) e a diferença aparece em Y e efetua-se. Para esta função, a execução é efetivamente um indicador de "empréstimo". Esta operação também pode ser usada para comparar as magnitudes de A e B; em tais casos, a saída Y pode ser ignorada pelo processador, que está interessado apenas nos bits de status (particularmente zero e negativo) que resultam da operação.
  • Subtrair com emprestar : B é subtraído de A (ou vice-versa) com emprestar (carry-in) e a diferença aparece em Y e realizar (emprestar).
  • Complemento de dois (negar) : A (ou B) é subtraído de zero e a diferença aparece em Y.
  • Incremento : A (ou B) é aumentado em um e o valor resultante aparece em Y.
  • Decremento : A (ou B) é diminuído em um e o valor resultante aparece em Y.
  • Passagem : todos os bits de A (ou B) aparecem inalterados em Y. Esta operação é normalmente usada para determinar a paridade do operando ou se é zero ou negativo, ou para carregar o operando em um registrador do processador.

Operações lógicas bit a bit

  • AND : o bit a bit AND de A e B aparece em Y.
  • OR : o bit a bit OR de A e B aparece em Y.
  • OR exclusivo : o XOR bit a bit de A e B aparece em Y.
  • Complemento de uns : todos os bits de A (ou B) são invertidos e aparecem em Y.

Operações de bit shift

Exemplos de bit shift para uma ALU de oito bits
Modelo Deixou Direito
Mudança aritmética Girar para a esquerda logicamente.svg Girar para a direita aritmeticamente.svg
Mudança lógica Girar para a esquerda logicamente.svg Girar para a direita logicamente.svg
Girar Girar para a esquerda.svg Girar para a direita.svg
Rodar através do transporte Gire para a esquerda através de carry.svg Gire para a direita em carry.svg

Operações de deslocamento de UTA causar operando A (ou B) para deslocamento para a esquerda ou para a direita (de acordo com o código de operação) e o deslocada operando aparece no Y. ULAs simples tipicamente pode deslocar o operando por apenas uma posição de bit, enquanto que mais complexas ULAs empregam barrei shifters que permitem que eles desloquem o operando por um número arbitrário de bits em uma operação. Em todas as operações de deslocamento de bit único, o bit deslocado para fora do operando aparece na execução; o valor do bit deslocado para o operando depende do tipo de deslocamento.

  • Deslocamento aritmético : o operando é tratado como uminteiro complemento de dois , o que significa que o bit mais significativo é um bit de "sinal" e é preservado.
  • Mudança lógica : um zero lógico é deslocado para o operando. Isso é usado para deslocar números inteiros sem sinal.
  • Girar : o operando é tratado como um buffer circular de bits, de forma que seus bits menores e mais significativos sejam efetivamente adjacentes.
  • Rotate through carry : o carry e o operando são tratados coletivamente como um buffer circular de bits.

Formulários

Aritmética de precisão múltipla

Em cálculos aritméticos inteiros, a aritmética de precisão múltipla é um algoritmo que opera em inteiros maiores que o tamanho da palavra ALU. Para fazer isso, o algoritmo trata cada operando como uma coleção ordenada de fragmentos de tamanho de ALU, organizados do mais significativo (MS) ao menos significativo (LS) ou vice-versa. Por exemplo, no caso de uma ALU de 8 bits, o inteiro de 24 bits 0x123456seria tratado como uma coleção de três fragmentos de 8 bits: 0x12(MS) 0x34, e 0x56(LS). Como o tamanho de um fragmento corresponde exatamente ao tamanho da palavra da ALU, a ALU pode operar diretamente neste "pedaço" do operando.

O algoritmo usa a ALU para operar diretamente em fragmentos de operandos específicos e, assim, gerar um fragmento correspondente (uma "parcial") do resultado de precisão múltipla. Cada parcial, quando gerado, é gravado em uma região associada de armazenamento que foi designada para o resultado de precisão múltipla. Este processo é repetido para todos os fragmentos de operandos de modo a gerar uma coleção completa de parciais, que é o resultado da operação de precisão múltipla.

Em operações aritméticas (por exemplo, adição, subtração), o algoritmo começa invocando uma operação ALU nos fragmentos LS dos operandos, produzindo assim um bit parcial de LS e um bit de execução. O algoritmo grava o parcial no armazenamento designado, enquanto a máquina de estado do processador normalmente armazena o bit de execução em um registrador de status da ALU. O algoritmo então avança para o próximo fragmento da coleção de cada operando e invoca uma operação ALU nesses fragmentos junto com o bit de transporte armazenado da operação ALU anterior, produzindo assim outro (mais significativo) parcial e um bit de execução. Como antes, o bit de transporte é armazenado no registrador de status e o parcial é gravado no armazenamento designado. Esse processo se repete até que todos os fragmentos de operando tenham sido processados, resultando em uma coleção completa de parciais no armazenamento, que compõem o resultado aritmético de multiprecisão.

Em operações de deslocamento de precisão múltipla, a ordem de processamento do fragmento do operando depende da direção do deslocamento. Em operações de deslocamento à esquerda, os fragmentos são processados ​​LS primeiro porque o bit LS de cada parcial - que é transmitido por meio do bit de transporte armazenado - deve ser obtido do bit MS do operando anteriormente deslocado à esquerda e menos significativo. Por outro lado, os operandos são processados ​​MS primeiro em operações de deslocamento à direita porque o bit MS de cada parcial deve ser obtido do bit LS do operando anteriormente deslocado à direita, mais significativo.

Em operações lógicas bit a bit (por exemplo, AND lógico, OR lógico), os fragmentos de operando podem ser processados ​​em qualquer ordem arbitrária porque cada parcial depende apenas dos fragmentos de operando correspondentes (o bit de transporte armazenado da operação ALU anterior é ignorado).

Operações complexas

Embora uma ALU possa ser projetada para executar funções complexas, a maior complexidade do circuito, custo, consumo de energia e tamanho maior resultantes tornam isso impraticável em muitos casos. Conseqüentemente, as ALUs são freqüentemente limitadas a funções simples que podem ser executadas em velocidades muito altas (isto é, atrasos de propagação muito curtos), e o circuito do processador externo é responsável por executar funções complexas orquestrando uma sequência de operações ALU mais simples.

Por exemplo, o cálculo da raiz quadrada de um número pode ser implementado de várias maneiras, dependendo da complexidade da ALU:

  • Cálculo em um único relógio : uma ALU muito complexa que calcula uma raiz quadrada em uma operação.
  • Pipeline de cálculo : um grupo de ALUs simples que calcula uma raiz quadrada em estágios, com resultados intermediários passando por ALUs organizados como uma linha de produção de fábrica. Este circuito pode aceitar novos operandos antes de terminar os anteriores e produz resultados tão rápidos quanto a ALU muito complexa, embora os resultados sejam atrasados ​​pela soma dos atrasos de propagação dos estágios da ALU. Para obter mais informações, consulte o artigo sobre pipelining de instruções .
  • Cálculo iterativo : uma ALU simples que calcula a raiz quadrada por meio de várias etapas sob a direção de uma unidade de controle .

As implementações acima fazem a transição da mais rápida e cara para a mais lenta e menos cara. A raiz quadrada é calculada em todos os casos, mas os processadores com ALUs simples levarão mais tempo para realizar o cálculo porque várias operações ALU devem ser realizadas.

Implementação

Uma ALU é geralmente implementada como um circuito integrado autônomo (IC), como o 74181 , ou como parte de um IC mais complexo. No último caso, uma ALU é tipicamente instanciada sintetizando-a a partir de uma descrição escrita em VHDL , Verilog ou alguma outra linguagem de descrição de hardware . Por exemplo, o seguinte código VHDL descreve uma ALU de 8 bits muito simples :

entity alu is
port (  -- the alu connections to external circuitry:
  A  : in signed(7 downto 0);   -- operand A
  B  : in signed(7 downto 0);   -- operand B
  OP : in unsigned(2 downto 0); -- opcode
  Y  : out signed(7 downto 0));  -- operation result
end alu;

architecture behavioral of alu is
begin
 case OP is  -- decode the opcode and perform the operation:
 when "000" =>  Y <= A + B;   -- add
 when "001" =>  Y <= A - B;   -- subtract
 when "010" =>  Y <= A - 1;   -- decrement
 when "011" =>  Y <= A + 1;   -- increment
 when "100" =>  Y <= not A;   -- 1's complement
 when "101" =>  Y <= A and B; -- bitwise AND
 when "110" =>  Y <= A or B;  -- bitwise OR
 when "111" =>  Y <= A xor B; -- bitwise XOR
 when others => Y <= (others => 'X');
 end case; 
end behavioral;

História

O matemático John von Neumann propôs o conceito de ALU em 1945 em um relatório sobre as bases para um novo computador chamado EDVAC .

O custo, o tamanho e o consumo de energia dos circuitos eletrônicos foram relativamente altos durante a infância da era da informação . Conseqüentemente, todos os computadores seriais e muitos dos primeiros computadores, como o PDP-8 , tinham uma ALU simples que operava em um bit de dados por vez, embora muitas vezes apresentasse um tamanho de palavra mais amplo para os programadores. Um dos primeiros computadores a ter vários circuitos ALU discretos de bit único foi o Whirlwind I de 1948 , que empregava dezesseis dessas "unidades matemáticas" para permitir que operasse em palavras de 16 bits.

Em 1967, a Fairchild introduziu a primeira ALU implementada como um circuito integrado, o Fairchild 3800, consistindo em uma ALU de oito bits com acumulador. Outras ALUs de circuito integrado surgiram logo, incluindo ALUs de quatro bits, como Am2901 e 74181 . Esses dispositivos eram tipicamente capazes de " bit slice ", o que significa que tinham sinais de "carry look ahead" que facilitavam o uso de vários chips ALU interconectados para criar uma ALU com um tamanho de palavra mais amplo. Esses dispositivos rapidamente se tornaram populares e foram amplamente usados ​​em minicomputadores bit-slice.

Os microprocessadores começaram a aparecer no início dos anos 1970. Embora os transistores tivessem se tornado menores, muitas vezes havia espaço insuficiente no molde para uma ALU de largura de palavra inteira e, como resultado, alguns dos primeiros microprocessadores empregavam uma ALU estreita que exigia vários ciclos por instrução de linguagem de máquina. Exemplos disso incluem o popular Zilog Z80 , que executava adições de oito bits com uma ALU de quatro bits. Com o tempo, as geometrias do transistor encolheram ainda mais, seguindo a lei de Moore , e tornou-se viável construir ALUs mais amplas em microprocessadores.

Os transistores de circuito integrado (IC) modernos são ordens de magnitude menores do que os dos primeiros microprocessadores, tornando possível encaixar ALUs altamente complexos em ICs. Hoje, muitas ALUs modernas têm larguras de palavras amplas e aprimoramentos arquitetônicos, como deslocadores de barril e multiplicadores binários, que lhes permitem realizar, em um único ciclo de clock, operações que teriam exigido várias operações em ALUs anteriores.

As ALUs podem ser realizadas como circuitos mecânicos , eletromecânicos ou eletrônicos e, nos últimos anos, pesquisas em ALUs biológicas foram realizadas (por exemplo, baseadas em actina ).

Veja também

Referências

Leitura adicional

links externos