add clock domains doc to README
[rv32.git] / cpu_decoder.v
1 /*
2 * Copyright 2018 Jacob Lifshay
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 */
23 `timescale 1ns / 100ps
24 `include "riscv.vh"
25 `include "cpu.vh"
26
27 module cpu_decoder(
28 input [31:0] instruction,
29 output [6:0] funct7,
30 output [2:0] funct3,
31 output [4:0] rd,
32 output [4:0] rs1,
33 output [4:0] rs2,
34 output [31:0] immediate,
35 output [6:0] opcode,
36 output `decode_action decode_action
37 );
38
39 assign funct7 = instruction[31:25];
40 assign funct3 = instruction[14:12];
41 assign rd = instruction[11:7];
42 assign rs1 = instruction[19:15];
43 assign rs2 = instruction[24:20];
44 assign opcode = instruction[6:0];
45
46 function [31:0] calculate_immediate(input [31:0] instruction, input [6:0] opcode);
47 begin
48 case(opcode)
49 `opcode_amo,
50 `opcode_op,
51 `opcode_op_32,
52 `opcode_op_fp:
53 // R-type: no immediate
54 calculate_immediate = 32'hXXXXXXXX;
55 `opcode_load,
56 `opcode_load_fp,
57 `opcode_misc_mem,
58 `opcode_op_imm,
59 `opcode_op_imm_32,
60 `opcode_jalr,
61 `opcode_system:
62 // I-type
63 calculate_immediate = {{20{instruction[31]}}, instruction[31:20]};
64 `opcode_store,
65 `opcode_store_fp:
66 // S-type
67 calculate_immediate = {{21{instruction[31]}}, instruction[30:25], instruction[11:7]};
68 `opcode_branch:
69 // B-type
70 calculate_immediate = {{20{instruction[31]}}, instruction[7], instruction[30:25], instruction[11:8], 1'b0};
71 `opcode_auipc,
72 `opcode_lui:
73 // U-type
74 calculate_immediate = {instruction[31:12], 12'b0};
75 `opcode_jal:
76 // J-type
77 calculate_immediate = {{12{instruction[31]}}, instruction[19:12], instruction[20], instruction[30:25], instruction[24:21], 1'b0};
78 `opcode_madd,
79 `opcode_msub,
80 `opcode_nmsub,
81 `opcode_nmadd:
82 // R4-type: no immediate
83 calculate_immediate = 32'hXXXXXXXX;
84 `opcode_custom_0,
85 `opcode_48b_escape_0,
86 `opcode_custom_1,
87 `opcode_64b_escape,
88 `opcode_reserved_10101,
89 `opcode_rv128_0,
90 `opcode_48b_escape_1,
91 `opcode_reserved_11010,
92 `opcode_reserved_11101,
93 `opcode_rv128_1,
94 `opcode_80b_escape:
95 // unknown
96 calculate_immediate = 32'hXXXXXXXX;
97 default:
98 calculate_immediate = 32'hXXXXXXXX;
99 endcase
100 end
101 endfunction
102
103 assign immediate = calculate_immediate(instruction, opcode);
104
105 function `decode_action calculate_action(
106 input [6:0] funct7,
107 input [2:0] funct3,
108 input [4:0] rd,
109 input [4:0] rs1,
110 input [4:0] rs2,
111 input [31:0] immediate,
112 input [6:0] opcode);
113 begin
114 case(opcode)
115 `opcode_load: begin
116 case(funct3)
117 `funct3_lb,
118 `funct3_lbu,
119 `funct3_lh,
120 `funct3_lhu,
121 `funct3_lw:
122 calculate_action = `decode_action_load;
123 default:
124 calculate_action = `decode_action_trap_illegal_instruction;
125 endcase
126 end
127 `opcode_misc_mem: begin
128 if(funct3 == `funct3_fence) begin
129 if((immediate[11:8] == 0) & (rs1 == 0) & (rd == 0))
130 calculate_action = `decode_action_fence;
131 else
132 calculate_action = `decode_action_trap_illegal_instruction;
133 end
134 else if(funct3 == `funct3_fence_i) begin
135 if((immediate[11:0] == 0) & (rs1 == 0) & (rd == 0))
136 calculate_action = `decode_action_fence_i;
137 else
138 calculate_action = `decode_action_trap_illegal_instruction;
139 end
140 else
141 begin
142 calculate_action = `decode_action_trap_illegal_instruction;
143 end
144 end
145 `opcode_op_imm,
146 `opcode_op: begin
147 if(funct3 == `funct3_slli) begin
148 if(funct7 == 0)
149 calculate_action = `decode_action_op_op_imm;
150 else
151 calculate_action = `decode_action_trap_illegal_instruction;
152 end
153 else if(funct3 == `funct3_srli_srai) begin
154 if(funct7 == 0 || funct7 == 7'h20)
155 calculate_action = `decode_action_op_op_imm;
156 else
157 calculate_action = `decode_action_trap_illegal_instruction;
158 end
159 else begin
160 calculate_action = `decode_action_op_op_imm;
161 end
162 end
163 `opcode_lui,
164 `opcode_auipc: begin
165 calculate_action = `decode_action_lui_auipc;
166 end
167 `opcode_store: begin
168 case(funct3)
169 `funct3_sb,
170 `funct3_sh,
171 `funct3_sw:
172 calculate_action = `decode_action_store;
173 default:
174 calculate_action = `decode_action_trap_illegal_instruction;
175 endcase
176 end
177 `opcode_branch: begin
178 case(funct3)
179 `funct3_beq,
180 `funct3_bne,
181 `funct3_blt,
182 `funct3_bge,
183 `funct3_bltu,
184 `funct3_bgeu:
185 calculate_action = `decode_action_branch;
186 default:
187 calculate_action = `decode_action_trap_illegal_instruction;
188 endcase
189 end
190 `opcode_jalr: begin
191 if(funct3 == `funct3_jalr)
192 calculate_action = `decode_action_jalr;
193 else
194 calculate_action = `decode_action_trap_illegal_instruction;
195 end
196 `opcode_jal: begin
197 calculate_action = `decode_action_jal;
198 end
199 `opcode_system: begin
200 case(funct3)
201 `funct3_ecall_ebreak:
202 if((rs1 != 0) | (rd != 0) | ((immediate & ~32'b1) != 0))
203 calculate_action = `decode_action_trap_illegal_instruction;
204 else
205 calculate_action = `decode_action_trap_ecall_ebreak;
206 `funct3_csrrw,
207 `funct3_csrrs,
208 `funct3_csrrc,
209 `funct3_csrrwi,
210 `funct3_csrrsi,
211 `funct3_csrrci:
212 calculate_action = `decode_action_csr;
213 default:
214 calculate_action = `decode_action_trap_illegal_instruction;
215 endcase
216 end
217 `opcode_load_fp,
218 `opcode_custom_0,
219 `opcode_op_imm_32,
220 `opcode_48b_escape_0,
221 `opcode_store_fp,
222 `opcode_custom_1,
223 `opcode_amo,
224 `opcode_op_32,
225 `opcode_64b_escape,
226 `opcode_madd,
227 `opcode_msub,
228 `opcode_nmsub,
229 `opcode_nmadd,
230 `opcode_op_fp,
231 `opcode_reserved_10101,
232 `opcode_rv128_0,
233 `opcode_48b_escape_1,
234 `opcode_reserved_11010,
235 `opcode_reserved_11101,
236 `opcode_rv128_1,
237 `opcode_80b_escape: begin
238 calculate_action = `decode_action_trap_illegal_instruction;
239 end
240 default:
241 calculate_action = `decode_action_trap_illegal_instruction;
242 endcase
243 end
244 endfunction
245
246 assign decode_action = calculate_action(funct7,
247 funct3,
248 rd,
249 rs1,
250 rs2,
251 immediate,
252 opcode);
253
254 endmodule