origen_jtag 0.19.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/config/application.rb +64 -64
- data/config/boot.rb +24 -24
- data/config/commands.rb +127 -127
- data/config/version.rb +8 -8
- data/lib/origen_jtag.rb +13 -13
- data/lib/origen_jtag/driver.rb +624 -624
- data/lib/origen_jtag/tap_controller.rb +347 -347
- data/lib/origen_jtag_dev/new_style.rb +113 -113
- data/lib/origen_jtag_dev/top_level.rb +94 -94
- data/pattern/full_reg_ovly_cap.rb +11 -11
- data/pattern/global_label_test.rb +12 -12
- data/pattern/jtag_workout.rb +221 -221
- data/pattern/rww_test.rb +25 -25
- data/pattern/two_port.rb +49 -49
- data/templates/web/index.md.erb +234 -234
- data/templates/web/layouts/_basic.html.erb +16 -16
- data/templates/web/partials/_navbar.html.erb +22 -22
- data/templates/web/release_notes.md.erb +5 -5
- metadata +3 -4
- data/config/development.rb +0 -15
@@ -1,347 +1,347 @@
|
|
1
|
-
module OrigenJTAG
|
2
|
-
# Provides methods specifically for controlling the state of the
|
3
|
-
# TAP Controller
|
4
|
-
module TAPController
|
5
|
-
# Map of internal state symbols to human readable names
|
6
|
-
STATES = {
|
7
|
-
reset: 'Test-Logic-Reset',
|
8
|
-
idle: 'Run-Test/Idle',
|
9
|
-
select_dr: 'Select-DR',
|
10
|
-
capture_dr: 'Capture-DR',
|
11
|
-
shift_dr: 'Shift-DR',
|
12
|
-
exit1_dr: 'Exit1-DR',
|
13
|
-
pause_dr: 'Pause-DR',
|
14
|
-
exit2_dr: 'Exit2-DR',
|
15
|
-
update_dr: 'Update-DR',
|
16
|
-
select_ir: 'Select-IR',
|
17
|
-
capture_ir: 'Capture-IR',
|
18
|
-
shift_ir: 'Shift-IR',
|
19
|
-
exit1_ir: 'Exit1-IR',
|
20
|
-
pause_ir: 'Pause-IR',
|
21
|
-
exit2_ir: 'Exit2-IR',
|
22
|
-
update_ir: 'Update-IR'
|
23
|
-
}
|
24
|
-
|
25
|
-
# Returns the current state of the JTAG TAP Controller
|
26
|
-
attr_reader :state
|
27
|
-
alias_method :current_state, :state
|
28
|
-
|
29
|
-
# Goto Shift-DR state then exit back to Run-Test/Idle
|
30
|
-
#
|
31
|
-
# @example Trandition into Shift-DR
|
32
|
-
# # State is Run-Test/Idle
|
33
|
-
# jtag.shift_dr do
|
34
|
-
# # State is Shift-DR
|
35
|
-
# end
|
36
|
-
# # State is Run-Test/Idle
|
37
|
-
#
|
38
|
-
# This method can be nested inside of a pause_dr block
|
39
|
-
# to transition into the Shift-DR state and then back
|
40
|
-
# to Pause-DR
|
41
|
-
#
|
42
|
-
# @example Switching between Pause-DR and Shift-DR
|
43
|
-
# # State is Run-Test/Idle
|
44
|
-
# jtag.pause_dr do
|
45
|
-
# # State is Pause-DR
|
46
|
-
# jtag.shift_dr do
|
47
|
-
# # State is Shift-DR
|
48
|
-
# end
|
49
|
-
# # State is Pause-DR
|
50
|
-
# end
|
51
|
-
# # State is Run-Test/Idle
|
52
|
-
def shift_dr(options = {})
|
53
|
-
validate_state(:idle, :pause_dr)
|
54
|
-
log 'Transition to Shift-DR...'
|
55
|
-
if state == :idle
|
56
|
-
tms!(1) # => Select-DR-Scan
|
57
|
-
update_state :select_dr_scan
|
58
|
-
tms!(0) # => Capture-DR
|
59
|
-
update_state :capture_dr
|
60
|
-
tms!(0) # => Shift-DR
|
61
|
-
update_state :shift_dr
|
62
|
-
if options[:write]
|
63
|
-
msg = "Write DR: #{options[:write]}"
|
64
|
-
elsif options[:read]
|
65
|
-
msg = "Read DR: #{options[:read]}"
|
66
|
-
else
|
67
|
-
msg = 'DR Data'
|
68
|
-
end
|
69
|
-
log msg, always: true do
|
70
|
-
yield
|
71
|
-
log 'Transition to Run-Test/Idle...'
|
72
|
-
if @last_data_vector_shifted
|
73
|
-
@last_data_vector_shifted = false
|
74
|
-
else
|
75
|
-
tms!(1) # => Exit1-DR
|
76
|
-
update_state :exit1_dr
|
77
|
-
end
|
78
|
-
end
|
79
|
-
tms!(1) # => Update-DR
|
80
|
-
update_state :update_dr
|
81
|
-
tms!(0) # => Run-Test/Idle
|
82
|
-
update_state :idle
|
83
|
-
else # :pause_dr
|
84
|
-
tms!(1) # => Exit2-DR
|
85
|
-
update_state :exit2_dr
|
86
|
-
tms!(0) # => Shift-DR
|
87
|
-
update_state :shift_dr
|
88
|
-
yield
|
89
|
-
log 'Transition to Pause-DR...'
|
90
|
-
tms!(1) # => Exit1-DR
|
91
|
-
update_state :exit1_dr
|
92
|
-
tms!(0) # => Pause-DR
|
93
|
-
update_state :pause_dr
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# Goto Pause-DR state then exit back to Run-Test/Idle
|
98
|
-
#
|
99
|
-
# @example Trandition into Pause-DR
|
100
|
-
# # State is Run-Test/Idle
|
101
|
-
# jtag.pause_dr do
|
102
|
-
# # State is Pause-DR
|
103
|
-
# end
|
104
|
-
# # State is Run-Test/Idle
|
105
|
-
#
|
106
|
-
# This method can be nested inside of a shift_dr block
|
107
|
-
# to transition into the Pause-DR state and then back
|
108
|
-
# to Shift-DR
|
109
|
-
#
|
110
|
-
# @example Switching between Shift-DR and Pause-DR
|
111
|
-
# # State is Run-Test/Idle
|
112
|
-
# jtag.shift_dr do
|
113
|
-
# # State is Shift-DR
|
114
|
-
# jtag.pause_dr do
|
115
|
-
# # State is Pause-DR
|
116
|
-
# end
|
117
|
-
# # State is Shift-DR
|
118
|
-
# end
|
119
|
-
# # State is Run-Test/Idle
|
120
|
-
def pause_dr
|
121
|
-
validate_state(:idle, :shift_dr)
|
122
|
-
log 'Transition to Pause-DR...'
|
123
|
-
if state == :idle
|
124
|
-
tms!(1) # => Select-DR-Scan
|
125
|
-
update_state :select_dr_scan
|
126
|
-
tms!(0) # => Capture-DR
|
127
|
-
update_state :capture_dr
|
128
|
-
tms!(1) # => Exit1-DR
|
129
|
-
update_state :exit1_dr
|
130
|
-
tms!(0) # => Pause-DR
|
131
|
-
update_state :pause_dr
|
132
|
-
yield
|
133
|
-
log 'Transition to Run-Test/Idle...'
|
134
|
-
tms!(1) # => Exit2-DR
|
135
|
-
update_state :exit2_dr
|
136
|
-
tms!(1) # => Update-DR
|
137
|
-
update_state :update_dr
|
138
|
-
tms!(0) # => Run-Test/Idle
|
139
|
-
update_state :idle
|
140
|
-
else # shift_dr
|
141
|
-
tms!(1) # => Exit1-DR
|
142
|
-
update_state :exit1_dr
|
143
|
-
tms!(0) # => Pause-DR
|
144
|
-
update_state :pause_dr
|
145
|
-
yield
|
146
|
-
log 'Transition to Shift-DR...'
|
147
|
-
tms!(1) # => Exit2-DR
|
148
|
-
update_state :exit2_dr
|
149
|
-
tms!(0) # => Shift-DR
|
150
|
-
update_state :shift_dr
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# Goto Shift-IR state then exit back to Run-Test/Idle
|
155
|
-
#
|
156
|
-
# @example Trandition into Shift-IR
|
157
|
-
# # State is Run-Test/Idle
|
158
|
-
# jtag.shift_ir do
|
159
|
-
# # State is Shift-IR
|
160
|
-
# end
|
161
|
-
# # State is Run-Test/Idle
|
162
|
-
#
|
163
|
-
# This method can be nested inside of a pause_ir block
|
164
|
-
# to transition into the Shift-IR state and then back
|
165
|
-
# to Pause-IR
|
166
|
-
#
|
167
|
-
# @example Switching between Pause-IR and Shift-IR
|
168
|
-
# # State is Run-Test/Idle
|
169
|
-
# jtag.pause_ir do
|
170
|
-
# # State is Pause-IR
|
171
|
-
# jtag.shift_ir do
|
172
|
-
# # State is Shift-IR
|
173
|
-
# end
|
174
|
-
# # State is Pause-IR
|
175
|
-
# end
|
176
|
-
# # State is Run-Test/Idle
|
177
|
-
def shift_ir(options = {})
|
178
|
-
validate_state(:idle, :pause_ir)
|
179
|
-
log 'Transition to Shift-IR...'
|
180
|
-
if state == :idle
|
181
|
-
tms!(1) # => Select-DR-Scan
|
182
|
-
update_state :select_dr_scan
|
183
|
-
tms!(1) # => Select-IR-Scan
|
184
|
-
update_state :select_ir_scan
|
185
|
-
tms!(0) # => Capture-IR
|
186
|
-
update_state :capture_ir
|
187
|
-
tms!(0) # => Shift-IR
|
188
|
-
update_state :shift_ir
|
189
|
-
if options[:write]
|
190
|
-
msg = "Write IR: #{options[:write]}"
|
191
|
-
elsif options[:read]
|
192
|
-
msg = "Read IR: #{options[:read]}"
|
193
|
-
else
|
194
|
-
msg = 'IR Data'
|
195
|
-
end
|
196
|
-
log msg, always: true do
|
197
|
-
yield
|
198
|
-
log 'Transition to Run-Test/Idle...'
|
199
|
-
if @last_data_vector_shifted
|
200
|
-
@last_data_vector_shifted = false
|
201
|
-
else
|
202
|
-
tms!(1) # => Exit1-IR
|
203
|
-
update_state :exit1_ir
|
204
|
-
end
|
205
|
-
end
|
206
|
-
tms!(1) # => Update-IR
|
207
|
-
update_state :update_ir
|
208
|
-
tms!(0) # => Run-Test/Idle
|
209
|
-
update_state :idle
|
210
|
-
else # :pause_ir
|
211
|
-
tms!(1) # => Exit2-IR
|
212
|
-
update_state :exit2_ir
|
213
|
-
tms!(0) # => Shift-IR
|
214
|
-
update_state :shift_ir
|
215
|
-
yield
|
216
|
-
log 'Transition to Pause-IR...'
|
217
|
-
tms!(1) # => Exit1-IR
|
218
|
-
update_state :exit1_ir
|
219
|
-
tms!(0) # => Pause-IR
|
220
|
-
update_state :pause_ir
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
# Goto Pause-IR state then exit back to Run-Test/Idle
|
225
|
-
#
|
226
|
-
# @example Trandition into Pause-iR
|
227
|
-
# # State is Run-Test/Idle
|
228
|
-
# jtag.pause_ir do
|
229
|
-
# # State is Pause-IR
|
230
|
-
# end
|
231
|
-
# # State is Run-Test/Idle
|
232
|
-
#
|
233
|
-
# This method can be nested inside of a shift_ir block
|
234
|
-
# to transition into the Pause-IR state and then back
|
235
|
-
# to Shift-IR
|
236
|
-
#
|
237
|
-
# @example Switching between Shift-IR and Pause-IR
|
238
|
-
# # State is Run-Test/Idle
|
239
|
-
# jtag.shift_ir do
|
240
|
-
# # State is Shift-IR
|
241
|
-
# jtag.pause_ir do
|
242
|
-
# # State is Pause-IR
|
243
|
-
# end
|
244
|
-
# # State is Shift-IR
|
245
|
-
# end
|
246
|
-
# # State is Run-Test/Idle
|
247
|
-
def pause_ir
|
248
|
-
validate_state(:idle, :shift_ir)
|
249
|
-
log 'Transition to Pause-IR...'
|
250
|
-
if state == :idle
|
251
|
-
tms!(1) # => Select-DR-Scan
|
252
|
-
update_state :select_dr_scan
|
253
|
-
tms!(1) # => Select-IR-Scan
|
254
|
-
update_state :select_ir_scan
|
255
|
-
tms!(0) # => Capture-IR
|
256
|
-
update_state :capture_ir
|
257
|
-
tms!(1) # => Exit1-IR
|
258
|
-
update_state :exit1_ir
|
259
|
-
tms!(0) # => Pause-IR
|
260
|
-
update_state :pause_ir
|
261
|
-
yield
|
262
|
-
log 'Transition to Run-Test/Idle...'
|
263
|
-
tms!(1) # => Exit2-IR
|
264
|
-
update_state :exit2_ir
|
265
|
-
tms!(1) # => Update-IR
|
266
|
-
update_state :update_ir
|
267
|
-
tms!(0) # => Run-Test/Idle
|
268
|
-
update_state :idle
|
269
|
-
else # :shift_ir
|
270
|
-
tms!(1) # => Exit1-IR
|
271
|
-
update_state :exit1_ir
|
272
|
-
tms!(0) # => Pause-IR
|
273
|
-
update_state :pause_ir
|
274
|
-
yield
|
275
|
-
log 'Transition to Shift-IR...'
|
276
|
-
tms!(1) # => Exit2-IR
|
277
|
-
update_state :exit2_ir
|
278
|
-
tms!(0) # => Shift-IR
|
279
|
-
update_state :shift_ir
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
# Returns the current state as a human readable string
|
284
|
-
def state_str
|
285
|
-
STATES[state]
|
286
|
-
end
|
287
|
-
alias_method :current_state_str, :state_str
|
288
|
-
|
289
|
-
# Forces the state to Run-Test/Idle regardless of the current
|
290
|
-
# state.
|
291
|
-
def idle
|
292
|
-
log 'Force transition to Run-Test/Idle...'
|
293
|
-
# From the JTAG2IPS block guide holding TMS high for 5 cycles
|
294
|
-
# will force it to reset regardless of the state, let's give
|
295
|
-
# it 6 for luck:
|
296
|
-
6.times { tms!(1) }
|
297
|
-
# Now a couple of cycles low to get it into idle
|
298
|
-
2.times { tms!(0) }
|
299
|
-
update_state :idle
|
300
|
-
end
|
301
|
-
|
302
|
-
# Force state to Test-Logic-Reset regardless of the current
|
303
|
-
# state
|
304
|
-
def reset
|
305
|
-
log 'Force transition to Test-Logic-Reset...'
|
306
|
-
# JTAG reset
|
307
|
-
6.times { tms!(1) }
|
308
|
-
end
|
309
|
-
|
310
|
-
def update_state(state)
|
311
|
-
@state = state
|
312
|
-
log "Current state: #{state_str}" if log_state_changes
|
313
|
-
@listeners ||= Origen.listeners_for(:on_jtag_state_change)
|
314
|
-
@listeners.each { |l| l.on_jtag_state_change(@state) }
|
315
|
-
end
|
316
|
-
|
317
|
-
private
|
318
|
-
|
319
|
-
def init_tap_controller(options = {})
|
320
|
-
options = {
|
321
|
-
}.merge(options)
|
322
|
-
end
|
323
|
-
|
324
|
-
# Ensures that the current state matches one of the given acceptable
|
325
|
-
# states.
|
326
|
-
#
|
327
|
-
# Additionally if the current state is unknown and idle is acceptable
|
328
|
-
# then the state will be transitioned to idle.
|
329
|
-
def validate_state(*acceptable_states)
|
330
|
-
if current_state == :unknown && acceptable_states.include?(:idle)
|
331
|
-
idle
|
332
|
-
elsif acceptable_states.include?(current_state)
|
333
|
-
return
|
334
|
-
else
|
335
|
-
fail 'JTAG TAP Controller - An invalid state sequence has occurred!'
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
def log(msg, options = {})
|
340
|
-
cc "[JTAG] #{msg}" if verbose? || options[:always]
|
341
|
-
if block_given?
|
342
|
-
yield
|
343
|
-
cc "[JTAG] /#{msg}" if verbose? || options[:always]
|
344
|
-
end
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
1
|
+
module OrigenJTAG
|
2
|
+
# Provides methods specifically for controlling the state of the
|
3
|
+
# TAP Controller
|
4
|
+
module TAPController
|
5
|
+
# Map of internal state symbols to human readable names
|
6
|
+
STATES = {
|
7
|
+
reset: 'Test-Logic-Reset',
|
8
|
+
idle: 'Run-Test/Idle',
|
9
|
+
select_dr: 'Select-DR',
|
10
|
+
capture_dr: 'Capture-DR',
|
11
|
+
shift_dr: 'Shift-DR',
|
12
|
+
exit1_dr: 'Exit1-DR',
|
13
|
+
pause_dr: 'Pause-DR',
|
14
|
+
exit2_dr: 'Exit2-DR',
|
15
|
+
update_dr: 'Update-DR',
|
16
|
+
select_ir: 'Select-IR',
|
17
|
+
capture_ir: 'Capture-IR',
|
18
|
+
shift_ir: 'Shift-IR',
|
19
|
+
exit1_ir: 'Exit1-IR',
|
20
|
+
pause_ir: 'Pause-IR',
|
21
|
+
exit2_ir: 'Exit2-IR',
|
22
|
+
update_ir: 'Update-IR'
|
23
|
+
}
|
24
|
+
|
25
|
+
# Returns the current state of the JTAG TAP Controller
|
26
|
+
attr_reader :state
|
27
|
+
alias_method :current_state, :state
|
28
|
+
|
29
|
+
# Goto Shift-DR state then exit back to Run-Test/Idle
|
30
|
+
#
|
31
|
+
# @example Trandition into Shift-DR
|
32
|
+
# # State is Run-Test/Idle
|
33
|
+
# jtag.shift_dr do
|
34
|
+
# # State is Shift-DR
|
35
|
+
# end
|
36
|
+
# # State is Run-Test/Idle
|
37
|
+
#
|
38
|
+
# This method can be nested inside of a pause_dr block
|
39
|
+
# to transition into the Shift-DR state and then back
|
40
|
+
# to Pause-DR
|
41
|
+
#
|
42
|
+
# @example Switching between Pause-DR and Shift-DR
|
43
|
+
# # State is Run-Test/Idle
|
44
|
+
# jtag.pause_dr do
|
45
|
+
# # State is Pause-DR
|
46
|
+
# jtag.shift_dr do
|
47
|
+
# # State is Shift-DR
|
48
|
+
# end
|
49
|
+
# # State is Pause-DR
|
50
|
+
# end
|
51
|
+
# # State is Run-Test/Idle
|
52
|
+
def shift_dr(options = {})
|
53
|
+
validate_state(:idle, :pause_dr)
|
54
|
+
log 'Transition to Shift-DR...'
|
55
|
+
if state == :idle
|
56
|
+
tms!(1) # => Select-DR-Scan
|
57
|
+
update_state :select_dr_scan
|
58
|
+
tms!(0) # => Capture-DR
|
59
|
+
update_state :capture_dr
|
60
|
+
tms!(0) # => Shift-DR
|
61
|
+
update_state :shift_dr
|
62
|
+
if options[:write]
|
63
|
+
msg = "Write DR: #{options[:write]}"
|
64
|
+
elsif options[:read]
|
65
|
+
msg = "Read DR: #{options[:read]}"
|
66
|
+
else
|
67
|
+
msg = 'DR Data'
|
68
|
+
end
|
69
|
+
log msg, always: true do
|
70
|
+
yield
|
71
|
+
log 'Transition to Run-Test/Idle...'
|
72
|
+
if @last_data_vector_shifted
|
73
|
+
@last_data_vector_shifted = false
|
74
|
+
else
|
75
|
+
tms!(1) # => Exit1-DR
|
76
|
+
update_state :exit1_dr
|
77
|
+
end
|
78
|
+
end
|
79
|
+
tms!(1) # => Update-DR
|
80
|
+
update_state :update_dr
|
81
|
+
tms!(0) # => Run-Test/Idle
|
82
|
+
update_state :idle
|
83
|
+
else # :pause_dr
|
84
|
+
tms!(1) # => Exit2-DR
|
85
|
+
update_state :exit2_dr
|
86
|
+
tms!(0) # => Shift-DR
|
87
|
+
update_state :shift_dr
|
88
|
+
yield
|
89
|
+
log 'Transition to Pause-DR...'
|
90
|
+
tms!(1) # => Exit1-DR
|
91
|
+
update_state :exit1_dr
|
92
|
+
tms!(0) # => Pause-DR
|
93
|
+
update_state :pause_dr
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Goto Pause-DR state then exit back to Run-Test/Idle
|
98
|
+
#
|
99
|
+
# @example Trandition into Pause-DR
|
100
|
+
# # State is Run-Test/Idle
|
101
|
+
# jtag.pause_dr do
|
102
|
+
# # State is Pause-DR
|
103
|
+
# end
|
104
|
+
# # State is Run-Test/Idle
|
105
|
+
#
|
106
|
+
# This method can be nested inside of a shift_dr block
|
107
|
+
# to transition into the Pause-DR state and then back
|
108
|
+
# to Shift-DR
|
109
|
+
#
|
110
|
+
# @example Switching between Shift-DR and Pause-DR
|
111
|
+
# # State is Run-Test/Idle
|
112
|
+
# jtag.shift_dr do
|
113
|
+
# # State is Shift-DR
|
114
|
+
# jtag.pause_dr do
|
115
|
+
# # State is Pause-DR
|
116
|
+
# end
|
117
|
+
# # State is Shift-DR
|
118
|
+
# end
|
119
|
+
# # State is Run-Test/Idle
|
120
|
+
def pause_dr
|
121
|
+
validate_state(:idle, :shift_dr)
|
122
|
+
log 'Transition to Pause-DR...'
|
123
|
+
if state == :idle
|
124
|
+
tms!(1) # => Select-DR-Scan
|
125
|
+
update_state :select_dr_scan
|
126
|
+
tms!(0) # => Capture-DR
|
127
|
+
update_state :capture_dr
|
128
|
+
tms!(1) # => Exit1-DR
|
129
|
+
update_state :exit1_dr
|
130
|
+
tms!(0) # => Pause-DR
|
131
|
+
update_state :pause_dr
|
132
|
+
yield
|
133
|
+
log 'Transition to Run-Test/Idle...'
|
134
|
+
tms!(1) # => Exit2-DR
|
135
|
+
update_state :exit2_dr
|
136
|
+
tms!(1) # => Update-DR
|
137
|
+
update_state :update_dr
|
138
|
+
tms!(0) # => Run-Test/Idle
|
139
|
+
update_state :idle
|
140
|
+
else # shift_dr
|
141
|
+
tms!(1) # => Exit1-DR
|
142
|
+
update_state :exit1_dr
|
143
|
+
tms!(0) # => Pause-DR
|
144
|
+
update_state :pause_dr
|
145
|
+
yield
|
146
|
+
log 'Transition to Shift-DR...'
|
147
|
+
tms!(1) # => Exit2-DR
|
148
|
+
update_state :exit2_dr
|
149
|
+
tms!(0) # => Shift-DR
|
150
|
+
update_state :shift_dr
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Goto Shift-IR state then exit back to Run-Test/Idle
|
155
|
+
#
|
156
|
+
# @example Trandition into Shift-IR
|
157
|
+
# # State is Run-Test/Idle
|
158
|
+
# jtag.shift_ir do
|
159
|
+
# # State is Shift-IR
|
160
|
+
# end
|
161
|
+
# # State is Run-Test/Idle
|
162
|
+
#
|
163
|
+
# This method can be nested inside of a pause_ir block
|
164
|
+
# to transition into the Shift-IR state and then back
|
165
|
+
# to Pause-IR
|
166
|
+
#
|
167
|
+
# @example Switching between Pause-IR and Shift-IR
|
168
|
+
# # State is Run-Test/Idle
|
169
|
+
# jtag.pause_ir do
|
170
|
+
# # State is Pause-IR
|
171
|
+
# jtag.shift_ir do
|
172
|
+
# # State is Shift-IR
|
173
|
+
# end
|
174
|
+
# # State is Pause-IR
|
175
|
+
# end
|
176
|
+
# # State is Run-Test/Idle
|
177
|
+
def shift_ir(options = {})
|
178
|
+
validate_state(:idle, :pause_ir)
|
179
|
+
log 'Transition to Shift-IR...'
|
180
|
+
if state == :idle
|
181
|
+
tms!(1) # => Select-DR-Scan
|
182
|
+
update_state :select_dr_scan
|
183
|
+
tms!(1) # => Select-IR-Scan
|
184
|
+
update_state :select_ir_scan
|
185
|
+
tms!(0) # => Capture-IR
|
186
|
+
update_state :capture_ir
|
187
|
+
tms!(0) # => Shift-IR
|
188
|
+
update_state :shift_ir
|
189
|
+
if options[:write]
|
190
|
+
msg = "Write IR: #{options[:write]}"
|
191
|
+
elsif options[:read]
|
192
|
+
msg = "Read IR: #{options[:read]}"
|
193
|
+
else
|
194
|
+
msg = 'IR Data'
|
195
|
+
end
|
196
|
+
log msg, always: true do
|
197
|
+
yield
|
198
|
+
log 'Transition to Run-Test/Idle...'
|
199
|
+
if @last_data_vector_shifted
|
200
|
+
@last_data_vector_shifted = false
|
201
|
+
else
|
202
|
+
tms!(1) # => Exit1-IR
|
203
|
+
update_state :exit1_ir
|
204
|
+
end
|
205
|
+
end
|
206
|
+
tms!(1) # => Update-IR
|
207
|
+
update_state :update_ir
|
208
|
+
tms!(0) # => Run-Test/Idle
|
209
|
+
update_state :idle
|
210
|
+
else # :pause_ir
|
211
|
+
tms!(1) # => Exit2-IR
|
212
|
+
update_state :exit2_ir
|
213
|
+
tms!(0) # => Shift-IR
|
214
|
+
update_state :shift_ir
|
215
|
+
yield
|
216
|
+
log 'Transition to Pause-IR...'
|
217
|
+
tms!(1) # => Exit1-IR
|
218
|
+
update_state :exit1_ir
|
219
|
+
tms!(0) # => Pause-IR
|
220
|
+
update_state :pause_ir
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Goto Pause-IR state then exit back to Run-Test/Idle
|
225
|
+
#
|
226
|
+
# @example Trandition into Pause-iR
|
227
|
+
# # State is Run-Test/Idle
|
228
|
+
# jtag.pause_ir do
|
229
|
+
# # State is Pause-IR
|
230
|
+
# end
|
231
|
+
# # State is Run-Test/Idle
|
232
|
+
#
|
233
|
+
# This method can be nested inside of a shift_ir block
|
234
|
+
# to transition into the Pause-IR state and then back
|
235
|
+
# to Shift-IR
|
236
|
+
#
|
237
|
+
# @example Switching between Shift-IR and Pause-IR
|
238
|
+
# # State is Run-Test/Idle
|
239
|
+
# jtag.shift_ir do
|
240
|
+
# # State is Shift-IR
|
241
|
+
# jtag.pause_ir do
|
242
|
+
# # State is Pause-IR
|
243
|
+
# end
|
244
|
+
# # State is Shift-IR
|
245
|
+
# end
|
246
|
+
# # State is Run-Test/Idle
|
247
|
+
def pause_ir
|
248
|
+
validate_state(:idle, :shift_ir)
|
249
|
+
log 'Transition to Pause-IR...'
|
250
|
+
if state == :idle
|
251
|
+
tms!(1) # => Select-DR-Scan
|
252
|
+
update_state :select_dr_scan
|
253
|
+
tms!(1) # => Select-IR-Scan
|
254
|
+
update_state :select_ir_scan
|
255
|
+
tms!(0) # => Capture-IR
|
256
|
+
update_state :capture_ir
|
257
|
+
tms!(1) # => Exit1-IR
|
258
|
+
update_state :exit1_ir
|
259
|
+
tms!(0) # => Pause-IR
|
260
|
+
update_state :pause_ir
|
261
|
+
yield
|
262
|
+
log 'Transition to Run-Test/Idle...'
|
263
|
+
tms!(1) # => Exit2-IR
|
264
|
+
update_state :exit2_ir
|
265
|
+
tms!(1) # => Update-IR
|
266
|
+
update_state :update_ir
|
267
|
+
tms!(0) # => Run-Test/Idle
|
268
|
+
update_state :idle
|
269
|
+
else # :shift_ir
|
270
|
+
tms!(1) # => Exit1-IR
|
271
|
+
update_state :exit1_ir
|
272
|
+
tms!(0) # => Pause-IR
|
273
|
+
update_state :pause_ir
|
274
|
+
yield
|
275
|
+
log 'Transition to Shift-IR...'
|
276
|
+
tms!(1) # => Exit2-IR
|
277
|
+
update_state :exit2_ir
|
278
|
+
tms!(0) # => Shift-IR
|
279
|
+
update_state :shift_ir
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
# Returns the current state as a human readable string
|
284
|
+
def state_str
|
285
|
+
STATES[state]
|
286
|
+
end
|
287
|
+
alias_method :current_state_str, :state_str
|
288
|
+
|
289
|
+
# Forces the state to Run-Test/Idle regardless of the current
|
290
|
+
# state.
|
291
|
+
def idle
|
292
|
+
log 'Force transition to Run-Test/Idle...'
|
293
|
+
# From the JTAG2IPS block guide holding TMS high for 5 cycles
|
294
|
+
# will force it to reset regardless of the state, let's give
|
295
|
+
# it 6 for luck:
|
296
|
+
6.times { tms!(1) }
|
297
|
+
# Now a couple of cycles low to get it into idle
|
298
|
+
2.times { tms!(0) }
|
299
|
+
update_state :idle
|
300
|
+
end
|
301
|
+
|
302
|
+
# Force state to Test-Logic-Reset regardless of the current
|
303
|
+
# state
|
304
|
+
def reset
|
305
|
+
log 'Force transition to Test-Logic-Reset...'
|
306
|
+
# JTAG reset
|
307
|
+
6.times { tms!(1) }
|
308
|
+
end
|
309
|
+
|
310
|
+
def update_state(state)
|
311
|
+
@state = state
|
312
|
+
log "Current state: #{state_str}" if log_state_changes
|
313
|
+
@listeners ||= Origen.listeners_for(:on_jtag_state_change)
|
314
|
+
@listeners.each { |l| l.on_jtag_state_change(@state) }
|
315
|
+
end
|
316
|
+
|
317
|
+
private
|
318
|
+
|
319
|
+
def init_tap_controller(options = {})
|
320
|
+
options = {
|
321
|
+
}.merge(options)
|
322
|
+
end
|
323
|
+
|
324
|
+
# Ensures that the current state matches one of the given acceptable
|
325
|
+
# states.
|
326
|
+
#
|
327
|
+
# Additionally if the current state is unknown and idle is acceptable
|
328
|
+
# then the state will be transitioned to idle.
|
329
|
+
def validate_state(*acceptable_states)
|
330
|
+
if current_state == :unknown && acceptable_states.include?(:idle)
|
331
|
+
idle
|
332
|
+
elsif acceptable_states.include?(current_state)
|
333
|
+
return
|
334
|
+
else
|
335
|
+
fail 'JTAG TAP Controller - An invalid state sequence has occurred!'
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def log(msg, options = {})
|
340
|
+
cc "[JTAG] #{msg}" if verbose? || options[:always]
|
341
|
+
if block_given?
|
342
|
+
yield
|
343
|
+
cc "[JTAG] /#{msg}" if verbose? || options[:always]
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|