Registradores e Contadores
Vídeo da aula estará disponível em breve
Registradores
Um registrador é um grupo de flip-flops que armazena uma palavra binária de n bits. Todos os flip-flops compartilham o mesmo clock, atualizando simultaneamente. Registradores são os blocos de armazenamento mais rápidos dentro de um processador.
Registrador de carga paralela
4 flip-flops D com clock comum e sinal LOAD:
D₃──┤MUX├──┤D FF├── Q₃
Q₃──┘ ↑ CLK
LOAD
D₂──┤MUX├──┤D FF├── Q₂
Q₂──┘ ↑ CLK
LOAD
D₁──┤MUX├──┤D FF├── Q₁
Q₁──┘ ↑ CLK
LOAD
D₀──┤MUX├──┤D FF├── Q₀
Q₀──┘ ↑ CLK
LOAD
Quando LOAD=1: Q(next) = D (carrega dados de entrada)
Quando LOAD=0: Q(next) = Q (mantém valor atual)
Na CPU, registradores como $t0, $s0 no MIPS funcionam assim:
a instrução determina quando LOAD é ativado.
Registrador de deslocamento (Shift Register)
Um shift register desloca os bits em uma posição a cada pulso de clock. A saída de cada flip-flop alimenta a entrada do próximo:
Serial In, Serial Out (SISO):
Dᵢₙ ──┤D FF₃├──┤D FF₂├──┤D FF₁├──┤D FF₀├── Dₒᵤₜ
CLK CLK CLK CLK
└────────┴────────┴────────── clock comum
Diagrama de tempo (entrada serial: 1011):
CLK: ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
Dᵢₙ: 1 0 1 1 0 0 0 0
FF₃: 1 0 1 1 0 0 0 0
FF₂: - 1 0 1 1 0 0 0
FF₁: - - 1 0 1 1 0 0
FF₀: - - - 1 0 1 1 0
↑ dado completo disponível
São 4 clocks para carregar 4 bits serialmente.
Compare com o registrador paralelo: 1 clock para 4 bits.
Classificação por entrada/saída:
SISO — Serial In, Serial Out
Uso: linhas de atraso, buffering serial
SIPO — Serial In, Parallel Out
Uso: conversão serial→paralelo (receptor UART)
PISO — Parallel In, Serial Out
Uso: conversão paralelo→serial (transmissor UART)
PIPO — Parallel In, Parallel Out
Uso: registrador com deslocamento (barrel shifter)
Direção de deslocamento:
Shift right: bit MSB → LSB (divide por 2)
Shift left: bit LSB → MSB (multiplica por 2)
Bidirecional: sinal de controle escolhe a direção
x << 1 (multiplica por 2) e x >> 1 (divide por 2). É muito mais rápido que multiplicação/divisão real, e compiladores usam essa otimização constantemente.
Contadores binários
Um contador é um registrador que incrementa (ou decrementa) seu valor a cada pulso de clock. Existem dois tipos fundamentais:
Contador assíncrono (ripple counter)
Cada flip-flop T (com T=1) divide a frequência por 2.
A saída de cada FF é o clock do próximo:
CLK ──┤T FF₀├──┤T FF₁├──┤T FF₂├──┤T FF₃├
Q₀ Q₁ Q₂ Q₃
(LSB) (MSB)
Diagrama de tempo:
CLK: ↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑
Q₀: _‾_‾_‾_‾_‾_‾_‾_‾_‾_‾_‾_‾_‾_‾_‾_‾
Q₁: __‾‾__‾‾__‾‾__‾‾__‾‾__‾‾__‾‾__‾‾
Q₂: ____‾‾‾‾____‾‾‾‾____‾‾‾‾____‾‾‾‾
Q₃: ________‾‾‾‾‾‾‾‾________‾‾‾‾‾‾‾‾
Contagem: 0000→0001→0010→...→1111→0000 (módulo 16)
Problema: como cada FF usa a saída do anterior como clock,
há atraso acumulado (ripple). Com 4 FFs, o atraso total
é 4 × tₚ. Para contadores grandes, isso limita a frequência.
Contador síncrono
Todos os flip-flops recebem o mesmo clock. A lógica combinacional determina quais flip-flops devem alternar:
Regra: um bit Qᵢ inverte quando todos os bits menos
significativos são 1.
T₀ = 1 (Q₀ sempre inverte)
T₁ = Q₀ (Q₁ inverte quando Q₀=1)
T₂ = Q₀ · Q₁ (Q₂ inverte quando Q₀=Q₁=1)
T₃ = Q₀ · Q₁ · Q₂ (Q₃ inverte quando Q₀=Q₁=Q₂=1)
┌─────────────────────────────────────────┐
1 ──── T₀ │ Q₀ ── T₁ │ Q₁ ── AND ── T₂ │ ...
FF₀│CLK FF₁│CLK Q₀ ──┘ FF₂│CLK
└──────────┴──────────────────────┘
clock comum
Vantagem: todas as saídas mudam simultaneamente (1 tₚ)
Custo: mais portas AND para a lógica de habilitação
Contador up/down
Sinal de controle: UP/DOWN̅ (1=up, 0=down)
Para contar para cima: Tᵢ depende de Qᵢ₋₁ (como antes)
Para contar para baixo: Tᵢ depende de Q̅ᵢ₋₁
Combinando com MUX:
Tᵢ = MUX(UP, Qᵢ₋₁, Q̅ᵢ₋₁) × (habilitação anterior)
Exemplo de contagem down (4 bits):
1111 → 1110 → 1101 → 1100 → ... → 0001 → 0000 → 1111
Contadores especiais
RING COUNTER (contador em anel):
Shift register com a saída do último FF realimentando
a entrada do primeiro. Apenas um bit 1 circula.
Inicialização: 1000
Sequência: 1000 → 0100 → 0010 → 0001 → 1000 → ...
4 flip-flops → 4 estados (ineficiente: 2⁴=16 possíveis)
Vantagem: decodificação trivial (cada saída é um estado)
JOHNSON COUNTER (contador Johnson):
Shift register com Q̅ do último FF realimentando
a entrada do primeiro. Sequência complementar.
Inicialização: 0000
Sequência (4 bits):
0000 → 1000 → 1100 → 1110 → 1111 →
0111 → 0011 → 0001 → 0000 → ...
4 flip-flops → 8 estados (2n estados com n FFs)
Decodificação: cada estado é identificado por 2 bits adjacentes
Comparação:
Tipo │ FFs │ Estados │ Decodificação
────────────┼─────┼─────────┼──────────────
Binário │ n │ 2ⁿ │ complexa
Ring │ n │ n │ trivial
Johnson │ n │ 2n │ simples
Contador módulo-N
Para contar de 0 a N-1 (módulo N), usamos um contador
binário com lógica de reset quando atinge N.
Exemplo: Contador módulo-6 (conta 0 a 5):
Usa 3 flip-flops (2³=8 ≥ 6)
Quando Q₂Q₁Q₀ = 110 (6), reset assíncrono → 000
Circuito:
Q₂ ──┤AND├── RESET (todos os FFs)
Q₁ ──┘
Contagem: 000→001→010→011→100→101→(110→reset)→000
Aplicação: relógio digital
Segundos: contador mod-60 (mod-10 × mod-6)
Minutos: contador mod-60
Horas: contador mod-24 (ou mod-12)
No harness.os
Registradores e contadores aparecem em vários padrões do harness:
- Registradores como variáveis de estado — cada campo de status no banco de dados do harness (fase do projeto, estado da sessão) é conceitualmente um registrador que armazena o estado atual e é atualizado em momentos definidos.
- Shift registers e pipelines — um pipeline de CI/CD (build → test → deploy) funciona como um shift register: cada estágio processa e passa o dado para o próximo. O harness modela pipelines da mesma forma.
- Contadores para métricas — contadores de sessões, de eventos, de erros. O campo
event_countem tabelas do harness é um contador síncrono em software — incrementa a cada evento, pode ser resetado. - Módulo-N e ciclos — rotação de logs, cache eviction (LRU usa um contador circular), e rotação de chaves de segurança são contadores módulo-N que voltam ao início após N operações.
- Serialização — dados que trafegam como JSON entre agentes e o harness são "serializados" (paralelo → serial) para transmissão e "desserializados" (serial → paralelo) na recepção. Exatamente o que um PISO/SIPO faz em hardware.
Exercícios
- Shift register: Um shift register SIPO de 8 bits recebe a sequência serial 11010011 (MSB primeiro). Desenhe o conteúdo do registrador após cada pulso de clock e identifique o valor final em hexadecimal.
- Contador síncrono: Projete um contador síncrono de 3 bits (módulo 8) usando flip-flops T. Derive as expressões para T₀, T₁ e T₂. Desenhe o circuito completo.
- Johnson counter: Um Johnson counter de 3 bits começa no estado 000. Liste todos os estados da sequência completa. Quantos estados tem? Derive a lógica de decodificação para identificar o estado 110.
Resumo
Verifique seu entendimento
Em um shift register de 4 bits com shift right, o que acontece com o bit no flip-flop mais à direita (LSB) a cada pulso de clock?
- Registrador: grupo de flip-flops com clock comum, armazena n bits
- Shift register: desloca bits a cada clock; SISO, SIPO, PISO, PIPO
- Shift left = ×2, shift right = ÷2 (otimização em compiladores)
- Contador assíncrono (ripple): simples mas com atraso acumulado
- Contador síncrono: clock comum, todas as saídas mudam juntas
- Ring counter: n estados com n FFs; Johnson: 2n estados com n FFs
- Contador módulo-N: reset quando atinge N