more cpu decode conversion
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 23 Nov 2018 23:44:51 +0000 (23:44 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 23 Nov 2018 23:44:51 +0000 (23:44 +0000)
cpu_decoder.py
riscvdefs.py

index d2eff7d66aaf594b1bbe01be5371220a39702e4b..93dbe634f961d8e4a5395684021e2bf3a22e2df0 100644 (file)
@@ -29,66 +29,6 @@ from migen.fhdl import verilog
 from riscvdefs import *
 from cpudefs import *
 
-def calculate_immediate(instruction, immediate):
-    """ calculate immediate
-    """
-    ci = {}
-    no_imm = 0x0
-
-    # R-type: no immediate
-    for op in [opcode_amo, opcode_op, opcode_op_32, opcode_op_fp]:
-        ci[op] = immediate.eq(no_imm)
-
-    # I-type
-    im = Cat(instruction[20:], Replicate(instruction[31], 20))
-    for op in [opcode_load, opcode_load_fp, opcode_misc_mem,
-               opcode_op_imm, opcode_op_imm_32, opcode_jalr,
-               opcode_system]:
-        ci[op] = immediate.eq(im)
-
-    # S-type
-    im = Cat(instruction[7:12], instruction[25:31],
-             Replicate(instruction[31], 21))
-    for op in [opcode_store, opcode_store_fp]:
-        ci[op] = immediate.eq(im)
-        
-    # B-type
-    im = Cat(Constant(0, 1),
-             instruction[8:12], instruction[25:31],
-             instruction[7], Replicate(instruction[31], 20))
-    for op in [opcode_branch, ]:
-        ci[op] = immediate.eq(im)
-
-    # U-type
-    im = Cat(Constant(0, 1), instruction[12:], )
-    for op in [opcode_auipc, opcode_lui]:
-        ci[op] = immediate.eq(im)
-
-    # J-type
-    im = Cat(Constant(0, 1),
-             instruction[21:25], instruction[25:31],
-             instruction[20], instruction[12:20],
-             Replicate(instruction[31], 12))
-    for op in [opcode_jal, ]:
-        ci[op] = immediate.eq(im)
-
-    # R4-type: no immediate
-    for op in [opcode_madd, opcode_msub, opcode_nmsub, opcode_nmadd]:
-        ci[op] = immediate.eq(no_imm)
-
-    # unknown
-    for op in [ opcode_custom_0, opcode_48b_escape_0, opcode_custom_1,
-                opcode_64b_escape, opcode_reserved_10101, opcode_rv128_0,
-                opcode_48b_escape_1, opcode_reserved_11010,
-                opcode_reserved_11101, opcode_rv128_1, opcode_80b_escape]:
-        ci[op] = immediate.eq(no_imm)
-
-    # default
-    for op in [ "default", ]:
-        ci[op] = immediate.eq(no_imm)
-
-    return ci
-
 class CPUDecoder(Module):
 
     def __init__(self):
@@ -102,44 +42,116 @@ class CPUDecoder(Module):
         self.opcode = Signal(7)
         self.decode_action = Signal(decode_action)
 
+        # decode bits of instruction
         self.comb += self.funct7.eq(self.instruction[25:32])
         self.comb += self.funct3.eq(self.instruction[12:15])
-        self.comb += self.rd.eq(self.instruction[7:12])
-        self.comb += self.rs1.eq(self.instruction[15:20])
-        self.comb += self.rs2.eq(self.instruction[20:25])
+        self.comb += self.rd.eq    (self.instruction[7:12])
+        self.comb += self.rs1.eq   (self.instruction[15:20])
+        self.comb += self.rs2.eq   (self.instruction[20:25])
         self.comb += self.opcode.eq(self.instruction[0:7])
 
-        # add combinatorial decode opcode case statement
-        ci = calculate_immediate(self.instruction, self.immediate)
-        self.comb += Case(self.opcode, ci)
-
+        # add combinatorial decode opcode case statements for immed and action
+        self.comb += self.calculate_immediate()
         self.comb += self.calculate_action()
 
-    def calculate_store_action(self):
-        """ decode store action
+    def calculate_immediate(self):
+        """ calculate immediate
+        """
+        ci = {}
+        no_imm = 0x0
+
+        # R-type: no immediate
+        for op in [opcode_amo, opcode_op, opcode_op_32, opcode_op_fp]:
+            ci[op] = self.immediate.eq(no_imm)
+
+        # I-type
+        im = Cat(self.instruction[20:], Replicate(self.instruction[31], 20))
+        for op in [opcode_load, opcode_load_fp, opcode_misc_mem,
+                   opcode_op_imm, opcode_op_imm_32, opcode_jalr,
+                   opcode_system]:
+            ci[op] = self.immediate.eq(im)
+
+        # S-type
+        im = Cat(self.instruction[7:12], self.instruction[25:31],
+                 Replicate(self.instruction[31], 21))
+        for op in [opcode_store, opcode_store_fp]:
+            ci[op] = self.immediate.eq(im)
+
+        # B-type
+        im = Cat(Constant(0, 1),
+                 self.instruction[8:12], self.instruction[25:31],
+                 self.instruction[7], Replicate(self.instruction[31], 20))
+        for op in [opcode_branch, ]:
+            ci[op] = self.immediate.eq(im)
+
+        # U-type
+        im = Cat(Constant(0, 1), self.instruction[12:], )
+        for op in [opcode_auipc, opcode_lui]:
+            ci[op] = self.immediate.eq(im)
+
+        # J-type
+        im = Cat(Constant(0, 1),
+                 self.instruction[21:25], self.instruction[25:31],
+                 self.instruction[20], self.instruction[12:20],
+                 Replicate(self.instruction[31], 12))
+        for op in [opcode_jal, ]:
+            ci[op] = self.immediate.eq(im)
+
+        # R4-type: no immediate
+        for op in [opcode_madd, opcode_msub, opcode_nmsub, opcode_nmadd]:
+            ci[op] = self.immediate.eq(no_imm)
+
+        # unknown
+        for op in [ opcode_custom_0, opcode_48b_escape_0, opcode_custom_1,
+                    opcode_64b_escape, opcode_reserved_10101, opcode_rv128_0,
+                    opcode_48b_escape_1, opcode_reserved_11010,
+                    opcode_reserved_11101, opcode_rv128_1, opcode_80b_escape]:
+            ci[op] = self.immediate.eq(no_imm)
+
+        # default
+        for op in [ "default", ]:
+            ci[op] = self.immediate.eq(no_imm)
+
+        return Case(self.opcode, ci)
+
+    def _decode_funct3(self, options, action):
+        """ decode by list of cases
         """
         c = {}
         # load opcode
-        for op in [ funct3_sb, funct3_sh, funct3_sw, ]:
-            c[op] = self.decode_action.eq(decode_action_store)
+        for op in options:
+            c[op] = self.decode_action.eq(action)
         # default
         c["default"] = \
             self.decode_action.eq(decode_action_trap_illegal_instruction)
 
         return Case(self.funct3, c)
 
+    def calculate_store_action(self):
+        """ decode store action
+        """
+        return self._decode_funct3([ funct3_sb, funct3_sh, funct3_sw, ],
+                                    decode_action_store)
+
     def calculate_load_action(self):
         """ decode load action
         """
-        c = {}
-        # load opcode
-        for op in [ funct3_lb, funct3_lbu, funct3_lh, funct3_lhu, funct3_lw, ]:
-            c[op] = self.decode_action.eq(decode_action_load)
-        # default
-        c["default"] = \
-            self.decode_action.eq(decode_action_trap_illegal_instruction)
+        return self._decode_funct3([ funct3_lb, funct3_lbu, funct3_lh,
+                                     funct3_lhu, funct3_lw, ],
+                                    decode_action_load)
 
-        return Case(self.funct3, c)
+    def calculate_branch_action(self):
+        """ decode branch action
+        """
+        return self._decode_funct3([ funct3_beq, funct3_bne, funct3_blt,
+                                     funct3_bge, funct3_bltu, funct3_bgeu ],
+                                    decode_action_branch)
+
+    def calculate_jalr_action(self):
+        """ decode jalr action
+        """
+        return self._decode_funct3([ funct3_jalr, ],
+                                    decode_action_jalr)
 
     def calculate_op_action(self):
         """ decode op action
@@ -204,11 +216,14 @@ class CPUDecoder(Module):
         c[opcode_lui] = self.decode_action.eq(decode_action_lui_auipc)
         c[opcode_auipc] = self.decode_action.eq(decode_action_lui_auipc)
         c[opcode_store] = self.calculate_store_action()
+        c[opcode_branch] = self.calculate_branch_action()
+        c[opcode_jalr] = self.calculate_jalr_action()
+        c[opcode_jal] = self.decode_action.eq(decode_action_jal)
 
         return Case(self.opcode, c)
 
 """
-        
+
         function `decode_action calculate_action(
             input [6:0] funct7,
             input [2:0] funct3,
@@ -219,28 +234,6 @@ class CPUDecoder(Module):
             input [6:0] opcode);
         begin
             case(opcode)
-            `opcode_branch: begin
-                case(funct3)
-                `funct3_beq,
-                `funct3_bne,
-                `funct3_blt,
-                `funct3_bge,
-                `funct3_bltu,
-                `funct3_bgeu:
-                    calculate_action = `decode_action_branch;
-                default:
-                    calculate_action = `decode_action_trap_illegal_instruction;
-                endcase
-            end
-            `opcode_jalr: begin
-                if(funct3 == `funct3_jalr)
-                    calculate_action = `decode_action_jalr;
-                else
-                    calculate_action = `decode_action_trap_illegal_instruction;
-            end
-            `opcode_jal: begin
-                calculate_action = `decode_action_jal;
-            end
             `opcode_system: begin
                 case(funct3)
                 `funct3_ecall_ebreak:
@@ -287,7 +280,7 @@ class CPUDecoder(Module):
             endcase
         end
         endfunction
-        
+
         assign decode_action = calculate_action(funct7,
                                                 funct3,
                                                 rd,
@@ -295,7 +288,7 @@ class CPUDecoder(Module):
                                                 rs2,
                                                 immediate,
                                                 opcode);
-        
+
     endmodule
 """
 
@@ -303,7 +296,7 @@ class CPUDecoder(Module):
 if __name__ == "__main__":
     example = CPUDecoder()
     print(verilog.convert(example,
-         { 
+         {
            example.instruction,
            example.funct7,
            example.funct3,
index e7a2ab319fb64f6f6d076cca5e17934e9ebac730..14267c5be3650d0fe7ab4157d9f97817039fdac1 100644 (file)
@@ -1,4 +1,3 @@
-
 """
 /*
  * Copyright 2018 Jacob Lifshay
@@ -84,14 +83,17 @@ funct3_blt = Constant(0x4, 3)
 funct3_bge = Constant(0x5, 3)
 funct3_bltu = Constant(0x6, 3)
 funct3_bgeu = Constant(0x7, 3)
+
 funct3_lb = Constant(0x0, 3)
 funct3_lh = Constant(0x1, 3)
 funct3_lw = Constant(0x2, 3)
 funct3_lbu = Constant(0x4, 3)
 funct3_lhu = Constant(0x5, 3)
+
 funct3_sb = Constant(0x0, 3)
 funct3_sh = Constant(0x1, 3)
 funct3_sw = Constant(0x2, 3)
+
 funct3_addi = Constant(0x0, 3)
 funct3_slli = Constant(0x1, 3)
 funct3_slti = Constant(0x2, 3)
@@ -100,6 +102,7 @@ funct3_xori = Constant(0x4, 3)
 funct3_srli_srai = Constant(0x5, 3)
 funct3_ori = Constant(0x6, 3)
 funct3_andi = Constant(0x7, 3)
+
 funct3_add_sub = Constant(0x0, 3)
 funct3_sll = Constant(0x1, 3)
 funct3_slt = Constant(0x2, 3)
@@ -108,8 +111,10 @@ funct3_xor = Constant(0x4, 3)
 funct3_srl_sra = Constant(0x5, 3)
 funct3_or = Constant(0x6, 3)
 funct3_and = Constant(0x7, 3)
+
 funct3_fence = Constant(0x0, 3)
 funct3_fence_i = Constant(0x1, 3)
+
 funct3_ecall_ebreak = Constant(0x0, 3)
 funct3_csrrw = Constant(0x1, 3)
 funct3_csrrs = Constant(0x2, 3)