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