79418e28ed27c88037fac58268e758f2aedfacbc
[soc.git] / src / soc / debug / jtagutils.py
1 #The server code
2 import socket
3 from socket import close, AF_INET, SOCK_STREAM
4 import sys
5 import select
6 import time
7
8
9 def client_sync(dut):
10 tck = yield dut.cbus.tck
11 tms = yield dut.cbus.tms
12 tdi = yield dut.cbus.tdi
13 dut.c.jtagremote_client_send((tck, tms, tdi))
14 #print ("about to client recv")
15 while True:
16 tdo = dut.c.jtagremote_client_recv(timeout=0)
17 if tdo is not None:
18 break
19 yield
20 yield dut.cbus.tdo.eq(tdo)
21
22
23 def tms_state_set(dut, bits):
24 for bit in bits:
25 yield dut.cbus.tms.eq(bit)
26 yield from client_sync(dut)
27 yield dut.cbus.tck.eq(1)
28 yield from client_sync(dut)
29 yield
30 yield dut.cbus.tck.eq(0)
31 yield from client_sync(dut)
32 yield
33 yield from client_sync(dut)
34 yield dut.cbus.tms.eq(0)
35 yield from client_sync(dut)
36
37
38 def tms_data_getset(dut, tms, d_len, d_in=0):
39 res = 0
40 yield dut.cbus.tms.eq(tms)
41 for i in range(d_len):
42 tdi = 1 if (d_in & (1<<i)) else 0
43 yield dut.cbus.tck.eq(1)
44 yield from client_sync(dut)
45 res |= (1<<i) if (yield dut.cbus.tdo) else 0
46 yield
47 yield from client_sync(dut)
48 yield dut.cbus.tdi.eq(tdi)
49 yield dut.cbus.tck.eq(0)
50 yield from client_sync(dut)
51 yield
52 yield from client_sync(dut)
53 yield dut.cbus.tms.eq(0)
54 yield from client_sync(dut)
55
56 return res
57
58
59 def jtag_set_reset(dut):
60 yield from tms_state_set(dut, [1, 1, 1, 1, 1])
61
62 def jtag_set_shift_dr(dut):
63 yield from tms_state_set(dut, [1, 0, 0])
64
65 def jtag_set_shift_ir(dut):
66 yield from tms_state_set(dut, [1, 1, 0])
67
68 def jtag_set_run(dut):
69 yield from tms_state_set(dut, [0])
70
71 def jtag_set_idle(dut):
72 yield from tms_state_set(dut, [1, 1, 0])
73
74
75 def jtag_set_ir(dut, addr):
76 yield from jtag_set_run(dut)
77 yield from jtag_set_shift_ir(dut)
78 result = yield from tms_data_getset(dut, 0, dut._ir_width, addr)
79 yield from jtag_set_idle(dut)
80 return result
81
82
83 def jtag_set_get_dr(dut, d_len, d_in=0):
84 yield from jtag_set_shift_dr(dut)
85 result = yield from tms_data_getset(dut, 0, d_len, d_in)
86 yield from jtag_set_idle(dut)
87 return result
88
89 def jtag_read_write_reg(dut, addr, d_len, d_in=0):
90 yield from jtag_set_ir(dut, addr)
91 return (yield from jtag_set_get_dr(dut, d_len, d_in))
92
93
94 def jtag_srv(dut):
95 while not dut.stop:
96 # loop and receive data from client
97 tdo = yield dut.bus.tdo
98 #print ("server tdo data", tdo)
99 data = dut.s.jtagremote_server_recv(tdo)
100 #print ("server recv data", data)
101 if not data:
102 yield
103 continue
104 tck, tms, tdi = data
105 yield dut.bus.tck.eq(tck)
106 yield dut.bus.tms.eq(tms)
107 yield dut.bus.tdi.eq(tdi)
108 yield
109 print ("jtag srv stopping")
110
111
112 def get_data(s, length=1024, timeout=None):
113 r, w, e = select.select( [s], [], [], timeout)
114
115 for sock in r:
116 #incoming message from remote server
117 if sock == s:
118 return sock.recv(length)
119 return None
120
121 class JTAGServer:
122 def __init__(self, debug=False):
123 self.debug = debug
124 HOST = ''
125 PORT = 44853
126 s = socket.socket(AF_INET, SOCK_STREAM)
127 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
128 s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
129 s.bind((HOST, PORT))
130 s.listen(1) #only needs to receive one connection (the client)
131 self.s = s
132 self.conn = None
133
134 def close(self):
135 self.s.close()
136 if self.conn:
137 self.conn.close()
138
139 def get_connection(self, timeout=0):
140 r, w, e = select.select( [self.s], [], [], timeout)
141 for sock in r:
142 #incoming message from remote server
143 if sock == self.s:
144 conn, addr = self.s.accept() #accepts the connection
145 if self.debug:
146 print("Connected by: ", addr) #prints the connection
147 conn.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
148 self.conn = conn
149 return conn
150 return None
151
152 def get_data(self, length=1024, timeout=None):
153 return get_data(self.conn, length, timeout)
154
155 def send(self, data):
156 return self.conn.sendall(data)
157
158 def jtagremote_server_recv(self, tdo):
159 data = self.get_data(1, 0) # read 1 byte, non-blocking
160 if data is None or len(data) == 0:
161 return None # no data read
162 data = bytes.decode(data)
163 if self.debug:
164 print ("jtagremote_server_recv", data)
165 # request to read TDO
166 if data == 'R':
167 self.send(str.encode(chr(ord('0') + tdo)))
168 return [] # no data
169 # decode tck, tms, tdi
170 data = ord(data) - ord('0')
171 # encode tck, tms and tdi as number from 0-7
172 tdi = 1 if (data & 1) else 0
173 tms = 1 if (data & 2) else 0
174 tck = 1 if (data & 4) else 0
175
176 return (tck, tms, tdi)
177
178
179
180 class JTAGClient:
181 def __init__(self, debug=False):
182 self.debug = debug
183 HOST = 'localhost'
184 PORT = 44853
185 s = socket.socket(AF_INET, SOCK_STREAM)
186 s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
187 s.connect((HOST, PORT))
188 self.s = s
189
190 def close(self):
191 self.s.close()
192
193 def get_data(self, length=1024, timeout=None):
194 return get_data(self.s, length, timeout)
195
196 def send(self, data):
197 return self.s.sendall(data)
198
199 def jtagremote_client_send(self, to_send):
200 # encode tck, tms and tdi as number from 0-7
201 tck, tms, tdi = to_send
202 data = 0
203 if tdi: data |= 1
204 if tms: data |= 2
205 if tck: data |= 4
206 data = chr(ord('0') + data)
207 self.send(str.encode(data))
208 if self.debug:
209 print ("jtagremote_client_send", data)
210 # now read tdo
211 self.send(str.encode('R'))
212
213
214 def jtagremote_client_recv(self, timeout=None):
215 data = self.get_data(1, timeout) # read 1 byte, blocking
216 if data is None:
217 return None
218 if self.debug:
219 print ("client recv", data)
220 data = bytes.decode(data)
221 return ord(data) - ord('0') # subtract ASCII for "0" to give 0 or 1
222
223