-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecoder.sv
More file actions
151 lines (129 loc) · 5.17 KB
/
Copy pathdecoder.sv
File metadata and controls
151 lines (129 loc) · 5.17 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
`default_nettype none
module DECODER #(
parameter PC_ADDR = 32'h8000_0000,
parameter ADDR_WIDTH = 32,
parameter DATA_WIDTH = 32
)
(
//input wire clk,
//input wire reset,
// From IFID stage
input wire [31:0] instruction,
output wire [4:0] rd, // Destination register index
// 0: No destination register (e.g., Store, Branch)
// 1-31: Valid destination register indices
output wire [4:0] rs1, // Source register 1 index
// 0-31: Valid source register indices
output wire [4:0] rs2, // Source register 2 index
// 0-31: Valid source register indices
// For instructions that do not use rs2, this can be ignored
output wire [DATA_WIDTH-1:0] imm, // Immediate value, sign-extended
// 0: No immediate value (e.g., R-type)
// Non-zero: Immediate value extracted and sign-extended
output wire imm_type // Immediate type indicator
// 1: Instruction includes an immediate value
// 0: Instruction does not include an immediate value
);
reg [4:0] rd_reg;
reg [4:0] rs1_reg;
reg [4:0] rs2_reg;
reg [DATA_WIDTH-1:0] imm_reg;
reg imm_type_reg;
assign rd = rd_reg;
assign rs1 = rs1_reg;
assign rs2 = rs2_reg;
assign imm = imm_reg;
assign imm_type = imm_type_reg;
wire [6:0] opcode = instruction[6:0];
wire [2:0] funct3 = instruction[14:12];
wire [6:0] funct7 = instruction[31:25];
localparam OPCODE_R_TYPE = 7'b0110011;
localparam OPCODE_I_TYPE = 7'b0010011;
localparam OPCODE_LOAD = 7'b0000011;
localparam OPCODE_STORE = 7'b0100011;
localparam OPCODE_BRANCH = 7'b1100011;
localparam OPCODE_JALR = 7'b1100111;
localparam OPCODE_JAL = 7'b1101111;
localparam OPCODE_LUI = 7'b0110111;
localparam OPCODE_AUIPC = 7'b0010111;
always @(*) begin
// Default values
rd_reg <= 5'b0;
rs1_reg <= 5'b0;
rs2_reg <= 5'b0;
imm_reg <= {DATA_WIDTH{1'b0}};
imm_type_reg <= 1'b0;
case (opcode)
OPCODE_R_TYPE: begin
rd_reg <= instruction[11:7];
rs1_reg <= instruction[19:15];
rs2_reg <= instruction[24:20];
imm_reg <= {DATA_WIDTH{1'b0}};
imm_type_reg <= 1'b0;
end
OPCODE_I_TYPE: begin
rd_reg <= instruction[11:7];
rs1_reg <= instruction[19:15];
rs2_reg <= 5'b0;
imm_reg <= {{(DATA_WIDTH-12){instruction[31]}}, instruction[31:20]};
imm_type_reg <= 1'b1;
end
OPCODE_LOAD: begin
rd_reg <= instruction[11:7];
rs1_reg <= instruction[19:15];
rs2_reg <= 5'b0;
imm_reg <= {{(DATA_WIDTH-12){instruction[31]}}, instruction[31:20]};
imm_type_reg <= 1'b1;
end
OPCODE_STORE: begin
rd_reg <= 5'b0;
rs1_reg <= instruction[19:15];
rs2_reg <= instruction[24:20];
imm_reg <= {{(DATA_WIDTH-12){instruction[31]}}, instruction[31:25], instruction[11:7]};
imm_type_reg <= 1'b1;
end
OPCODE_BRANCH: begin
rd_reg <= 5'b0;
rs1_reg <= instruction[19:15];
rs2_reg <= instruction[24:20];
imm_reg <= {{(DATA_WIDTH-13){instruction[31]}}, instruction[31], instruction[7], instruction[30:25], instruction[11:8], 1'b0};
imm_type_reg <= 1'b1;
end
OPCODE_JALR: begin
rd_reg <= instruction[11:7];
rs1_reg <= instruction[19:15];
rs2_reg <= 5'b0;
imm_reg <= {{(DATA_WIDTH-12){instruction[31]}}, instruction[31:20]};
imm_type_reg <= 1'b1;
end
OPCODE_JAL: begin
rd_reg <= instruction[11:7];
rs1_reg <= 5'b0;
rs2_reg <= 5'b0;
imm_reg <= {{11{instruction[31]}}, instruction[31], instruction[19:12], instruction[20], instruction[30:21], 1'b0};
imm_type_reg <= 1'b1;
end
OPCODE_LUI: begin
rd_reg <= instruction[11:7];
rs1_reg <= 5'b0;
rs2_reg <= 5'b0;
imm_reg <= {instruction[31:12], 12'b0};
imm_type_reg <= 1'b1;
end
OPCODE_AUIPC: begin
rd_reg <= instruction[11:7];
rs1_reg <= 5'b0;
rs2_reg <= 5'b0;
imm_reg <= {instruction[31:12], 12'b0};
imm_type_reg <= 1'b1;
end
default: begin
rd_reg <= 5'b0;
rs1_reg <= 5'b0;
rs2_reg <= 5'b0;
imm_reg <= {DATA_WIDTH{1'b0}};
imm_type_reg <= 1'b0;
end
endcase
end
endmodule