“Os que tocaram, e viram a face das Górgonas, não voltaram, ou voltaram sem palavras”
Primo Levi
O sistema decimal utiliza 10 dígitos (0 até 9) e uma estrutura posicional para escrever qualquer número, ou seja, 289 pode ser escrito como
$2\cdot 10^2+8\cdot10^1+9\cdot 10^0=200+80+9=289$
de forma que podemos separar os dígitos e multiplicá-los para potências de 10 para encontrar o valor desejado. Esse sistema é chamado de base 10 ou Radix de 10. Outros sistemas comuns são base 2 ou binário, base 8 ou octal e base 16 ou hexadecimal. A base 2, de alfabeto {0,1}, é utilizada na computação digital e em componentes eletrônicos, todo programa deve ser convertido para uma sequência de 0s e 1s para ser processada pelos circuitos. Para escrever um número em binário também utilizamos a estrutura posicional, aumentando as casas da direita para a esquerda e podemos converter o número para decimal utilizando a estratégia que usamos para a base decimal, ou seja, o número 1110 é
$1\cdot 2^3+1\cdot 2^2+1\cdot 2^1+0\cdot 2^0=8+4+2=14$
No caso de conversão para frações, usamos a mesma estratégia, diminuindo as potências de 2 para números negativos ao chegar no $2^0$ . Por exemplo, o número 1110.101 é
$1\cdot 2^3+1\cdot 2^2+1\cdot 2^1+0\cdot 2^0+1\cdot2^{-1}+0\cdot 2^{-2}+1\cdot 2^{-3}=8+4+2+0.5+0.125=14.625$
No caso da conversão de decimal para binário dividimos o número na base 10 por 2 e guardamos o resto até que ele seja zero e utilizamos a sequência de restos na ordem inversa (o primeiro por último) para gerar o número binário. Um número decimal fracionário deve ser multiplicado por 2 até que o resto seja 1.
A base 16 ou hexadecimal tem 16 caracteres para representar um número, 0-9, A, B, C, D, E e F. A grande vantagem é a fácil conversão de 4-bit para 1 hexadecimal. Também é utilizada a estrutura posicional que vimos antes, ou seja, o número 10 em hex convertido na base decimal é:
$1\cdot 16^1+0\cdot 16^0=16+0=16$
Outro exemplo, 2B6:
$2\cdot 16^2+B\cdot16^1+6\cdot 16^0=2\cdot256+11\cdot16+6\cdot16=512+176+6=694$
Para converter de hexadecimal para binário basta lembrar que cada dígito hexadecimal corresponde exatamente a 4 bits. Por exemplo, o número hexadecimal 3B9 pode ser escrito em binário da seguinte forma:
3 = 0011
B = 1011
9 = 1001
Então 3B9 = 001110111001
Para representarmos números positivos e negativos em uma cadeia de bits utilizamos a notação de complemento de 2. Por exemplo, para 1 byte ou 8 bits, o primeiro dígito à esquerda é chamado de mais significativo, representa o sinal, se for 0 é positivo e se for 1 é negativo, os outros 7 bits representam a magnitude, ou o valor numérico. Porém, como temos um bit a menos agora, para escrever o maior valor em 1 byte escrevemos 01111111 = +127 e seu par negativo é o inverso ou complemento 10000000=128.
Alguns números binários chamados de códigos são especiais para processar certas funções em um sistema computacional. BCD, ou binary-coded decimal (decimal em código binário) ou 8421 BCD é uma operação de conversão para decimais mais fácil. É uma tabela de representação e uma técnica para identificar rapidamente um número decimal pelo seu binário. Por exemplo, 150 ficaria
1 = 0001
5 = 0101
0 = 0000
150 = 0001 0101 0000
Há também os números binários não ponderados, como excess-3 (XS3) e gray. O primeiro é parecido com o 8421 BCD, mas usa sempre 3 mais que o BCD.
62 em XS3 = 62 em BCD + 0011 em cada dígito
Sua utilidade é em aritmética de circuitos pois é fácil calcular o complemento, calculando não com 2, mas com 9.
O código gray não é do tipo BCD, cada incremento só altera uma mudança de bit. Isso é importante em algumas aplicações de eletrônica digital, como correção de erros e sensores.
Também podemos utilizar bits para representar outros caracteres além de dígitos. Um padrão clássico é a tabela ASCII (American Standard Code for Information Interchange), que associa sequências de bits a letras, números, sinais de pontuação e caracteres de controle.
EBCDIC (Extended Binary-Coded Decimal Interchange Code) é outro padrão de codificação de caracteres, historicamente associado a sistemas IBM.
Portas lógicas são abstrações de operações booleanas implementadas em circuitos eletrônicos. Em termos ideais, interpretamos sinais elétricos como níveis lógicos 0 e 1. A partir de portas básicas como AND, OR e NOT, podemos construir circuitos capazes de executar operações aritméticas, armazenamento e controle.
No caso do OR, usamos $A+B+C=Y$, onde a saída é zero somente se $A=B=C=0$, caso contrário, Y vale 1.
O operador NOT inverte um bit, se é 0 vira 1 e se é 1 vira 0. A entrada é sempre de uma variável, assim como a saída.
Podemos combinar as portas lógicas para formar novos padrões, por exemplo, passando as variáveis por duas portas AND que são entradas depois de uma porta OR. Disso poderíamos escrever, com três variáveis, $(A\cdot B)+(B\cdot C)= Y$, dada pela representação:
Historicamente, portas lógicas já foram implementadas com válvulas, relés e outras tecnologias eletromecânicas. Hoje, são construídas principalmente com transistores integrados em circuitos eletrônicos.
TTL: Transistor-transistor logic
CMOS: Complementary Metal Oxide Semiconductor
Outras portas lógicas, usando apenas as três já mencionadas AND, OR e NOT são: NAND, NOR, Exclusive-OR, Exclusive-NOR.
As regras da soma de dois bits são as seguintes:
a - 0+0 = 0
b - 0+1 = 1
c - 1+0 = 1
d - 1+1 = 0 e sobra 1 = 10
Com isso conseguimos escrever a tabela verdade com duas variáveis e a sobra e desenhar um circuito adequado, por exemplo, uma função XOR que produza a soma respectiva de duas variáveis e uma porta lógica AND para a sobra.
Quando há necessidade de somar três bits, como em uma soma com carry de entrada, o circuito de meia soma não é suficiente. Nesse caso, utilizamos um somador completo.
As regras de subtração são as seguintes:
a - 0-0 = 0
b - 0-1 = 1 e empresta 1
c - 1-0 = 1
d - 1-1 = 0
Da mesma forma que na soma, montamos a tabela verdade com duas variáveis e desenhamos dois circuitos: meia (HS) e subtração completa (FS).
A adição binária pode ser implementada de forma serial ou paralela. Na abordagem serial, os bits são processados ao longo do tempo, normalmente um por vez. Na abordagem paralela, vários bits são processados simultaneamente, o que tende a aumentar a velocidade ao custo de maior complexidade de hardware. O mesmo raciocínio vale para circuitos de subtração.
Também é comum construir somadores inteiros utilizando apenas full adders, configurando apropriadamente a entrada de carry inicial. Com pequenas modificações, esses mesmos circuitos podem ser adaptados para subtração, explorando complemento de dois e inversão de entradas.
Quando utilizamos números negativos precisamos novamente da regra de complemento de 2 para resolver as contas. Esse processo é muito utilizado em microprocessadores.
Circuitos combinatórios são aqueles cujo sinal de saída depende apenas das entradas, ele não tem memória de outras execuções, é composto apenas de portas lógicas. São exemplos: Codificador, decodificador, somador, comparador, multiplexador, demultiplexador.
Quando criamos expressões booleanas e analisamos a tabela-verdade correspondente, percebemos que nem sempre a implementação inicial é a mais simples. Em muitos casos, podemos substituir circuitos complexos por equivalentes com menos portas lógicas, menor profundidade ou menor custo de implementação. Em problemas mais complexos, também podem ser usados multiplexadores, decodificadores, PLAs, ROMs e PROMs.
Há duas formas padrão de expressar as funções booleanas:
Para $n$ variáveis, temos $2^n$ combinações de mintermos. Por exemplo, com duas variáveis, temos:
$$ \bar{A}\bar{B}, \bar{A}B, A\bar{B}, AB $$Um mintermo sempre usa uma porta tipo AND.
No maxtermo, temos a porta tipo OR, em uma soma do tipo: $A+B+C$.
Um maxtermo / mintermo pode ser convertido para mintermo / maxtermo, são complementares um ao outro. Exemplo, provar que $M_1=m_1$, onde $M$ é maxtermo e $m$ é um mintermo:
$$ M_1=A+B+\bar{C} \\ \bar{M_1}=\bar{A+B+\bar{C}}=\bar{A}\bar{B}C=m_1 $$Onde utilizamos o teorema de DeMorgan. Qualquer função booleana pode ser expressa através da soma de mintermos ou produto de maxtermos, nesse caso, é chamada de forma canônica.
Podemos usar a notação $f(A,B,C)$ para a expressão. Por exemplo : $f(A,B,C)=A+\bar{B}C$, que pode ser reescrita como:
$$ f(A,B,C)=A(B+\bar{B})+(A+\bar{A})\bar{B}C \\ =AB+A\bar{B}+A\bar{B}C+\bar{A}\bar{B}C \\ =\bar{A}\bar{B}C+A\bar{B}\bar{C}+A\bar{B}C+AB\bar{C}+ABC \\ =m_1+m+4+m_5+m_6+m_7= \Sigma (1,4,5,6,7) $$Nem sempre a expressão booleana inicialmente obtida é a mínima possível. A minimização pode ter diferentes objetivos: reduzir o número de literais, o número de portas, a profundidade lógica do circuito ou o número de entradas por porta.
Podemos usar a álgebra booleana e os teoremas de Morgan para simplificar e converter da forma soma de produtos para produto das somas e vice-versa, além de se livrar de inversões indesejadas. Os quatro passos para usar os teoremas são:
Como portas NAND e NOR são funcionais completas, elas podem ser usadas para implementar qualquer circuito booleano. Em muitos contextos, isso simplifica fabricação e padronização. Os passos para converter uma função AND-OR para NAND são:
Nem sempre isso resulta em um circuito mais simples, mas pode ser preferido por usar menos portas.
No caso de um circuito OR-AND usamos uma porta do tipo NOR para substituição.
Implicante primário: No mapa de Karnaugh é o agrupamento de células com tamanho máximo;
Don’t care: a saída para certas combinações não importa (0 ou 1).
Método Tabular ou Algoritmo Quine-McCluskey: procedimento para extração de implicantes primários e pode ser usada para construir algoritmo iterativo;
O projeto de um circuito combinacional costuma partir da especificação do comportamento desejado. Em seguida, definem-se entradas e saídas, constrói-se a tabela-verdade, obtêm-se as expressões booleanas equivalentes, simplificam-se essas expressões e finalmente mapeia-se a solução para a biblioteca de portas disponível. O mapa de Karnaugh é uma das ferramentas clássicas para essa etapa de simplificação.
Componentes sequenciais diferem dos combinacionais porque sua saída depende não apenas das entradas atuais, mas também do estado anterior do circuito. Em outras palavras, eles incorporam memória. Essa memória pode ser usada para armazenar informação temporária, coordenar etapas de processamento e implementar controle de estados.
Circuitos sequenciais são aqueles cuja saída depende não apenas das entradas atuais, mas também de estados anteriores. Por isso, são frequentemente chamados de circuitos com memória. Exemplos incluem contadores, registradores e controladores. Para armazenar dados e estados, usam-se elementos como latches e flip-flops.
Um flip-flop J-K é um tipo de circuito lógico sequencial que pode armazenar e manipular informações binárias. É composto de múltiplas portas lógicas e é comumente usado em eletrônica digital e sistemas de computador para diversos fins, incluindo armazenamento de dados, divisão de frequência e geração de sinal de controle.
O flip-flop J-K tem duas entradas: J (set) e K (reset). Também possui duas saídas: Q (saída normal) e Q̅ (saída complementar). O estado do flip-flop é determinado por suas entradas atuais (J e K) e seu estado anterior.
O comportamento de um flip-flop J-K pode ser resumido da seguinte forma:
Quando as entradas J e K são 0, o flip-flop permanece em seu estado atual (sem alteração).
Quando J é 1 e K é 0, o flip-flop define o estado "SET", onde Q torna-se 1 e Q̅ torna-se 0.
Quando J é 0 e K é 1, o flip-flop é redefinido para o estado "RESET", onde Q torna-se 0 e Q̅ torna-se 1.
Quando as entradas J e K são 1, o flip-flop alterna ou altera seu estado. Se o estado anterior era "SET", ele se tornará "RESET" e vice-versa.
O flip-flop J-K pode ser pensado como uma extensão do flip-flop SR (Set-Reset) mais simples. Ele supera o problema da combinação de entrada proibida (entradas S e R sendo 1), que pode causar comportamento imprevisível no flip-flop SR. O flip-flop J-K introduz a funcionalidade de alternância, permitindo que a combinação de entrada de J e K seja 1.
Ao conectar vários flip-flops J-K juntos, é possível criar circuitos sequenciais mais complexos, como contadores, registradores de deslocamento e unidades de memória. Esses circuitos encontram aplicações em vários sistemas digitais, incluindo microprocessadores, dispositivos de comunicação e sistemas de controle.
Uma máquina de estados finitos (FSM, Finite State Machine) é um modelo abstrato que, em cada instante, pode ocupar apenas um entre um conjunto finito de estados. A mudança entre estados é chamada de transição e depende, em geral, das entradas recebidas e do estado atual. Uma FSM é descrita por seus estados, pelo estado inicial, pelas transições e, em muitos casos, por saídas associadas aos estados ou às transições.
Do ponto de vista teórico, uma FSM tem poder computacional limitado quando comparada a modelos mais gerais, como a máquina de Turing, justamente porque sua memória é finita. Ainda assim, ela é extremamente útil na modelagem de controladores, protocolos, interfaces, sequenciadores e circuitos de controle digital.
Um exemplo de FSM é uma catraca, equipamento utilizado para controle de acesso.
O diagrama de estados pode ser representado por um grafo direcionado, no qual cada estado é um nó e cada transição é uma aresta orientada.
Classificação de FSM:
Acceptors: produzem uma resposta binária indicando se uma determinada entrada é aceita ou rejeitada.
Transducers: produzem saídas associadas às entradas e aos estados, sendo comuns em circuitos de controle e processamento de sinais.
Generators ou sequencers: modelos que geram sequências de símbolos ou estados segundo regras de transição previamente definidas.
Um circuito sequencial assíncrono tem elementos que dependem do atraso das entradas e podem ser alterados em qualquer momento, devido às mudanças das entradas. A propagação de atraso não é fixa, depende de várias outras partes. É um tipo de circuito que pode ser visualizado como um combinacional com realimentação.
Um circuito sequencial síncrono utiliza um sinal de relógio, ou clock, para coordenar as mudanças de estado. Toda atualização relevante ocorre em instantes definidos por esse sinal, normalmente em uma borda de subida ou de descida. O período do clock é o inverso da frequência de operação.
O elemento clássico de memória em circuitos sequenciais é o flip-flop. Ele armazena, em geral, um bit de informação e atualiza seu estado conforme entradas de dados e sinais de controle, muitas vezes sincronizados por clock. Enquanto o circuito permanecer energizado e dentro das condições de operação, o estado armazenado pode ser preservado até que uma nova transição o altere.
O tipo mais básico de elemento de armazenamento é o latch, sensível a nível. A partir dele, são construídos flip-flops sensíveis a borda, muito usados em projetos síncronos. Entre os tipos mais comuns, destacam-se:
Latch RS: construído com realimentação entre portas lógicas, permitindo armazenamento simples de estado.
Latch D: evita combinações inválidas ao concentrar a informação de entrada em uma única linha de dados.
Flip-flop D: amplamente usado em registradores e pipelines, atualizando seu valor em uma borda do clock.
Flip-flops JK e T: úteis em contadores, divisores de frequência e circuitos de controle.
A cada transição de estados podemos montar uma tabela de transição, para cada tipo de flip-flop. Certos estados são denominados proibidos ou indeterminados, além dos estados de reset 0 e set 1.
Sistemas hierárquicos foram criados para lidar com a complexidade crescente de circuitos grandes, dividindo-os em blocos ou módulos menores que podem ser projetados separadamente e depois integrados. Cada módulo representa um subproblema com interfaces bem definidas.
Uma estratégia para particionar o sistema em módulos é através do “dividir e conquistar”, ou seja, quebrar o sistema original em partes menores e interligá-los. Deve-se separar primeiramente em fluxo de dados e unidade de controle.
Classificação dos recursos no fluxo de dados: funcionais, memória e interface.
No projeto da unidade de controle, é comum utilizar diagramas ASM (Algorithmic State Machine), semelhantes a máquinas de estados finitos, mas voltados à descrição de operações de controle, decisões e saídas condicionais. Em implementações modernas, essa descrição costuma ser feita em linguagens de descrição de hardware, como VHDL ou Verilog.
O projeto de sistemas digitais não envolve apenas quais funções booleanas devem ser implementadas, mas também quando cada operação deve ocorrer e como os sinais de controle coordenam o comportamento do circuito. Por isso, conceitos de controle e de tempo são centrais na engenharia digital.
No aspecto temporal, analisamos atrasos de propagação, tempos de setup e hold, frequência de clock, sincronização entre blocos e possíveis hazards ou glitches. Um circuito logicamente correto pode falhar se esses requisitos temporais não forem respeitados.
No aspecto de controle, definimos como sinais habilitam registradores, selecionam multiplexadores, disparam operações aritméticas e comandam transições de estado. Em projetos maiores, a lógica de controle costuma ser separada do caminho de dados, permitindo organização mais clara e manutenção mais simples.
Fabricantes de circuitos integrados desenvolveram diferentes famílias lógicas para implementação de sistemas digitais. Essas famílias variam em tecnologia de fabricação, consumo de energia, velocidade de comutação, imunidade a ruído e compatibilidade elétrica. Historicamente, destacam-se famílias bipolares e famílias MOS.
Também é comum classificar circuitos integrados pelo nível de integração:
SSI (Small-scale integration): menos do que 12 portas.
MSI (Medium-scale integration): de 12 até 99 portas. Usado em somadores, contadores, decodificadores, encodificadores, multiplexadores e registros.
LSI (large-scale integration): de 100 até 9999 portas. Relógios digitais, chips de memória, calculadoras.
VLSI (very-large-scale integration): de 10000 até 99999 portas. Microprocessadores, chips grandes de memória e calculadoras avançadas.
ULSI (ultra-large-scale integration): mais de 100000 portas. Microprocessadores avançados.
Entre as famílias bipolares, destacam-se:
RTL (Resistor-transistor logic)
DTL (diode-transistor logic)
TTL (Transistor-transistor logic)
ECL (Emitter-coupled logic)
HTL (High-threshold logic)
ITL (Integrated-injection logic)
Entre as famílias MOS (Metal-Oxide Semiconductor), destacam-se:
PMOS (P-channel metal-oxide semiconductor)
NMOS (N-channel metal-oxide semiconductor)
CMOS (complementary metal-oxide semiconductor)
Dispositivos lógicos programáveis são componentes eletrônicos que permitem implementar funções digitais configuráveis após a fabricação. Em vez de produzir um circuito fixo para cada aplicação, o projetista programa a estrutura interna do dispositivo conforme a lógica desejada.
Essa abordagem facilita prototipagem, reuso, redução de espaço físico e implementação de circuitos complexos. Entre as principais categorias estão:
SPLDs (Simple Programmable Logic Devices), incluindo PAL (Programmable Array Logic) e GAL (Generic Array Logic).
CPLDs (Complex Programmable Logic Devices).
FPGAs (Field-Programmable Gate Arrays).
EPLDs (Erasable Programmable Logic Devices).
Referências: