vexriscv: reset wishbone bus on CPU reset
[litex.git] / litex / soc / tools / vexriscv_debug.py
1 #!/usr/bin/env python3
2
3 import sys
4 import os
5 import time
6 import threading
7 import argparse
8 import socket
9 import struct
10 from litex.soc.tools.remote import RemoteClient
11
12 class ConnectionClosed(Exception):
13 pass
14
15 # struct vexriscv_req {
16 # uint8_t readwrite;
17 # uint8_t size;
18 # uint32_t address;
19 # uint32_t data;
20 #} __attribute__((packed));
21 class VexRiscvDebugPacket():
22 def __init__(self, data):
23 self.is_write, self.size, self.address, self.value = struct.unpack("=?BII", data)
24
25 class VexRiscvDebugBridge():
26 def __init__(self):
27 self._get_args()
28
29 def open(self):
30 if not hasattr(self, "debugger_socket"):
31 self.debugger_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
32 self.debugger_socket.bind(('',7893))
33 self.debugger_socket.listen(0)
34
35 if not hasattr(self, "rc"):
36 self.rc = RemoteClient(csr_csv=self.args.csr)
37 self.rc.open()
38 self.core_reg = self.rc.regs.cpu_or_bridge_debug_core
39 self.data_reg = self.rc.regs.cpu_or_bridge_debug_data
40 self.refresh_reg = self.rc.regs.cpu_or_bridge_debug_refresh
41
42 def _get_args(self):
43 parser = argparse.ArgumentParser()
44 parser.add_argument("--csr", default="test/csr.csv", help="csr mapping file")
45 self.args = parser.parse_args()
46
47 def accept(self):
48 if hasattr(self, "debugger"):
49 return
50 print("Waiting for connection from debugger...")
51 self.debugger, address = self.debugger_socket.accept()
52 print("Accepted debugger connection from {}".format(address[0]))
53
54 def _refresh_reg(self, reg):
55 self.refresh_reg.write(reg)
56
57 def read_core(self):
58 self._refresh_reg(0)
59 self.write_to_debugger(self.core_reg.read())
60
61 def read_data(self):
62 self._refresh_reg(4)
63 self.write_to_debugger(self.data_reg.read())
64
65 def write_core(self, value):
66 self.core_reg.write(value)
67
68 def write_data(self, value):
69 self.data_reg.write(value)
70
71 def read_from_debugger(self):
72 data = self.debugger.recv(10)
73 if len(data) != 10:
74 self.debugger.close()
75 del self.debugger
76 raise ConnectionClosed()
77 return VexRiscvDebugPacket(data)
78
79 def write_to_debugger(self, data):
80 self.debugger.send(struct.pack("=I", data))
81
82 def main():
83 vrvb = VexRiscvDebugBridge()
84 vrvb.open()
85
86 while True:
87 vrvb.accept()
88 try:
89 pkt = vrvb.read_from_debugger()
90 if pkt.is_write == True:
91 if pkt.address == 0xf00f0000:
92 vrvb.write_core(pkt.value)
93 elif pkt.address == 0xf00f0004:
94 vrvb.write_data(pkt.value)
95 else:
96 raise "Unrecognized address"
97 else:
98 if pkt.address == 0xf00f0000:
99 vrvb.read_core()
100 elif pkt.address == 0xf00f0004:
101 vrvb.read_data()
102 else:
103 raise "Unrecognized address"
104 except ConnectionClosed:
105 print("Debugger connection closed")
106
107 if __name__ == "__main__":
108 main()