Aula 20 - Projeto Capstone: Simulador de Unidade Lógica e Aritmética (ULA) 🏆
Objetivo Pedagógico
Objetivo: Construção de um simulador completo de Unidade Lógica e Aritmética (ULA) de 8 bits em código estruturado, com registradores de status (Flags) e decodificador de opcode.
📑 1. Fundamentos Teóricos & Análise Técnica
O Projeto Capstone de Fundamentos da Computação desafia o estudante a integrar os conceitos de arquitetura digital, lógica booleana e representação de dados através da construção de um Simulador de Unidade Lógica e Aritmética (ULA - ALU) funcional.
A ULA simula o coração de um processador clássico de 8 bits (semelhante ao lendário Intel 8080 ou Zilog Z80), recebendo dois barramentos de operandos (A e B), um barramento de código de operação (Opcode) e produzindo o resultado conjuntamente com o Registrador de Flags de Status: 1. Flag Zero (Z): Ligada (1) se o resultado da operação for exatamente zero. 2. Flag Carry (C): Ligada se a operação aritmética gerou um overflow no bit mais significativo (vai-um). 3. Flag Sign/Negative (S): Ligada se o bit mais significativo for 1, indicando número negativo em complemento de dois. 4. Operações Obrigatórias: Soma binária (ADD), Subtração (SUB), AND bitwise (AND), OR bitwise (OR), XOR (XOR), Inversão (NOT) e Deslocamentos lógicos (SHL, SHR).
📐 Arquitetura Conceitual & Diagrama de Fluxo
graph TD
OpA["Operando A (8 bits)"] --> ALU["Unidade Lógica e Aritmética (ULA)"]
OpB["Operando B (8 bits)"] --> ALU
Opcode["Código da Operação (Opcode)"] --> ALU
ALU --> Result["Barramento de Saída (8 bits)"]
ALU --> Flags["Registrador de Status (Zero, Carry, Sign, Overflow)"]
style ALU fill:#e3f2fd,stroke:#1565c0
style Result fill:#e8f5e9,stroke:#2e7d32
style Flags fill:#fff3e0,stroke:#e65100 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Controle de Flags Determinístico: Atualização correta das flags de condição para ramificações condicionais (branches). - Aritmética em Complemento de Dois: A subtração é executada como soma de A com o complemento de dois de B. - Arquitetura de Barramentos: Separação estrita entre barramento de controle e barramento de dados. - Tratamento de Overflow Aritmético: Detecção de transbordamento de capacidade em somas de números com sinal.
🛠️ 2. Implementação Prática em Arquitetura de Computadores e Engenharia de Sistemas
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// alu_simulator.c (Implementação da ULA de 8 bits em C)
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
ALU_ADD = 0x01,
ALU_SUB = 0x02,
ALU_AND = 0x03,
ALU_OR = 0x04,
ALU_XOR = 0x05,
ALU_SHL = 0x06
} AluOpcode;
typedef struct {
bool zero;
bool carry;
bool negative;
} AluFlags;
typedef struct {
uint8_t result;
AluFlags flags;
} AluOutput;
AluOutput execute_alu(AluOpcode op, uint8_t a, uint8_t b) {
AluOutput out = {0, {false, false, false}};
uint16_t temp = 0;
switch (op) {
case ALU_ADD:
temp = (uint16_t)a + (uint16_t)b;
out.result = (uint8_t)(temp & 0xFF);
out.flags.carry = (temp > 0xFF);
break;
case ALU_SUB:
out.result = a - b;
out.flags.carry = (a < b); // Borrow flag
break;
case ALU_AND: out.result = a & b; break;
case ALU_OR: out.result = a | b; break;
case ALU_XOR: out.result = a ^ b; break;
case ALU_SHL:
temp = (uint16_t)a << 1;
out.result = (uint8_t)(temp & 0xFF);
out.flags.carry = ((a & 0x80) != 0);
break;
}
out.flags.zero = (out.result == 0);
out.flags.negative = ((out.result & 0x80) != 0);
return out;
}
💡 Análise Passo a Passo do Código
- Uso de Variável Intermediária de 16 bits:
tempcaptura bits extras além do oitavo bit para calcular confiavelmente a flag de Carry. - Atualização Universal de Zero e Negative: Qualquer operação que retorne zero ou MSB 1 atualiza os registradores correspondentes.
- Contrato Industrial: Estrutura pronta para ser incorporada em emuladores de CPU completos.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto