Módulo 1: Fundamentos de Arquitetura e Organização de Computadores — Resumo

Esta é a versão ultra-enxuta do Módulo 1, para revisão rápida antes da aula, da prova ou de uma tutoria do Projeto Integrador.

Imagine dois processadores Intel rodando o mesmo binário x86 e diferindo cinco vezes em desempenho no mesmo benchmark. Como isso é possível, se o programa é logicamente idêntico? Responder com precisão organiza todo o vocabulário que você usará nos próximos quatorze módulos.

flowchart TB
    subgraph CONC["Fundamentos conceituais"]
        AO["Arquitetura × Organização"]
        HIST["5 gerações<br/>RISC × CISC"]
        VN["Von Neumann"]
        HV["Harvard / Harvard mod."]
    end

    subgraph CASO["Estudo de caso e métricas"]
        PIC["PIC18F4550<br/>(blocos, ciclo, pipeline)"]
        MET["Métricas:<br/>T = N·CPI·Tcy<br/>IPC, MIPS, Amdahl, Gustafson"]
    end

    subgraph PRAT["Prática (Projeto Integrador)"]
        T1["Tarefa 1<br/>Ambiente + LED"]
        T2["Tarefa 2<br/>Quadro Arq/Org<br/>Harvard mod no .map"]
        T3["Tarefa 3<br/>Medição de tempo<br/>no osciloscópio"]
    end

    CONC --> CASO --> PRAT
    PRAT --> M2["Módulo 02:<br/>Representação de Dados"]
Figura 1: Mapa do módulo: das definições até a primeira medição no kit.

Arquitetura e Organização

Chamo de arquitetura o conjunto de atributos visíveis ao programador: instruções, registradores nomeáveis, modos de endereçamento, modelo de memória, mecanismos de exceção e modelo de E/S. É o contrato público entre quem escreve o código e quem projeta o chip. Chamo de organização as decisões de implementação que cumprem o contrato: pipeline, hierarquia de cache, frequência, larguras de barramento, tecnologia de memórias. Duas organizações distintas podem implementar a mesma arquitetura com desempenhos radicalmente diferentes sem que um programa correto consiga distingui-las pelo resultado.

flowchart TB
    P["Programador<br/>(código C, ASM)"]
    A["Arquitetura<br/>ISA, registradores, modelo de memória,<br/>modos de endereçamento, exceções"]
    O["Organização<br/>Pipeline, caches, ULA, barramentos,<br/>frequência, tecnologia de memória"]
    H["Silício<br/>Transistores, geometria, materiais"]

    P -->|"escreve programa"| A
    A -.->|"contrato visível"| P
    A --> O
    O --> H
    H -.->|"desempenho percebido"| P
Figura 2: As duas camadas: o programador enxerga só a arquitetura; a organização fica oculta atrás do contrato.

A separação tem origem histórica na família IBM System/360 de 1964, primeira em que uma única arquitetura foi realizada por modelos com organizações deliberadamente diferentes. Ofereço a prova do programador: se a alteração de um detalhe muda o resultado lógico de algum programa correto, é arquitetura; se só afeta tempo, consumo ou custo, é organização. O Core i9-13900K e o i3-13100 são arquiteturalmente equivalentes — ambos x86-64 — mas organizacionalmente abissais, o que explica a diferença da pergunta de abertura.

Existe uma camada intermediária, a microarquitetura, que vive dentro da organização e descreve como o processador implementa internamente a arquitetura — pipeline, execução fora de ordem, unidade de controle. Cuidado com a literatura comercial: “arquitetura Skylake” ou “arquitetura M2” descrevem, no rigor que adoto, microarquiteturas dentro das famílias x86-64 e ARMv8-A.

Se eu trocar a SRAM de 2 KB do PIC18F4550 por uma SRAM de 8 KB sem alterar o mapa de endereçamento visível ao programador, isso é mudança de arquitetura ou de organização? Responder corretamente valida que esta seção foi sedimentada.

Gerações e a Disputa RISC versus CISC

Cada inovação arquitetural respondeu a uma limitação tecnológica concreta. A primeira geração (1940–1955) usa válvulas: o ENIAC era programado por reconexão de cabos, e von Neumann formulou no EDVAC de 1945 o conceito de programa armazenado. A segunda trouxe transistores discretos, FORTRAN e COBOL; a terceira, circuitos integrados, o System/360 e a microprogramação; a quarta começou em 1971 com o Intel 4004 e viabilizou o PC; a quinta, dos anos 1980 em diante, é a do VLSI e da computação ubíqua. O PIC18F4550, projetado pela Microchip por volta de 2007, é típico dessa quinta geração mas executa um modelo conceitual de 1945.

A controvérsia RISC versus CISC merece nota. CISC (VAX-11, x86) adotava conjuntos extensos esperando reduzir o trabalho do compilador; Patterson e Hennessy observaram que só um pequeno subconjunto era de fato usado e propuseram o contrário: poucas instruções simples, tamanho fixo, um ciclo cada, acesso à memória restrito a load/store. O PIC18F4550 é híbrido — tamanho fixo de 16 bits típico de RISC, mas 75 instruções com várias combinando memória e aritmética (como ADDWF), típico de CISC. O desfecho foi pragmático: x86 modernos traduzem em micro-operações RISC, e ARM/RISC-V acumularam extensões que os aproximam do CISC.

Von Neumann e a Harvard Modificada

A ideia que justifica nomear um modelo inteiro em homenagem a von Neumann é a do programa armazenado: instruções representadas como números, gravadas na mesma memória dos dados e lidas pelo processador da mesma forma. O modelo tem cinco subsistemas — unidade de controle, ULA, registradores, memória principal e E/S — e executa o ciclo de busca, decodificação e execução. O contador de programa (PC) aponta a próxima instrução; a unidade de controle envia o endereço pelo barramento; a memória devolve a instrução ao registrador de instrução (IR); o IR é decodificado e os sinais coordenam a execução; ao final, o PC é incrementado ou alterado por desvio.

flowchart LR
    subgraph CPU["CPU"]
        UC["Unidade<br/>de Controle"]
        ULA["ULA"]
        REG["Registradores<br/>PC, IR, ACC"]
    end
    MEM["Memória Principal<br/>instruções + dados<br/>(mesma)"]
    IO["Subsistema<br/>de E/S"]

    CPU <-->|"barramento único<br/>endereço/dado/controle"| MEM
    CPU <--> IO
Figura 3: Modelo de Von Neumann: memória única, barramento único, serialização forçada entre busca e dado.

A elegância esconde uma fragilidade. Como instruções e dados compartilham o barramento, a CPU não pode buscar uma instrução e ler um dado no mesmo instante. John Backus, no Turing de 1977, batizou o fenômeno de gargalo de Von Neumann:

\tau \geq \tau_p + 2 \, \tau_m,

porque cada instrução exige pelo menos uma busca da própria instrução e um acesso ao dado. Quando \tau_m supera \tau_p, a CPU passa a maior parte do tempo esperando — a memory wall, atacada nos computadores de propósito geral pela hierarquia de caches do Módulo 09 e nos microcontroladores por uma rota arquitetural distinta.

Essa rota é a Harvard, que mantém instruções e dados em memórias fisicamente separadas com barramentos independentes. O nome vem do Mark I, de Howard Aiken, operacional em 1944. A largura dos dois barramentos pode diferir — no PIC18, instruções têm 16 bits e dados têm 8 — e as tecnologias também: Flash não volátil para instruções, SRAM rápida para dados. O paralelismo de acesso permite alcançar uma instrução por ciclo de máquina sem cache sofisticada. A Harvard pura, porém, dificulta o uso de tabelas e constantes grandes, que não cabem confortavelmente na RAM. A Harvard modificada do PIC18 resolve isso com TBLRD*, TBLRD*+, TBLRD*- e TBLRD+*, que leem bytes da Flash via ponteiro TBLPTR expondo o byte em TABLAT. Ao declarar static const uint8_t tabela[] = {...} em C, o XC8 aloca a tabela em Flash e emite automaticamente a sequência de leitura cruzada — parece um acesso ordinário a vetor, mas é uma travessia de fronteira entre espaços de endereçamento.

flowchart LR
    MI["Memória de<br/>Instruções<br/>(Flash 32 KB)"]
    CPU["CPU"]
    MD["Memória de<br/>Dados<br/>(SRAM 2 KB)"]
    EE["EEPROM<br/>256 bytes"]

    MI -->|"barramento de<br/>instruções 16 bits"| CPU
    CPU <-->|"barramento de<br/>dados 8 bits"| MD
    MI -.->|"TBLRD via TBLPTR<br/>(Harvard modificada)"| CPU
    CPU <-.->|"EECON1/EECON2<br/>(protocolo)"| EE
Figura 4: Harvard modificada do PIC18F4550: dois espaços principais, duas vias paralelas e a EEPROM como terceiro espaço com protocolo próprio.

O PIC18 dispõe ainda de um terceiro espaço, a EEPROM de 256 bytes para dados persistentes, mediada por EECON1/EECON2 com bytes mágicos que evitam escritas acidentais. Detalhe que surpreende: o x86 moderno é, para o programador, Von Neumann — uma única memória —, mas internamente possui caches L1 separadas em instruções e dados, materializando uma organização de inspiração harvardiana. Arquitetura Von Neumann, organização mista: a prova do programador resolve o paradoxo em uma sentença.

O PIC18F4550 como Estudo de Caso

Escolhi o PIC18F4550 por quatro razões: regularidade ortogonal (75 instruções, quase todas de um ciclo, codificação fixa de 16 bits) que permite estudar o ISA inteiro em um módulo; acesso direto a periféricos (ADC, USB, UART, SPI, I²C, comparadores, timers) num único datasheet; previsibilidade absoluta de timing, sem caches nem execução fora de ordem, com tempo de execução calculável; e o custo e a robustez do KIT ACEPIC PRO V8.2, que tolera erros típicos de quem aprende eletrônica embarcada.

flowchart TB
    subgraph Nucleo["Núcleo do PIC18F4550"]
        UC["Unidade<br/>de Controle"]
        ULA["ULA 8 bits"]
        W["WREG"]
        ST["STATUS<br/>C, DC, Z, OV, N"]
    end

    Flash["Flash 32 KB<br/>(16 K palavras<br/>de 16 bits)"]
    SRAM["SRAM 2 KB<br/>(16 bancos +<br/>Access Bank)"]
    EE["EEPROM<br/>256 bytes"]

    subgraph Perif["Periféricos integrados"]
        USB["USB 2.0"]
        UART["EUSART"]
        MSSP["MSSP<br/>(I²C/SPI)"]
        ADC["ADC 10 bits<br/>13 canais"]
        TIM["Timers<br/>+ CCP/PWM"]
        IO["35 pinos I/O<br/>PORTA..PORTE"]
    end

    CK["Oscilador externo<br/>8 MHz → ÷4 → Fcy = 2 MHz<br/>+ PLL para USB"]

    Flash --> Nucleo
    Nucleo <--> SRAM
    Nucleo <-.-> EE
    Nucleo <--> Perif
    CK --> Nucleo
Figura 5: Anatomia em blocos do PIC18F4550: núcleo com ULA, W e STATUS, três memórias, periféricos integrados e cadeia de clock.

A CPU abriga unidade de controle, ULA de 8 bits, registrador WREG e registrador STATUS com cinco flags: Carry, Digit Carry, Zero, Overflow e Negative. A Flash de 32 KB armazena 16 K palavras de 16 bits, reprogramável in-circuit. A SRAM de 2 KB se organiza em dezesseis bancos de 256 bytes selecionados pelo BSR, com o Access Bank combinando os 96 bytes iniciais da RAM e os 160 bytes superiores onde residem os SFRs. Os periféricos incluem dois MSSP (I²C/SPI), EUSART, USB 2.0 full-speed, ADC de 10 bits, três comparadores, quatro timers, dois CCP e trinta e cinco pinos de E/S.

Aplique a prova do programador a esse chip: as 75 instruções, o WREG, os flags, os três espaços de memória e SFRs como TRISx, LATx e ADCONx são arquitetura, porque seu código depende deles. Já o pipeline de dois estágios, o Access Bank, a largura física do barramento, o cristal externo, a divisão por quatro e a tecnologia das células são organização. Esse quadro é a base da Tarefa 2 do Projeto Integrador.

O ciclo de instrução compacta as cinco fases conceituais em dois estágios físicos, fetch e execute, graças à Harvard, que permite buscar a próxima instrução pelo barramento de instruções enquanto a atual executa pelo de dados. Após uma latência inicial de um ciclo, conclui-se uma instrução por ciclo de máquina, exceto nas que alteram o PC — GOTO, CALL, BRA tomado, RETURN, RETFIE e BTFSS/BTFSC quando causam skip —, em que o prefetch errado é descartado e o CPI vira 2.

Métricas de Desempenho

Quando alguém afirma que um processador é “duas vezes mais rápido”, pergunte sob qual carga, qual compilador, qual frequência e medindo o quê — sem qualificação, a expressão é vazia. A equação que carrego pelo semestre é

T = N_{\text{instr}} \cdot \text{CPI} \cdot T_{cy}.

Cada fator depende de uma camada: N depende do algoritmo e do compilador; \text{CPI} depende da arquitetura, da microarquitetura e da mistura de instruções; T_{cy} depende exclusivamente da organização. Otimizar é atacar os três simultaneamente.

flowchart LR
    XT["Cristal externo<br/>Fosc = 8 MHz"]
    DIV["Divisor<br/>÷ 4"]
    FCY["Clock de máquina<br/>Fcy = 2 MHz<br/>Tcy = 500 ns"]
    CPU["CPU<br/>(Q1, Q2, Q3, Q4)"]

    XT --> DIV --> FCY --> CPU
Figura 6: Cadeia de clock do PIC18: o cristal Fosc é dividido por 4 para gerar o clock de máquina Fcy.

No PIC18, o cristal externo gera F_{osc}, mas um divisor interno por quatro produz o clock de máquina F_{cy} = F_{osc}/4. Para o cristal de 8 MHz típico do KIT ACEPIC PRO V8.2, F_{cy} = 2 MHz e T_{cy} = 500 ns. Trocar F_{osc} por F_{cy} é o erro mais frequente da disciplina e produz previsão quatro vezes menor que a medida. Para uma mistura f_i com CPIs c_i,

\text{CPI}_{\text{médio}} = \sum_{i} f_i \, c_i.

Um programa com 90% de instruções de CPI 1 e 10% de desvios tomados (CPI 2) tem CPI médio 1,10; a 8 MHz com 10 000 instruções, o tempo total é 5,5 ms. O throughput generaliza a métrica: IPC vale 1/\text{CPI}, e no PIC18 fica próximo de 1 em pipeline cheio. Superescalares modernos atingem IPC maior que 1 — tema do Módulo 15.

Para tornar o efeito do CPI palpável, considere um pulso em RD0 delimitando um laço de soma — padrão que reaparece nas tarefas do Projeto Integrador.

#include <xc.h>
void main(void) {
  TRISD = 0x00; LATD = 0x00;
  uint16_t s = 0;
  LATDbits.LATD0 = 1;           // sobe pulso
  for (uint8_t i = 0; i < 100; i++) s += i;
  LATDbits.LATD0 = 0;           // desce pulso
  while (1);
}
    BSF   TRISD, 0, A
    BCF   TRISD, 0, A           ; RD0 como saída
    CLRF  CONT, A
    BSF   LATD,  0, A           ; sobe pulso
LOOP
    INCF  CONT, F, A
    MOVF  CONT, W, A
    SUBLW d'100'
    BNZ   LOOP
    BCF   LATD,  0, A           ; desce pulso
    BRA   $

A Lei de Amdahl responde a uma pergunta natural: se uma fração f do tempo de execução é acelerada por um fator k, qual o ganho global? A resposta de Gene Amdahl em 1967 é

S = \frac{1}{(1-f) + \dfrac{f}{k}}.

No limite k \to \infty, S_{\max} = 1/(1-f). Acelerar infinitamente 90% do tempo dá speedup de apenas dez; acelerar por dez uma fração de 50% dá 1,82, não 5,5. Otimização vale a pena onde o programa gasta tempo, e o ganho é tetado pela fração não otimizada. A Lei de Gustafson (1988) complementa: quando o problema cresce com os recursos, o speedup escalado vale (1-f) + k\cdot f. Amdahl descreve strong scaling; Gustafson, weak scaling. Em sistemas embarcados, em que o problema é dado pela aplicação, Amdahl costuma ser mais aderente.

flowchart LR
    T0["Tempo original<br/>T = 1"]
    F["Fração f<br/>acelerável"]
    NF["Fração (1−f)<br/>inalterada"]
    K["Aceleração<br/>por fator k"]
    S["Speedup global<br/>S = 1 / ((1−f) + f/k)"]
    LIM["Limite k → ∞<br/>S_max = 1 / (1−f)"]

    T0 --> F
    T0 --> NF
    F --> K
    K --> S
    NF --> S
    S --> LIM
Figura 7: Geometria da Lei de Amdahl: a fração não acelerada estabelece o teto do speedup global.

Se um programa gasta 30% do tempo em E/S sequencial obrigatória e 70% em laço computacional, qual o speedup máximo teórico mesmo paralelizando o laço infinitamente? Faça a conta antes de virar a página — é exatamente o tipo de pergunta que aparecerá em prova.

Da Teoria ao Kit

A cadeia de ferramentas tem cinco blocos: MPLAB X IDE como ambiente integrado; XC8 traduzindo C em assembly e código de máquina; pic-as fazendo o mesmo a partir de assembly puro; arquivo .hex no formato Intel HEX; e gravação via bootloader residente (AN1310 ou ACEPIC Terminal pela USB) ou via PICkit no header ICSP.

flowchart LR
    SRC["Código-fonte<br/>(.c / .asm)<br/>MPLAB X IDE"]
    XC8["XC8 (C)<br/>ou pic-as (ASM)"]
    LINK["Linker<br/>(.elf)"]
    HEX["Imagem<br/>Intel HEX (.hex)"]
    CHIP["PIC18F4550<br/>(Flash gravada)"]

    SRC --> XC8 --> LINK --> HEX
    HEX -->|"bootloader<br/>via USB"| CHIP
    HEX -->|"PICkit<br/>via ICSP"| CHIP
Figura 8: Cadeia de ferramentas do PIC18: do código-fonte ao silício.

O Projeto Integrador pede três tarefas. Na primeira, você configura o ambiente e grava um programa que pisca os oito LEDs do kit em sequência (PORTD como saída, 500 ms entre acionamentos). O aprendizado está na cadeia inteira: driver CH340G, MPLAB X compatível, XC8 reconhecendo o PIC18F4550, jumpers corretos, bootloader íntegro. Quatro pontos do kit exigem atenção: jumper LEDS fechado para acender L1–L8 via LATD; jumper J1 em 1-2 para alimentar com 5 V; jumpers JP14 do cristal de 8 MHz fechados verticalmente, sob pena de o chip cair no oscilador interno; e DIP-switch DP2 com as chaves 5 a 8 em OFF, pois controlam cátodos de displays compartilhados com PORTD.

Na segunda tarefa, você produz evidência empírica da Harvard modificada. O programa define uma tabela de oito padrões em const uint8_t (Flash) e uma variável de índice em RAM; a cada iteração, o byte é lido via TBLRD e escrito em LATD. O entregável traz o quadro Arq/Org do PIC18F4550 e a inspeção do .map, onde padroes[] aparece em endereços baixos (Flash, a partir de 0x000000) e o índice em outra faixa (RAM, no Access Bank). A separação conceitual vira dois conjuntos disjuntos de endereços.

A terceira tarefa fecha o ciclo teoria-medição. Você eleva RD0 antes de um trecho instrumentado e o abaixa depois, observa o pulso no osciloscópio, calcula o tempo teórico pela contagem de instruções no datasheet e compara com a medida. O entregável traz tabela de instruções, cálculo teórico, valor medido, erro relativo e fontes de incerteza. É a primeira tarefa em que você age como engenheiro: prevê, mede, confronta.

Síntese e Próximos Passos

Você atravessou um caminho que partiu de uma distinção aparentemente acadêmica e desembocou na configuração física de um microcontrolador real com tempo medido no osciloscópio. A pergunta de abertura sobre os dois processadores Intel tem agora resposta precisa: arquitetura define o contrato com o programador, organização define o desempenho real. Antes de seguir, garanta que você sabe aplicar a prova do programador, descrever o ciclo de busca-decodificação-execução, identificar o gargalo de Von Neumann, diferenciar Harvard pura e modificada, calcular T = N \cdot \text{CPI} \cdot T_{cy} sem esquecer da divisão por quatro do clock do PIC18 e aplicar a Lei de Amdahl. No Módulo 02 mergulharemos na representação de dados e na aritmética computacional; pergunta para o intervalo: por que somar dois números de 16 bits num chip de 8 bits exige mais de uma instrução, e que registrador entra em cena na segunda?

Antes da próxima aula, abra o MPLAB X, compile o programa de pisca-LED da Tarefa 1, conecte o osciloscópio em RD0 e meça a largura do pulso. Compare com o valor que você calcular pela contagem de instruções e pela relação T_{cy} = 4 / F_{osc}. O encontro entre teoria e medição é o ponto de partida do seu trabalho no semestre inteiro.