handle_trap returns values that get manually transferred on trap
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 28 Nov 2018 03:34:22 +0000 (03:34 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 28 Nov 2018 03:34:22 +0000 (03:34 +0000)
cpu.py
cpu_handle_trap.py

diff --git a/cpu.py b/cpu.py
index b12f90e8558223e9274b8b9f9567f6569b601e0b..29cbe574a8e266a5e5b4c30a666a123696d3e3a4 100644 (file)
--- a/cpu.py
+++ b/cpu.py
@@ -235,6 +235,13 @@ class CPU(Module):
     #    return [m.mcause.eq(0),
     #            ]
 
+    def handle_trap(self, mcause, mepc, mie, mpie):
+        s = [mcause.eq(self.new_mcause),
+             mepc.eq(self.new_mepc),
+             mpie.eq(self.new_mpie),
+             mie.eq(self.new_mie)]
+        return s
+
     def main_block(self, mtvec, mip, minfo, misa, csr, mi, m, mstatus, mie,
                          ft, dc,
                          load_store_misaligned,
@@ -242,17 +249,16 @@ class CPU(Module):
                          lui_auipc_result):
         c = {}
         c[FOS.empty] = []
-        c[FOS.trap] = self.handle_trap.eq(1)
+        c[FOS.trap] = self.handle_trap(m.mcause, m.mepc,
+                                       mstatus.mie, mstatus.mpie)
         c[FOS.valid] = self.handle_valid(mtvec, mip, minfo, misa, csr, mi, m,
                                        mstatus, mie, ft, dc,
                                        load_store_misaligned,
                                        loaded_value,
                                        alu_result,
                                        lui_auipc_result)
-        return [self.handle_trap.eq(0),
-                self.regs.w_en.eq(0),
+        return [self.regs.w_en.eq(0),
                 Case(ft.output_state, c),
-                self.handle_trap.eq(0),
                 self.regs.w_en.eq(0)]
 
     def write_register(self, rd, val):
@@ -268,8 +274,7 @@ class CPU(Module):
                            lui_auipc_result):
         # fetch action ack trap
         i = If((ft.action == FA.ack_trap) | (ft.action == FA.noerror_trap),
-                [self.handle_trap.eq(1),
-                ]
+                self.handle_trap(m.mcause, m.mepc, mstatus.mie, mstatus.mpie)
               )
 
         # load
@@ -617,7 +622,10 @@ class CPU(Module):
 
         minfo = MInfo(self.comb)
 
-        self.handle_trap = Signal(reset=0)
+        self.new_mcause = Signal(32)
+        self.new_mepc = Signal(32)
+        self.new_mpie = Signal()
+        self.new_mie = Signal()
 
         ht = Instance("CPUHandleTrap", "cpu_handle_trap",
                       i_ft_action = ft.action,
@@ -625,9 +633,11 @@ class CPU(Module):
                       i_dc_action = dc.act,
                       i_dc_immediate = dc.immediate,
                       i_load_store_misaligned = load_store_misaligned,
-                      o_mcause = m.mcause,
-                      o_mepc = m.mepc,
-                      o_mie = mstatus.mie)
+                      i_mie = mstatus.mie,
+                      o_mcause = self.new_mcause,
+                      o_mepc = self.new_mepc,
+                      o_mpie = self.new_mpie,
+                      o_mie = self.new_mie)
 
         self.specials += ht
 
index c77be862b9893f5022ea87c2ddca9456495a9fdf..ad4510c2364be3613eb72c24053cc7ef6a3f6888 100644 (file)
@@ -44,31 +44,31 @@ class CPUHandleTrap(Module):
         self.clk = ClockSignal()
         self.reset = ResetSignal()
 
-        self.handle_trap = Signal()
         self.ft_action = Signal(fetch_action)
         self.dc_action = Signal(decode_action)
         self.dc_immediate = Signal(32)
-        self.mcause = Signal(32)
-        self.mepc = Signal()
-        self.mpie = Signal()
         self.mie = Signal()
+        self.new_mie = Signal()
+        self.new_mepc = Signal()
+        self.new_mpie = Signal()
+        self.new_mcause = Signal(32)
         self.ft_output_pc = Signal(32)
         self.load_store_misaligned = Signal()
 
-        s = [self.mpie.eq(self.mie),
-             self.mie.eq(0),
-             self.mepc.eq(Mux(self.ft_action == FA.noerror_trap,
+        s = [self.new_mpie.eq(self.mie),
+             self.new_mie.eq(0),
+             self.new_mepc.eq(Mux(self.ft_action == FA.noerror_trap,
                            self.ft_output_pc + 4,
                            self.ft_output_pc))]
 
         # fetch action ack trap
         i = If(self.ft_action == FA.ack_trap,
-                self.mcause.eq(cause_instruction_access_fault)
+                self.new_mcause.eq(cause_instruction_access_fault)
               )
 
         # ecall/ebreak
         i = i.Elif((self.dc_action & DA.trap_ecall_ebreak) != 0,
-                self.mcause.eq(Mux(self.dc_immediate[0],
+                self.new_mcause.eq(Mux(self.dc_immediate[0],
                                 cause_machine_environment_call,
                                 cause_breakpoint))
               )
@@ -76,44 +76,45 @@ class CPUHandleTrap(Module):
         # load
         i = i.Elif((self.dc_action & DA.load) != 0,
                 If(self.load_store_misaligned,
-                    self.mcause.eq(cause_load_address_misaligned)
+                    self.new_mcause.eq(cause_load_address_misaligned)
                 ).Else(
-                    self.mcause.eq(cause_load_access_fault)
+                    self.new_mcause.eq(cause_load_access_fault)
                 )
               )
 
         # store
         i = i.Elif((self.dc_action & DA.store) != 0,
                 If(self.load_store_misaligned,
-                    self.mcause.eq(cause_store_amo_address_misaligned)
+                    self.new_mcause.eq(cause_store_amo_address_misaligned)
                 ).Else(
-                    self.mcause.eq(cause_store_amo_access_fault)
+                    self.new_mcause.eq(cause_store_amo_access_fault)
                 )
               )
 
         # jal/jalr -> misaligned=error, otherwise jump
         i = i.Elif((self.dc_action & (DA.jal | DA.jalr | DA.branch)) != 0,
-                self.mcause.eq(cause_instruction_address_misaligned)
+                self.new_mcause.eq(cause_instruction_address_misaligned)
               )
 
         # defaults to illegal instruction
-        i = i.Else(self.mcause.eq(cause_illegal_instruction))
+        i = i.Else(self.new_mcause.eq(cause_illegal_instruction))
 
         s.append(i)
 
-        self.sync += If(self.handle_trap, s)
+        self.sync += s
 
 
 if __name__ == "__main__":
     example = CPUHandleTrap()
     print(verilog.convert(example,
          {
-            example.handle_trap,
             example.ft_action,
             example.dc_immediate,
-            example.mcause,
-            example.mpie,
             example.mie,
+            example.new_mcause,
+            example.new_mepc,
+            example.new_mpie,
+            example.new_mie,
             example.ft_output_pc,
             example.load_store_misaligned,
            }))