From eae153f27e68e99783cc2942c200d2cd11953196 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 24 Nov 2018 00:01:26 +0000 Subject: [PATCH] cleanup cpu_decode.py --- cpu_decoder.py | 118 +++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 73 deletions(-) diff --git a/cpu_decoder.py b/cpu_decoder.py index 93dbe63..d8b4680 100644 --- a/cpu_decoder.py +++ b/cpu_decoder.py @@ -30,6 +30,11 @@ from riscvdefs import * from cpudefs import * class CPUDecoder(Module): + """ decodes a 32-bit instruction into an immediate and other constituent + parts, including the opcode and funct3 and funct7, followed by + a further (hierarchical) breakdown of the action required to be taken. + unidentified actions are decoded as an illegal instruction trap. + """ def __init__(self): self.instruction = Signal(32) @@ -204,11 +209,37 @@ class CPUDecoder(Module): return Case(self.funct3, c) + def calculate_system_action(self): + """ decode system action + """ + c = {} + b1 = Constant(1, 32) + regz = Constant(0, 5) + # ebreak + c[funct3_ecall_ebreak] = \ + If((self.immediate != ~b1) | (self.rs1 != regz) | \ + (self.rd != regz), + self.decode_action.eq(decode_action_trap_illegal_instruction)).\ + Else( + self.decode_action.eq(decode_action_trap_ecall_ebreak)) + # csrs + for op in [ funct3_csrrw, funct3_csrrs, funct3_csrrc, + funct3_csrrwi, funct3_csrrsi, funct3_csrrci]: + c[op] = self.decode_action.eq(decode_action_csr) + # default + c["default"] = \ + self.decode_action.eq(decode_action_trap_illegal_instruction) + + return Case(self.funct3, c) + def calculate_action(self): - """ calculate action + """ calculate action based on opcode. + + this is a first level case statement that calls down to 2nd + level case (and in some cases if logic) mostly using funct3 + (funct7 in the case of arith ops). """ c = {} - # load opcode c[opcode_load] = self.calculate_load_action() c[opcode_misc_mem] = self.calculate_misc_action() c[opcode_op_imm] = self.calculate_op_action() @@ -219,80 +250,21 @@ class CPUDecoder(Module): c[opcode_branch] = self.calculate_branch_action() c[opcode_jalr] = self.calculate_jalr_action() c[opcode_jal] = self.decode_action.eq(decode_action_jal) + c[opcode_system] = self.calculate_system_action() + + # big batch of unrecognised opcodes: throw trap. + for o in [ opcode_load_fp, opcode_custom_0, opcode_op_imm_32, + opcode_48b_escape_0, opcode_store_fp, opcode_custom_1, + opcode_amo, opcode_op_32, opcode_64b_escape, + opcode_madd, opcode_msub, opcode_nmsub, + opcode_nmadd, opcode_op_fp, opcode_reserved_10101, + opcode_rv128_0, opcode_48b_escape_1, opcode_reserved_11010, + opcode_reserved_11101, opcode_rv128_1, opcode_80b_escape, + "default", ]: + c[o] = self.decode_action.eq(decode_action_trap_illegal_instruction) return Case(self.opcode, c) -""" - - function `decode_action calculate_action( - input [6:0] funct7, - input [2:0] funct3, - input [4:0] rd, - input [4:0] rs1, - input [4:0] rs2, - input [31:0] immediate, - input [6:0] opcode); - begin - case(opcode) - `opcode_system: begin - case(funct3) - `funct3_ecall_ebreak: - if((rs1 != 0) | (rd != 0) | ((immediate & ~32'b1) != 0)) - calculate_action = `decode_action_trap_illegal_instruction; - else - calculate_action = `decode_action_trap_ecall_ebreak; - `funct3_csrrw, - `funct3_csrrs, - `funct3_csrrc, - `funct3_csrrwi, - `funct3_csrrsi, - `funct3_csrrci: - calculate_action = `decode_action_csr; - default: - calculate_action = `decode_action_trap_illegal_instruction; - endcase - end - `opcode_load_fp, - `opcode_custom_0, - `opcode_op_imm_32, - `opcode_48b_escape_0, - `opcode_store_fp, - `opcode_custom_1, - `opcode_amo, - `opcode_op_32, - `opcode_64b_escape, - `opcode_madd, - `opcode_msub, - `opcode_nmsub, - `opcode_nmadd, - `opcode_op_fp, - `opcode_reserved_10101, - `opcode_rv128_0, - `opcode_48b_escape_1, - `opcode_reserved_11010, - `opcode_reserved_11101, - `opcode_rv128_1, - `opcode_80b_escape: begin - calculate_action = `decode_action_trap_illegal_instruction; - end - default: - calculate_action = `decode_action_trap_illegal_instruction; - endcase - end - endfunction - - assign decode_action = calculate_action(funct7, - funct3, - rd, - rs1, - rs2, - immediate, - opcode); - - endmodule -""" - - if __name__ == "__main__": example = CPUDecoder() print(verilog.convert(example, -- 2.30.2