tools: vexriscv_debug: add debug bridge
authorSean Cross <sean@xobs.io>
Fri, 6 Jul 2018 08:08:06 +0000 (16:08 +0800)
committerSean Cross <sean@xobs.io>
Fri, 6 Jul 2018 08:08:06 +0000 (16:08 +0800)
Add a bridge that uses litex_server to go from openocd to wishbone.

Signed-off-by: Sean Cross <sean@xobs.io>
litex/soc/tools/vexriscv_debug.py [new file with mode: 0644]

diff --git a/litex/soc/tools/vexriscv_debug.py b/litex/soc/tools/vexriscv_debug.py
new file mode 100644 (file)
index 0000000..67b6b09
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3\r
+\r
+import sys\r
+import os\r
+import time\r
+import threading\r
+import argparse\r
+import socket\r
+import struct\r
+from litex.soc.tools.remote import RemoteClient\r
+\r
+class ConnectionClosed(Exception):\r
+    pass\r
+\r
+# struct vexriscv_req {\r
+#      uint8_t readwrite;\r
+#      uint8_t size;\r
+#      uint32_t address;\r
+#      uint32_t data;\r
+#} __attribute__((packed));\r
+class VexRiscvDebugPacket():\r
+    def __init__(self, data):\r
+        self.is_write, self.size, self.address, self.value = struct.unpack("=?BII", data)\r
+\r
+class VexRiscvDebugBridge():\r
+    def __init__(self):\r
+        self._get_args()\r
+\r
+    def open(self):\r
+        if not hasattr(self, "debugger_socket"):\r
+            self.debugger_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r
+            self.debugger_socket.bind(('',7893))\r
+            self.debugger_socket.listen(0)\r
+\r
+        if not hasattr(self, "rc"):\r
+            self.rc = RemoteClient(csr_csv=self.args.csr)\r
+            self.rc.open()\r
+            self.core_addr = self.rc.regs.cpu_or_bridge_debug_core.addr\r
+            self.data_addr = self.rc.regs.cpu_or_bridge_debug_data.addr\r
+            self.refresh_addr = self.rc.regs.cpu_or_bridge_debug_refresh.addr\r
+\r
+    def _get_args(self):\r
+        parser = argparse.ArgumentParser()\r
+        parser.add_argument("--csr", default="test/csr.csv", help="csr mapping file")\r
+        self.args = parser.parse_args()\r
+\r
+    def temperature(self):\r
+        return self.rc.read(self.rc.regs.xadc_temperature.addr) * 503.975 / 4096 - 273.15\r
+\r
+    def accept(self):\r
+        if hasattr(self, "debugger"):\r
+            return\r
+        print("Waiting for connection from debugger...")\r
+        self.debugger, address = self.debugger_socket.accept()\r
+        print("Accepted debugger connection from {}".format(address[0]))\r
+\r
+    def _refresh_reg(self, reg):\r
+        self.rc.write(self.refresh_addr, reg)\r
+\r
+    def read_core(self):\r
+        self._refresh_reg(0)\r
+        self.write_to_debugger(self.rc.read(self.core_addr))\r
+\r
+    def read_data(self):\r
+        self._refresh_reg(4)\r
+        self.write_to_debugger(self.rc.read(self.data_addr))\r
+\r
+    def write_core(self, value):\r
+        self.rc.write(self.core_addr, value)\r
+\r
+    def write_data(self, value):\r
+        self.rc.write(self.data_addr, value)\r
+\r
+    def read_from_debugger(self):\r
+        data = self.debugger.recv(10)\r
+        if len(data) != 10:\r
+            self.debugger.close()\r
+            del self.debugger\r
+            raise ConnectionClosed()\r
+        return VexRiscvDebugPacket(data)\r
+\r
+    def write_to_debugger(self, data):\r
+        self.debugger.send(struct.pack("=I", data))\r
+\r
+def main():\r
+    vrvb = VexRiscvDebugBridge()\r
+    vrvb.open()\r
+    print("FPGA Temperature: {} C".format(vrvb.temperature()))\r
+\r
+    while True:\r
+        vrvb.accept()\r
+        try:\r
+            pkt = vrvb.read_from_debugger()\r
+            if pkt.is_write == True:\r
+                if pkt.address == 0xf00f0000:\r
+                    vrvb.write_core(pkt.value)\r
+                elif pkt.address == 0xf00f0004:\r
+                    vrvb.write_data(pkt.value)\r
+                else:\r
+                    raise "Unrecognized address"\r
+            else:\r
+                if pkt.address == 0xf00f0000:\r
+                    vrvb.read_core()\r
+                elif pkt.address == 0xf00f0004:\r
+                    vrvb.read_data()\r
+                else:\r
+                    raise "Unrecognized address"\r
+        except ConnectionClosed:\r
+            print("Debugger connection closed")\r
+\r
+if __name__ == "__main__":\r
+    main()\r