cleanup cpu_decode.py
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 24 Nov 2018 00:01:26 +0000 (00:01 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 24 Nov 2018 00:01:26 +0000 (00:01 +0000)
cpu_decoder.py

index 93dbe634f961d8e4a5395684021e2bf3a22e2df0..d8b4680707124c8562e123f0eaa5ced7ccd159b6 100644 (file)
@@ -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,