fix dependency problems caused by pypi
[c4m-jtag.git] / c4m / cocotb / jtag / c4m_jtag_svfcocotb.py
1 from functools import singledispatch
2
3 import cocotb
4 from cocotb.binary import BinaryValue
5
6 from .c4m_jtag_svfgrammar import *
7
8
9 def decodescanspec(node):
10 length = int(str(node[2]))
11 fstr = "{:0"+str(node[2])+"b}"
12
13 g_tdi = node[4]
14 g_tdo = node[5]
15 g_mask = node[6]
16 g_smask = node[7]
17
18 if g_tdi is None:
19 tdi = None
20 else:
21 tdi = BinaryValue(fstr.format(int(str(g_tdi[2]),16)), length)
22
23 if g_tdo is None:
24 tdo = None
25 else:
26 tdo = BinaryValue(fstr.format(int(str(g_tdo[3]),16)), length)
27
28 if g_mask is None:
29 mask = None
30 else:
31 mask = BinaryValue(fstr.format(int(str(g_mask[3]),16)), length)
32
33 if g_smask is None:
34 smask = None
35 else:
36 smask = BinaryValue(fstr.format(int(str(g_smask[3]),16)), length)
37
38 return (length, tdi, tdo, mask, smask)
39
40
41 class SVF_Executor(object):
42 @cocotb.coroutine
43 def execute(self, node):
44 """This is the generic method"""
45 self._p("generic")
46 if False: # Make coroutine work
47 yield PythonTrigger()
48
49 @cocotb.coroutine
50 def _execute_NOP(self, node):
51 if False: # Make coroutine work
52 yield PythonTrigger()
53
54 @cocotb.coroutine
55 def _execute_EndDR(self, node):
56 self._p("EndDR ignored")
57 if False: # Make coroutine work
58 yield PythonTrigger()
59
60 @cocotb.coroutine
61 def _execute_EndIR(self, node):
62 self._p("EndIR ignored")
63 if False: # Make coroutine work
64 yield PythonTrigger()
65
66 @cocotb.coroutine
67 def _execute_Frequency(self, node):
68 self._p("Frequency ignored")
69 if False: # Make coroutine work
70 yield PythonTrigger()
71
72 @cocotb.coroutine
73 def _execute_HDR(self, node):
74 self._p("HDR ignored")
75 if False: # Make coroutine work
76 yield PythonTrigger()
77
78 @cocotb.coroutine
79 def _execute_HIR(self, node):
80 self._p("HIR ignored")
81 if False: # Make coroutine work
82 yield PythonTrigger()
83
84 @cocotb.coroutine
85 def _execute_SDR(self, node):
86 self._p("Executing SDR")
87 (length, tdi, tdo, mask, smask) = decodescanspec(node)
88
89 samelength = length == self._d_length
90 self._d_length = length
91
92 if tdi is None:
93 if not samelength:
94 raise(JTAGException("TDI needs to be specified when length of data changes"))
95 else:
96 self._d_tdi = tdi
97
98 if mask is not None:
99 self._d_mask = mask
100 elif not samelength:
101 self._d_mask = None
102
103 if smask is not None:
104 self._d_smask = smask
105 elif not samelength:
106 self._d_smask = None
107
108 yield self.master.shift_data(self._d_tdi)
109 if tdo is not None:
110 if self._d_mask is not None:
111 raise(JTAGException("MASK not supported for SDR"))
112 assert(self.master.result == tdo)
113
114 @cocotb.coroutine
115 def _execute_SIR(self, node):
116 (length, tdi, tdo, mask, smask) = decodescanspec(node)
117
118 samelength = length == self._i_length
119 self._i_length = length
120
121 if tdi is None:
122 if not samelength:
123 raise(JTAGException("TDI needs to be specified when length of data changes"))
124 else:
125 self._i_tdi = tdi
126
127 if mask is not None:
128 self._i_mask = mask
129 elif not samelength:
130 self._i_mask = None
131
132 if smask is not None:
133 self._i_smask = smask
134 elif not samelength:
135 self._i_smask = None
136
137 self._p("Executing SIR ({})".format(self._i_tdi.integer))
138
139 yield self.master.load_ir(self._i_tdi)
140 if tdo is not None:
141 if self._i_mask is not None:
142 raise(JTAGException("MASK not supported for SIR"))
143 assert(self.master.result == tdo)
144
145
146 @cocotb.coroutine
147 def _execute_State(self, node):
148 self._p("State")
149 if False: # Make coroutine work
150 yield PythonTrigger()
151
152 @cocotb.coroutine
153 def _execute_TDR(self, node):
154 self._p("TDR")
155 if False: # Make coroutine work
156 yield PythonTrigger()
157
158 @cocotb.coroutine
159 def _execute_TIR(self, node):
160 self._p("TIR")
161 if False: # Make coroutine work
162 yield PythonTrigger()
163
164 @cocotb.coroutine
165 def _execute_Trst(self, node):
166 self._p("TRST ignored")
167 if False: # Make coroutine work
168 yield PythonTrigger()
169
170 @cocotb.coroutine
171 def _execute_Runtest(self, node):
172 if node[1] is not None:
173 raise(JTAGException("State specification for RUNTEST not supported"))
174 # TODO: cycle the right number of clocks or wait the right time
175 yield(self.master.change_state([0]))
176
177 @cocotb.coroutine
178 def _execute_SVFFile(self, node):
179 self._p("Executing SVFFile")
180 for statement in node.elements[0]:
181 yield self.execute(statement)
182
183 def __init__(self, master):
184 # master is assumed to be a JTAG_Master class
185 # it needs to support methods load_ir() and shift_data()
186 self.master = master
187
188 # Due to bug in Grammar definition all possible classes have to have
189 # a dispatch entry otherwise an error will be raised.
190 self.execute = singledispatch(self.execute)
191 self.execute.register(EmptyLine, self._execute_NOP)
192 self.execute.register(Comment, self._execute_NOP)
193 self.execute.register(EndDR, self._execute_EndDR)
194 self.execute.register(EndIR, self._execute_EndIR)
195 self.execute.register(Frequency, self._execute_Frequency)
196 self.execute.register(HDR, self._execute_HDR)
197 self.execute.register(HIR, self._execute_HIR)
198 self.execute.register(Runtest, self._execute_Runtest)
199 self.execute.register(SDR, self._execute_SDR)
200 self.execute.register(SIR, self._execute_SIR)
201 self.execute.register(State, self._execute_State)
202 self.execute.register(TDR, self._execute_TDR)
203 self.execute.register(TIR, self._execute_TIR)
204 self.execute.register(Trst, self._execute_Trst)
205 self.execute.register(SVFFile, self._execute_SVFFile)
206
207 # Store the head and tail for the scan
208 self._d_tdi = self._d_tdi_h = self._d_tdi_t = None
209 self._d_tdo_h = self._d_tdo_t = None
210 self._i_tdi = self._i_tdi_h = self._i_tdi_t = None
211 self._i_tdo_h = self._i_tdo_t = None
212
213 # Remember the masks; smasks are ignored and bits always considered as care, e.g right
214 # value applied
215 self._d_length = self._d_length_h = self._d_length_t = None
216 self._d_mask = self._d_mask_h = self._d_mask_t = None
217 self._d_smask = self._d_smask_h = self._d_smask_t = None
218 self._i_length = self._i_length_h = self._i_length_t = None
219 self._i_mask = self._i_mask_h = self._i_mask_t = None
220 self._i_smask = self._i_smask_h = self._i_smask_t = None
221
222 @cocotb.coroutine
223 def run(self, cmds, p=print):
224 self._p = p
225 if isinstance(cmds, SVFFile):
226 yield self.execute(cmds)
227 else:
228 p = SVFFile.parser()
229 yield self.execute(p.parse_string(cmds))