--- /dev/null
+#!/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