Pular para conteúdo

🏋️ Exercício 20 – Projeto Capstone: Simulador de Unidade Lógica e Aritmética (ULA)


🎯 Objetivo

Integrar os conceitos de aritmética binária, registradores, portas lógicas e decodificação de operações no projeto de um simulador conceitual de ULA de 8 bits.


🥉 Nível Bronze (Fixação)

Exercício 1: Em uma ULA simples de 8 bits com 3 linhas de controle de operação (\(Op_2, Op_1, Op_0\)), quantas operações distintas a ULA consegue realizar no máximo?

Gabarito Explicado Com 3 linhas de controle binárias, temos $2^3 = 8$ combinações possíveis. Portanto, a ULA pode executar até **8 operações distintas** (ex: ADD, SUB, AND, OR, XOR, NOT, SHL, SHR).

🥈 Nível Prata (Aplicação)

Exercício 2: Considere uma ULA onde a instrução 000 realiza a operação ADD e 001 realiza a operação SUB. Dados os operandos \(A = 00001101_2\) (\(13_{10}\)) e \(B = 00000101_2\) (\(5_{10}\)), determine o valor de saída da ULA e as flags de status Zero (Z) e Carry (C) para a operação SUB (\(A - B\)).

Gabarito Explicado 1. **Operação SUB ($A - B$):** - $A = 13_{10} = 00001101_2$ - $B = 5_{10} = 00000101_2$ - $13 - 5 = 8_{10} = 00001000_2$ 2. **Saída da ULA:** $00001000_2$ (8 em decimal). 3. **Flags de Status:** - **Flag Zero ($Z$):** Falso ($0$), pois o resultado não é zero ($8 \neq 0$). - **Flag Carry ($C$):** Falso ($0$), pois não houve estouro de capacidade nos 8 bits.

🥇 Nível Ouro (Desafio)

Exercício 3: Escreva uma função em Python ou em pseudocódigo que simule a ULA de 8 bits aceitando as entradas A, B (números inteiros de 0 a 255) e o código de operação OP (0 a 3, onde 0=ADD, 1=SUB, 2=AND, 3=OR). A função deve retornar o resultado mascarado em 8 bits (& 0xFF) e um dicionário com as flags Zero, Carry e Negative.

Gabarito Explicado
def simulador_ula(a: int, b: int, op: int):
    # Mascara operandos para 8 bits
    a &= 0xFF
    b &= 0xFF
    carry = False

    if op == 0:  # ADD
        res_full = a + b
        res = res_full & 0xFF
        carry = res_full > 0xFF
    elif op == 1:  # SUB
        res_full = a - b
        res = res_full & 0xFF
        carry = a < b
    elif op == 2:  # AND
        res = a & b
    elif op == 3:  # OR
        res = a | b
    else:
        raise ValueError("Operação inválida")

    flags = {
        'Z': res == 0,
        'C': carry,
        'N': bool(res & 0x80)  # Bit mais significativo ativo indica negativo em C2
    }

    return res, flags

# Exemplo de teste:
# simulador_ula(200, 100, 0) -> (44, {'Z': False, 'C': True, 'N': False})