-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDecoder.h
More file actions
111 lines (94 loc) · 3.43 KB
/
Decoder.h
File metadata and controls
111 lines (94 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* @class Decoder
* @brief Decodes raw 32 bit RISC-V instructions into structured fields.
*
* This class provides functionality to decode different types of RISC-V
* instructions (R,I,S,B,U,J types) into a common structured format
* for easier instruction execution by the CPU emulator.
*/
#pragma once
#include <iostream>
#include <cstdint>
#include <string>
#include <array>
class Decoder {
public:
/**
* @struct DecodedInstr
* @brief Represents a fully decoded RISC-V instruction.
*
* Contains all relevant fields extracted from the instruction word,
* including opcode, function codes, registers, immediate value, and
* instruction format type.
*/
struct DecodedInstr {
uint8_t opcode; // Opcode field identifying instruction type
uint8_t funct3; // 3 bit function field used for further opcode decoding
uint8_t funct7; // 7 bit function field for R type instructions
uint8_t rd; // Destination register index
uint8_t rs1; // Source register 1
uint8_t rs2; // Source register 2
int32_t imm; // Sign extended immediate
std::string type; // Instruction format type
/**
* @brief Constructs a DecodedInstr with optional default values.
* @param op Opcode
* @param f3 funct3
* @param f7 funct7
* @param dr Destination register
* @param s1 Source register 1
* @param s2 Source register 2
* @param imm Immediate value
* @param type Instruction format type string
*/
DecodedInstr(uint8_t op = 0, uint8_t f3 = 0, uint8_t f7 = 0, uint8_t dr = 0,
uint8_t s1 = 0, uint8_t s2 = 0, int32_t imm = 0, std::string type = "")
: opcode(op), funct3(f3), funct7(f7), rd(dr), rs1(s1), rs2(s2), imm(imm), type(std::move(type)) {
}
};
enum InstrType {
R_TYPE,
I_TYPE,
S_TYPE,
B_TYPE,
U_TYPE,
J_TYPE,
ECALL_TYPE,
JALR_TYPE,
UNKNOWN_TYPE
};
using DecodeFunc = DecodedInstr(*)(uint32_t);
/**
* @brief Constructor for the Decoder that initializes the decoder table.
*/
Decoder();
/**
* @brief Decodes a 32 bit instruction into a structured DecodedInstr.
* @param instr 32 bit instruction word.
* @return DecodedInstr struct containing decoded fields.
*/
DecodedInstr decode(uint32_t instr);
/**
* @brief Sign extends a integer to a 32 bit signed integer.
*
* Extends the sign integer at the specified bit width to the full 32 bits.
*
* @param value The original unsigned bit value.
* @param bitWidth The bit position of the sign bit
* @return The sign extended 32 bit signed integer.
*/
static int32_t signExtend(uint32_t value, int bitWidth);
private:
DecodeFunc decodeTable[128] = {}; // Function pointer table indexed by opcode for decoding
/**
* @brief Initializes the decodeTable mapping opcodes to decode functions.
*/
void initDecodeTable();
// Static decoding functions for each instruction format:
static DecodedInstr decodeR(uint32_t instr);
static DecodedInstr decodeI(uint32_t instr);
static DecodedInstr decodeS(uint32_t instr);
static DecodedInstr decodeB(uint32_t instr);
static DecodedInstr decodeU(uint32_t instr);
static DecodedInstr decodeJ(uint32_t instr);
};