Implementação completa de um processador MIPS de 32 bits com arquitetura em pipeline de 5 estágios, intertravamento de hardware para controle de hazards (load-use hazard unit) e hierarquia de memória Harvard com módulos dedicados de memória Cache L1 de Mapeamento Direto (Direct-Mapped Cache), modelado e simulado em Logisim-evolution.
O circuito opera sob a divisão clássica de 5 estágios em pipeline proposta por Patterson & Hennessy, com registradores de desacoplamento entre estágios (IF/ID, ID/EX, EX/MEM e MEM/WB), unidade de controle combinacional desacoplada e hierarquia de memória de dados e instruções isoladas.
flowchart LR
subgraph IF ["Estágio IF"]
PC["PC Register"] --> ICache["L1 I-Cache (16x32b)"]
PC --> Addr4["PC + 4"]
end
subgraph ID ["Estágio ID"]
UC["Control Unit (UC)"]
UH["Hazard Unit (UH)"]
RF["Register File (32x32b)"]
Ext["Sign Extender (16->32)"]
end
subgraph EX ["Estágio EX"]
ALU["ULA (Add/Sub/Zero)"]
BranchCalc["Branch Target Adder"]
BranchCond["Branch Taken Logic"]
end
subgraph MEM ["Estágio MEM"]
DCache["L1 D-Cache (16x32b)"]
DMem["Data RAM"]
end
subgraph WB ["Estágio WB"]
MuxWB["MemtoReg MUX"]
end
IF -->|IF/ID| ID
ID -->|ID/EX| EX
EX -->|EX/MEM| MEM
MEM -->|MEM/WB| WB
WB -.->|DataWrite / RegWrite| RF
UH -.->|Stall / Freeze| PC
UH -.->|Stall / Freeze| IF
EX -.->|BranchTaken / Target| PC
-
Controle de Fluxo de PC: O registrador
PCé atualizado na borda de subida do clock. Na ausência de hazards e branches,$PC \leftarrow PC + 4$ . -
Desvios Condicionais: Em caso de branch tomado no estágio de execução (
EX_BranchTaken = 1), o multiplexador de entrada de PC selecionaEX_BranchTarget. -
Memória de Instruções & Cache L1-I: As instruções são acessadas em primeira instância pela
CacheModulede instruções; falhas de cache disparamStall_ICachecongelando o estágio até a recuperação pela ROM de instruções.
-
Banco de Registradores (
RegisterFile):- 32 registradores de uso geral de 32 bits (
$zeroa$ra). - Duas portas de leitura assíncronas (
ReadData1,ReadData2) indexadas pelos camposrs(bits [25:21]) ert(bits [20:16]). - Uma porta de escrita síncrona habilitada por
RegWriteindexada porRegAddrDest[4:0]. - O registrador
$zero($r0$ ) é fixado permanentemente em$0\text{x}00000000$ .
- 32 registradores de uso geral de 32 bits (
-
Extensor de Sinal (
Extender): Expansão do imediato de 16 bits para 32 bits com preservação do bit de sinal em complemento de dois ($\text{bit}[15]$ replicado nas posições$[31:16]$ ).
-
Unidade Lógica e Aritmética (
ULA):- Operações de soma (
$A + B$ ) e subtração ($A - B$ ) em barramentos de 32 bits. - Comparador de igualdade a zero para geração do sinal
Zero_Flag($A - B = 0$ ).
- Operações de soma (
-
Seleção de Operandos da ULA:
- Entrada
$A$ :EX_DataOut1(conteúdo ders). - Entrada
$B$ : Multiplexado viaALUSrcentreEX_DataOut2(conteúdo dert) eImmediateExt(imediato estendido).
- Entrada
-
Cálculo de Desvio (Branch Target):
Calculado no estágio de execução em paralelo à ULA principal:
\begin{aligned} \text{BranchTarget} &= \text{EX.PC4} + (\text{ImmediateExt} \ll 2) \\ \text{BranchTaken} &= \text{Branch} \land \text{Zero} \end{aligned} -
Destino do Registrador:
Multiplexador controlado por
RegDestseleciona entreEX_RT(instruções tipo I) eEX_RD(instruções tipo R).
- Interface com o subsistema de memória de dados através do módulo de Cache L1-D (
CacheModule) e memória primária de retaguarda (DataMemory). - Em operações de leitura (
MemRead) com acerto de cache, os dados são entregues no mesmo ciclo. Em caso de falha de cache (miss), o circuito geraStall_DCachepara pausar a propagação do pipeline até a conclusão da carga.
- Multiplexador controlado por
MemtoRegdefine o dado final a ser retroalimentado aoRegisterFile:-
$\text{MemtoReg} = 0$ : Dado proveniente do resultado da ULA (ResultOut). -
$\text{MemtoReg} = 1$ : Dado carregado da memória (DataOut).
-
O processador implementa uma memória cache L1 de Mapeamento Direto (Direct-Mapped Cache) com capacidade para 16 linhas de 1 palavra (32 bits), totalizando 64 bytes de armazenamento local.
O barramento de endereço de 32 bits é particionado da seguinte forma:
| Tag (26 bits) | Índice / Set (4 bits) | Byte Offset (2 bits) |
|---|---|---|
| bits [31:6] | bits [5:2] | bits [1:0] |
- Byte Offset (2 bits): Alinhamento em nível de palavra de 32 bits (bits [1:0] ignorados para indexação de palavras).
-
Índice (4 bits): Indexa diretamente uma das
$2^4 = 16$ linhas da cache. - Tag (26 bits): Rótulo comparado com a tag armazenada para verificação de correspondência de bloco.
Cada uma das 16 linhas da cache possui:
- Bit de Validade (
Valid): 1 bit indicando se a linha contém dados válidos. - Tag RAM: 26 bits para identificação do bloco de memória.
- Data RAM: 32 bits correspondentes à palavra de dados.
A lógica combinacional de validação é definida por:
Em caso de Miss, a cache dispara um ciclo de preenchimento a partir da memória primária (DataMemory ou InstructionMemory), atualizando simultaneamente a tag, o dado e ligando o bit de validade.
Para solucionar dependências de dados do tipo Load-Use (onde uma instrução imediatamente posterior a um lw tenta ler o registrador de destino antes de sua recuperação da memória), a unidade UH introduz uma bolha (stall) de 1 ciclo no pipeline.
Quando a condição de stall é ativada (Stall = 1):
IF_PC_Write = 0: Congela o registradorPCno ciclo atual, impedindo avanço de instrução.IF_ID_Write = 0: Congela o registrador de desacoplamentoIF/ID, retendo a instrução em decodificação.ID_Stall = 1: Força os sinais de controle no registradorID/EXpara zero (NOP), gerando uma bolha no estágio de execução.
A Unidade de Controle decodifica o código de operação (Opcode_In [31:26]) e o código de função (Funct_In [5:0]) utilizando dois decodificadores
| Instrução | Mnemônico | Formato | Opcode | Funct | Semântica Operacional |
|---|---|---|---|---|---|
| Add | add $rd, $rs, $rt |
R | 0x00 |
0x20 |
|
| Subtract | sub $rd, $rs, $rt |
R | 0x00 |
0x22 |
|
| Add Immediate | addi $rt, $rs, imm |
I | 0x08 |
N/A | |
| Load Word | lw $rt, offset($rs) |
I | 0x23 |
N/A | |
| Store Word | sw $rt, offset($rs) |
I | 0x2B |
N/A | |
| Branch on Equal | beq $rs, $rt, label |
I | 0x04 |
N/A |
-
Software: Logisim-evolution versão v4.0.0 ou superior (e.g.,
v4.1.0ouv5.0.0).[!IMPORTANT] Versões legadas (
$\le \text{v3.8.0}$ ) impõem restrição de 5 bits no componenteDecoderda biblioteca#Plexers, descartando os decodificadores de 6 bits daUC. Utilize sempre o pacote nativo atualizado (.debou-all.jar).
-
Abertura do Circuito:
# Execução via binário nativo ou jar logisim-evolution circuit/processor.circ &
-
Carregamento de Programas:
- Navegue até o subcircuito
InstructionMemory. - Clique com o botão direito sobre o componente ROM e selecione Edit Contents....
- Carregue o arquivo hexadecimal de teste localizado em
programs/cache_hazard_test.hex.
- Navegue até o subcircuito
-
Simulação por Passos ou Contínua:
- Habilite a simulação com
Ctrl + K. - Para avançar um semiciclo manualmente, pressione
Ctrl + T. - Para alternar a frequência de clock automática, acesse o menu Simulate
$\rightarrow$ Tick Frequency (recomendado: 1 Hz a 4 Hz para inspeção visual do pipeline).
- Habilite a simulação com
O programa de teste incluído valida simultaneamente a ocorrência de acertos e falhas na cache L1 e o intertravamento de dependência de dados:
# programs/cache_hazard_test.asm
lw $t0, 0($zero) # Compulsory Miss: Aloca índice 0 da D-Cache e dispara Stall_DCache
lw $t1, 0($zero) # Cache Hit: Dado lido diretamente da D-Cache sem stall
lw $t2, 4($zero) # Compulsory Miss: Aloca índice 1 da D-Cache
lw $t3, 0($zero) # Cache Hit: Linha 0 permanece residente na cache
addi $t4, $zero, 10 # Aritmética imediata
addi $t5, $zero, 10
sub $t6, $t4, $t5 # $t6 = 0 (Ativa Zero_Flag na ULA)
beq $t4, $t5, target # Desvio tomado: flush do pipeline
addi $t7, $zero, 99 # Instrução descartada
target:
sw $t6, 8($zero) # Armazena resultado na memória
mips-processor/
├── circuit/
│ └── processor.circ # Esquema estrutural completo (Logisim-evolution XML)
├── assets/
│ ├── datapath_overview.png # Esquema geral dos 5 estágios e pipeline registers
│ ├── control_unit.png # Esquema da UC (decodificadores 6->64 e portas lógicas)
│ ├── hazard_unit.png # Unidade de detecção de hazard Load-Use
│ ├── execute_stage.png # Estágio de execução (ULA e lógica de branch)
│ └── cache_module.png # Módulo da memória Cache L1 de Mapeamento Direto
├── programs/
│ ├── cache_hazard_test.asm # Código-fonte MIPS Assembly anotado para verificação
│ └── cache_hazard_test.hex # Imagem hexadecimal para carga na ROM do Logisim
└── README.md # Documentação formal da arquitetura




