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