split out cpu handle_trap
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 27 Nov 2018 04:08:38 +0000 (04:08 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 27 Nov 2018 04:08:38 +0000 (04:08 +0000)
cpu_handle_trap.py [new file with mode: 0644]

diff --git a/cpu_handle_trap.py b/cpu_handle_trap.py
new file mode 100644 (file)
index 0000000..c77be86
--- /dev/null
@@ -0,0 +1,119 @@
+"""
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+`timescale 1ns / 1ps
+`include "riscv.vh"
+`include "cpu.vh"
+"""
+
+import string
+from migen import *
+from migen.fhdl import verilog
+from migen.fhdl.structure import _Operator
+
+from riscvdefs import *
+from cpudefs import *
+
+
+class CPUHandleTrap(Module):
+    """
+    """
+
+    def __init__(self):
+        Module.__init__(self)
+        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.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,
+                           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)
+              )
+
+        # ecall/ebreak
+        i = i.Elif((self.dc_action & DA.trap_ecall_ebreak) != 0,
+                self.mcause.eq(Mux(self.dc_immediate[0],
+                                cause_machine_environment_call,
+                                cause_breakpoint))
+              )
+
+        # load
+        i = i.Elif((self.dc_action & DA.load) != 0,
+                If(self.load_store_misaligned,
+                    self.mcause.eq(cause_load_address_misaligned)
+                ).Else(
+                    self.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)
+                ).Else(
+                    self.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)
+              )
+
+        # defaults to illegal instruction
+        i = i.Else(self.mcause.eq(cause_illegal_instruction))
+
+        s.append(i)
+
+        self.sync += If(self.handle_trap, 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.ft_output_pc,
+            example.load_store_misaligned,
+           }))