origen_jtag 0.19.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|