1 from functools
import singledispatch
4 from cocotb
.binary
import BinaryValue
6 from .c4m_jtag_svfgrammar
import *
9 def decodescanspec(node
):
10 length
= int(str(node
[2]))
11 fstr
= "{:0"+str(node
[2])+"b}"
21 tdi
= BinaryValue(fstr
.format(int(str(g_tdi
[2]),16)), length
)
26 tdo
= BinaryValue(fstr
.format(int(str(g_tdo
[3]),16)), length
)
31 mask
= BinaryValue(fstr
.format(int(str(g_mask
[3]),16)), length
)
36 smask
= BinaryValue(fstr
.format(int(str(g_smask
[3]),16)), length
)
38 return (length
, tdi
, tdo
, mask
, smask
)
41 class SVF_Executor(object):
43 def execute(self
, node
):
44 """This is the generic method"""
46 if False: # Make coroutine work
50 def _execute_NOP(self
, node
):
51 if False: # Make coroutine work
55 def _execute_EndDR(self
, node
):
56 self
._p
("EndDR ignored")
57 if False: # Make coroutine work
61 def _execute_EndIR(self
, node
):
62 self
._p
("EndIR ignored")
63 if False: # Make coroutine work
67 def _execute_Frequency(self
, node
):
68 self
._p
("Frequency ignored")
69 if False: # Make coroutine work
73 def _execute_HDR(self
, node
):
74 self
._p
("HDR ignored")
75 if False: # Make coroutine work
79 def _execute_HIR(self
, node
):
80 self
._p
("HIR ignored")
81 if False: # Make coroutine work
85 def _execute_SDR(self
, node
):
86 self
._p
("Executing SDR")
87 (length
, tdi
, tdo
, mask
, smask
) = decodescanspec(node
)
89 samelength
= length
== self
._d
_length
90 self
._d
_length
= length
94 raise(JTAGException("TDI needs to be specified when length of data changes"))
103 if smask
is not None:
104 self
._d
_smask
= smask
108 yield self
.master
.shift_data(self
._d
_tdi
)
110 if self
._d
_mask
is not None:
111 raise(JTAGException("MASK not supported for SDR"))
112 assert(self
.master
.result
== tdo
)
115 def _execute_SIR(self
, node
):
116 (length
, tdi
, tdo
, mask
, smask
) = decodescanspec(node
)
118 samelength
= length
== self
._i
_length
119 self
._i
_length
= length
123 raise(JTAGException("TDI needs to be specified when length of data changes"))
132 if smask
is not None:
133 self
._i
_smask
= smask
137 self
._p
("Executing SIR ({})".format(self
._i
_tdi
.integer
))
139 yield self
.master
.load_ir(self
._i
_tdi
)
141 if self
._i
_mask
is not None:
142 raise(JTAGException("MASK not supported for SIR"))
143 assert(self
.master
.result
== tdo
)
147 def _execute_State(self
, node
):
149 if False: # Make coroutine work
150 yield PythonTrigger()
153 def _execute_TDR(self
, node
):
155 if False: # Make coroutine work
156 yield PythonTrigger()
159 def _execute_TIR(self
, node
):
161 if False: # Make coroutine work
162 yield PythonTrigger()
165 def _execute_Trst(self
, node
):
166 self
._p
("TRST ignored")
167 if False: # Make coroutine work
168 yield PythonTrigger()
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]))
178 def _execute_SVFFile(self
, node
):
179 self
._p
("Executing SVFFile")
180 for statement
in node
.elements
[0]:
181 yield self
.execute(statement
)
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()
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
)
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
213 # Remember the masks; smasks are ignored and bits always considered as care, e.g right
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
223 def run(self
, cmds
, p
=print):
225 if isinstance(cmds
, SVFFile
):
226 yield self
.execute(cmds
)
229 yield self
.execute(p
.parse_string(cmds
))