add get_fetch_action ready for conversion
[rv32.git] / cpu.py
diff --git a/cpu.py b/cpu.py
index 4fbeafe61938fff05d0a6994e6240b4dd9705966..47985745841e156ea462c3f12b8066e511c8f791 100644 (file)
--- a/cpu.py
+++ b/cpu.py
@@ -80,7 +80,7 @@ class MStatus:
         self.uie = Signal(name="mstatus_uie")
 
         for n in dir(self):
-            if n in ['mpp', 'comb', 'sync'] or n.startswith("_"):
+            if n in ['make', 'mpp', 'comb', 'sync'] or n.startswith("_"):
                 continue
             self.comb += getattr(self, n).eq(0x0)
         self.comb += self.mpp.eq(0b11)
@@ -88,6 +88,18 @@ class MStatus:
         self.sync += self.mie.eq(0)
         self.sync += self.mpie.eq(0)
 
+    def make(self):
+        return Cat(
+                self.uie, self.sie, Constant(0), self.mie,
+                self.upie, self.spie, Constant(0), self.mpie,
+                self.spp, Constant(0, 2), self.mpp,
+                self.fs, self.xs, self.mprv, self._sum,
+                self.mxr, self.tvm, self.tw, self.tsr,
+                Constant(0, 8),
+                (self.xs == Constant(0b11, 2)) | (self.fs == Constant(0b11, 2))
+                )
+
+
 class MIE:
     def __init__(self, comb, sync):
         self.comb = comb
@@ -102,7 +114,7 @@ class MIE:
         self.usie = Signal(name="mie_usie")
 
         for n in dir(self):
-            if n in ['comb', 'sync'] or n.startswith("_"):
+            if n in ['make', 'comb', 'sync'] or n.startswith("_"):
                 continue
             self.comb += getattr(self, n).eq(0x0)
 
@@ -110,6 +122,25 @@ class MIE:
         self.sync += self.mtie.eq(0)
         self.sync += self.msie.eq(0)
 
+class MIP:
+    def __init__(self, comb, sync):
+        self.comb = comb
+        self.sync = sync
+        self.meip = Signal(name="mip_meip") # TODO: implement ext interrupts
+        self.seip = Signal(name="mip_seip")
+        self.ueip = Signal(name="mip_uiep")
+        self.mtip = Signal(name="mip_mtip") # TODO: implement timer interrupts
+        self.stip = Signal(name="mip_stip")
+        self.msip = Signal(name="mip_stip")
+        self.utip = Signal(name="mip_utip")
+        self.ssip = Signal(name="mip_ssip")
+        self.usip = Signal(name="mip_usip")
+
+        for n in dir(self):
+            if n in ['comb', 'sync'] or n.startswith("_"):
+                continue
+            self.comb += getattr(self, n).eq(0x0)
+
 
 class M:
     def __init__(self, comb, sync):
@@ -173,6 +204,82 @@ class CPU(Module):
         for f in [F3.csrrc, F3.csrrci]: c[f] = ~written_value & previous_value
         return Case(funct3, c)
 
+    """
+    def get_fetch_action(self, fetch_output_state,
+        input `decode_action decode_action,
+        input load_store_misaligned,
+        input memory_interface_rw_address_valid,
+        input memory_interface_rw_wait,
+        input branch_taken,
+        input misaligned_jump_target,
+        input csr_op_is_valid
+        );
+    begin
+        case(fetch_output_state)
+        `fetch_output_state_empty:
+            get_fetch_action = `fetch_action_default;
+        `fetch_output_state_trap:
+            get_fetch_action = `fetch_action_ack_trap;
+        `fetch_output_state_valid: begin
+            if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
+                get_fetch_action = `fetch_action_error_trap;
+            end
+            else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
+                get_fetch_action = `fetch_action_noerror_trap;
+            end
+            else if((decode_action & (`decode_action_load | `decode_action_store)) != 0) begin
+                if(load_store_misaligned | ~memory_interface_rw_address_valid) begin
+                    get_fetch_action = `fetch_action_error_trap;
+                end
+                else if(memory_interface_rw_wait) begin
+                    get_fetch_action = `fetch_action_wait;
+                end
+                else begin
+                    get_fetch_action = `fetch_action_default;
+                end
+            end
+            else if((decode_action & `decode_action_fence_i) != 0) begin
+                get_fetch_action = `fetch_action_fence;
+            end
+            else if((decode_action & `decode_action_branch) != 0) begin
+                if(branch_taken) begin
+                    if(misaligned_jump_target) begin
+                        get_fetch_action = `fetch_action_error_trap;
+                    end
+                    else begin
+                        get_fetch_action = `fetch_action_jump;
+                    end
+                end
+                else
+                begin
+                    get_fetch_action = `fetch_action_default;
+                end
+            end
+            else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
+                if(misaligned_jump_target) begin
+                    get_fetch_action = `fetch_action_error_trap;
+                end
+                else begin
+                    get_fetch_action = `fetch_action_jump;
+                end
+            end
+            else if((decode_action & `decode_action_csr) != 0) begin
+                if(csr_op_is_valid)
+                    get_fetch_action = `fetch_action_default;
+                else
+                    get_fetch_action = `fetch_action_error_trap;
+            end
+            else begin
+                get_fetch_action = `fetch_action_default;
+            end
+        end
+        default:
+            get_fetch_action = 32'hXXXXXXXX;
+        endcase
+    end
+    endfunction
+    """
+
     def __init__(self):
         self.clk = ClockSignal()
         self.reset = ResetSignal()
@@ -404,8 +511,18 @@ class CPU(Module):
 
         misa = Misa(self.comb, self.sync)
 
-        #self.sync += If(self.reset, self.reset_to_initial(m, mstatus, mie,
-        #                                                  registers))
+        mvendorid = Signal(32)
+        marchid = Signal(32)
+        mimpid = Signal(32)
+        mhartid = Signal(32)
+        self.comb += mvendorid.eq(Constant(0, 32))
+        self.comb += marchid.eq(Constant(0, 32))
+        self.comb += mimpid.eq(Constant(0, 32))
+        self.comb += mhartid.eq(Constant(0, 32))
+
+        mip = MIP(self.comb, self.sync)
+
+        csr_op_is_valid = Signal()
 
 if __name__ == "__main__":
     example = CPU()
@@ -422,64 +539,6 @@ if __name__ == "__main__":
 
 """
 
-    parameter mvendorid = 32'b0;
-    parameter marchid = 32'b0;
-    parameter mimpid = 32'b0;
-    parameter mhartid = 32'b0;
-
-    function [31:0] make_mstatus(input mstatus_tsr,
-        input mstatus_tw,
-        input mstatus_tvm,
-        input mstatus_mxr,
-        input mstatus_sum,
-        input mstatus_mprv,
-        input [1:0] mstatus_xs,
-        input [1:0] mstatus_fs,
-        input [1:0] mstatus_mpp,
-        input mstatus_spp,
-        input mstatus_mpie,
-        input mstatus_spie,
-        input mstatus_upie,
-        input mstatus_mie,
-        input mstatus_sie,
-        input mstatus_uie);
-    begin
-        make_mstatus = {(mstatus_xs == 2'b11) | (mstatus_fs == 2'b11),
-            8'b0,
-            mstatus_tsr,
-            mstatus_tw,
-            mstatus_tvm,
-            mstatus_mxr,
-            mstatus_sum,
-            mstatus_mprv,
-            mstatus_xs,
-            mstatus_fs,
-            mstatus_mpp,
-            2'b0,
-            mstatus_spp,
-            mstatus_mpie,
-            1'b0,
-            mstatus_spie,
-            mstatus_upie,
-            mstatus_mie,
-            1'b0,
-            mstatus_sie,
-            mstatus_uie};
-    end
-    endfunction
-
-    wire mip_meip = 0; // TODO: implement external interrupts
-    parameter mip_seip = 0;
-    parameter mip_ueip = 0;
-    wire mip_mtip = 0; // TODO: implement timer interrupts
-    parameter mip_stip = 0;
-    parameter mip_utip = 0;
-    parameter mip_msip = 0;
-    parameter mip_ssip = 0;
-    parameter mip_usip = 0;
-
-    wire csr_op_is_valid;
-
     function `fetch_action get_fetch_action(
         input `fetch_output_state fetch_output_state,
         input `decode_action decode_action,