Decodificando instruções do RISC-V
O objetivo desta prática é construir um jogo para compreender a codificação de instruções e cálculos de endereço no RISC-V. Ele pode ser feito em qualquer linguagem de sua preferência, usando ou não o kit de FPGAs. A partir de um programa fornecido ou gerado aleatóriamente, o jogador precisa adivinhar partes das instruções ou endereços para ganhar pontos ou avançar no jogo. A seguir está um fluxo possível:
flowchart TD
Start(["Escolha Instrução"])
Opcode["Adivinhar OPCODE (7 bits)"]
Format{"Formato?"}
NextInstr(["Próxima Instrução"])
Start --> Opcode
Opcode --> Format
%% R-Type
Format --> RType(["R-Type"])
RType --> R_rd["Adivinhar rd (5)"]
R_rd --> R_funct3["Adivinhar funct3 (3)"]
R_funct3 --> R_rs1["Adivinhar rs1 (5)"]
R_rs1 --> R_rs2["Adivinhar rs2 (5)"]
R_rs2 --> R_funct7["Adivinhar funct7 (7)"]
R_funct7 --> NextInstr
%% I-Type
Format --> IType(["I-Type"])
IType --> I_rd["Adivinhar rd (5)"]
I_rd --> I_funct3["Adivinhar funct3 (3)"]
I_funct3 --> I_rs1["Adivinhar rs1 (5)"]
I_rs1 --> I_imm["Adivinhar imm (12)"]
I_imm --> NextInstr
%% S-Type
Format --> SType(["S-Type"])
SType --> S_funct3["Adivinhar funct3 (3)"]
S_funct3 --> S_rs1["Adivinhar rs1 (5)"]
S_rs1 --> S_rs2["Adivinhar rs2 (5)"]
S_rs2 --> S_imm["Adivinhar imm (12, encoded)"]
S_imm --> NextInstr
%% B-Type
Format --> BType(["B-Type"])
BType --> B_funct3["Adivinhar funct3 (3)"]
B_funct3 --> B_rs1["Adivinhar rs1 (5)"]
B_rs1 --> B_rs2["Adivinhar rs2 (5)"]
B_rs2 --> B_imm["Adivinhar imm (13, encoded)"]
B_imm --> NextInstr
%% U-Type
Format --> UType(["U-Type"])
UType --> U_rd["Adivinhar rd (5)"]
U_rd --> U_imm["Adivinhar imm (20)"]
U_imm --> NextInstr
%% J-Type
Format --> JType(["J-Type"])
JType --> J_rd["Adivinhar rd (5)"]
J_rd --> J_imm["Adivinhar imm (21, encoded)"]
J_imm --> NextInstr
%% STYLE DEFINITIONS
classDef Adivinhar fill:#cce5ff,stroke:#004085,stroke-width:2px;
class Opcode,R_rd,R_funct3,R_rs1,R_rs2,R_funct7,I_rd,I_funct3,I_rs1,I_imm,S_funct3,S_rs1,S_rs2,S_imm,B_funct3,B_rs1,B_rs2,B_imm,U_rd,U_imm,J_rd,J_imm Adivinhar;
Todas as jogadas devem ser informadas em binário na console!
Procure usar programas com instruções bem diversas, por exemplo:
Para garantir que as codificações estão corretas, seu programa deve invocar o GCC para gerá-la automaticamente.
Depois você pode extrair os campos e gerar tabelas como a seguinte:
Instr. | Opcode | rd | funct3 | rs1 | rs2 | funct7 | imm (decimal/hex) |
---|---|---|---|---|---|---|---|
xor x5,x1,x2 | 0110011 | 5 | 100 | 1 | 2 | 0000000 | - |
slli x6,x5,3 | 0010011 | 6 | 001 | 5 | - | 0000000 | shamt=3 |
lbu x7,8(x6) | 0000011 | 7 | 100 | 6 | - | - | 8 |
sb x7,16(x5) | 0100011 | - | 001 | 5 | 7 | - | 16 |
bne x5,x6,label | 1100011 | - | 001 | 5 | 6 | - | offset(label)=calculado |
lui x8,0xABCDE | 0110111 | 8 | - | - | - | - | 0xABCDE |
jal x1,end | 1101111 | 1 | - | - | - | - | offset(end)=calculado |
addi x9,x0,7 | 0010011 | 9 | 000 | 0 | - | - | 7 |
nop | 0010011 | 0 | 000 | 0 | - | - | 0 |
O jogo deve executar em sistemas Linux apenas no modo console. Incluir comentários no código fonte e dependências necessárias para sua execução.