3 * Copyright 2018 Jacob Lifshay
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:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
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
24 `timescale 1ns / 100ps
27 from migen
.fhdl
import verilog
29 from riscvdefs
import *
32 def calculate_immediate(instruction
, immediate
):
33 """ calculate immediate
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
)
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
,
47 ci
[op
] = immediate
.eq(im
)
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
)
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
)
63 im
= Cat(Constant(0, 1), instruction
[12:], )
64 for op
in [opcode_auipc
, opcode_lui
]:
65 ci
[op
] = immediate
.eq(im
)
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
)
75 # R4-type: no immediate
76 for op
in [opcode_madd
, opcode_msub
, opcode_nmsub
, opcode_nmadd
]:
77 ci
[op
] = immediate
.eq(no_imm
)
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
)
87 for op
in [ "default", ]:
88 ci
[op
] = immediate
.eq(no_imm
)
93 class CPUDecoder(Module
):
96 self
.instruction
= Signal(32)
97 self
.funct7
= Signal(7)
98 self
.funct3
= Signal(3)
102 self
.immediate
= Signal(32)
103 self
.opcode
= Signal(7)
104 self
.decode_action
= Signal(decode_action
)
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])
113 # add combinatorial decode opcode case statement
114 ci
= calculate_immediate(self
.instruction
, self
.immediate
)
115 self
.comb
+= Case(self
.opcode
, ci
)
119 function [31:0] calculate_immediate(input [31:0] instruction, input [6:0] opcode);
124 `opcode_48b_escape_0,
127 `opcode_reserved_10101,
129 `opcode_48b_escape_1,
130 `opcode_reserved_11010,
131 `opcode_reserved_11101,
135 calculate_immediate = 32'hXXXXXXXX;
137 calculate_immediate = 32'hXXXXXXXX;
142 assign immediate = calculate_immediate(instruction, opcode);
144 function `decode_action calculate_action(
150 input [31:0] immediate,
161 calculate_action = `decode_action_load;
163 calculate_action = `decode_action_trap_illegal_instruction;
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;
171 calculate_action = `decode_action_trap_illegal_instruction;
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;
177 calculate_action = `decode_action_trap_illegal_instruction;
181 calculate_action = `decode_action_trap_illegal_instruction;
186 if(funct3 == `funct3_slli) begin
188 calculate_action = `decode_action_op_op_imm;
190 calculate_action = `decode_action_trap_illegal_instruction;
192 else if(funct3 == `funct3_srli_srai) begin
193 if(funct7 == 0 || funct7 == 7'h20)
194 calculate_action = `decode_action_op_op_imm;
196 calculate_action = `decode_action_trap_illegal_instruction;
199 calculate_action = `decode_action_op_op_imm;
204 calculate_action = `decode_action_lui_auipc;
211 calculate_action = `decode_action_store;
213 calculate_action = `decode_action_trap_illegal_instruction;
216 `opcode_branch: begin
224 calculate_action = `decode_action_branch;
226 calculate_action = `decode_action_trap_illegal_instruction;
230 if(funct3 == `funct3_jalr)
231 calculate_action = `decode_action_jalr;
233 calculate_action = `decode_action_trap_illegal_instruction;
236 calculate_action = `decode_action_jal;
238 `opcode_system: begin
240 `funct3_ecall_ebreak:
241 if((rs1 != 0) | (rd != 0) | ((immediate & ~32'b1) != 0))
242 calculate_action = `decode_action_trap_illegal_instruction;
244 calculate_action = `decode_action_trap_ecall_ebreak;
251 calculate_action = `decode_action_csr;
253 calculate_action = `decode_action_trap_illegal_instruction;
259 `opcode_48b_escape_0,
270 `opcode_reserved_10101,
272 `opcode_48b_escape_1,
273 `opcode_reserved_11010,
274 `opcode_reserved_11101,
276 `opcode_80b_escape: begin
277 calculate_action = `decode_action_trap_illegal_instruction;
280 calculate_action = `decode_action_trap_illegal_instruction;
285 assign decode_action = calculate_action(funct7,
297 if __name__
== "__main__":
298 example
= CPUDecoder()
299 print(verilog
.convert(example
,
309 example
.decode_action
,