Module: OrigenJTAG::TAPController

Included in:
Driver
Defined in:
lib/origen_jtag/tap_controller.rb

Overview

Provides methods specifically for controlling the state of the TAP Controller

Constant Summary collapse

STATES =

Map of internal state symbols to human readable names

{
  reset:          'Test-Logic-Reset',
  idle:           'Run-Test/Idle',
  select_dr_scan: 'Select-DR-Scan',
  capture_dr:     'Capture-DR',
  shift_dr:       'Shift-DR',
  exit1_dr:       'Exit1-DR',
  pause_dr:       'Pause-DR',
  exit2_dr:       'Exit2-DR',
  update_dr:      'Update-DR',
  select_ir_scan: 'Select-IR-Scan',
  capture_ir:     'Capture-IR',
  shift_ir:       'Shift-IR',
  exit1_ir:       'Exit1-IR',
  pause_ir:       'Pause-IR',
  exit2_ir:       'Exit2-IR',
  update_ir:      'Update-IR'
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#stateObject (readonly) Also known as: current_state

Returns the current state of the JTAG TAP Controller



26
27
28
# File 'lib/origen_jtag/tap_controller.rb', line 26

def state
  @state
end

Instance Method Details

#idleObject

Forces the state to Run-Test/Idle regardless of the current state.



330
331
332
333
334
335
336
337
338
339
# File 'lib/origen_jtag/tap_controller.rb', line 330

def idle
  log 'Force transition to Run-Test/Idle...'
  # From the JTAG2IPS block guide holding TMS high for 5 cycles
  # will force it to reset regardless of the state, let's give
  # it 6 for luck:
  6.times { tms!(1) }
  # Now a couple of cycles low to get it into idle
  2.times { tms!(0) }
  update_state :idle
end

#pause_drObject

Goto Pause-DR state then exit back to Run-Test/Idle

This method can be nested inside of a shift_dr block to transition into the Pause-DR state and then back to Shift-DR

Examples:

Trandition into Pause-DR

# State is Run-Test/Idle
jtag.pause_dr do
  # State is Pause-DR
end
# State is Run-Test/Idle

Switching between Shift-DR and Pause-DR

# State is Run-Test/Idle
jtag.shift_dr do
  # State is Shift-DR
  jtag.pause_dr do
    # State is Pause-DR
  end
  # State is Shift-DR
end
# State is Run-Test/Idle


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/origen_jtag/tap_controller.rb', line 138

def pause_dr
  validate_state(:idle, :shift_dr)
  log 'Transition to Pause-DR...'
  if state == :idle
    tms!(1)  # => Select-DR-Scan
    update_state :select_dr_scan
    tms!(0)  # => Capture-DR
    update_state :capture_dr
    tms!(1)  # => Exit1-DR
    update_state :exit1_dr
    tms!(0)  # => Pause-DR
    update_state :pause_dr
    yield
    log 'Transition to Run-Test/Idle...'
    tms!(1)  # => Exit2-DR
    update_state :exit2_dr
    tms!(1)  # => Update-DR
    update_state :update_dr
    tms!(0)  # => Run-Test/Idle
    update_state :idle
  else  # shift_dr
    tms!(1)  # => Exit1-DR
    update_state :exit1_dr
    tms!(0)  # => Pause-DR
    update_state :pause_dr
    yield
    log 'Transition to Shift-DR...'
    tms!(1)  # => Exit2-DR
    update_state :exit2_dr
    tms!(0)  # => Shift-DR
    update_state :shift_dr
  end
end

#pause_irObject

Goto Pause-IR state then exit back to Run-Test/Idle

This method can be nested inside of a shift_ir block to transition into the Pause-IR state and then back to Shift-IR

Examples:

Trandition into Pause-iR

# State is Run-Test/Idle
jtag.pause_ir do
  # State is Pause-IR
end
# State is Run-Test/Idle

Switching between Shift-IR and Pause-IR

# State is Run-Test/Idle
jtag.shift_ir do
  # State is Shift-IR
  jtag.pause_ir do
    # State is Pause-IR
  end
  # State is Shift-IR
end
# State is Run-Test/Idle


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/origen_jtag/tap_controller.rb', line 286

def pause_ir
  validate_state(:idle, :shift_ir)
  log 'Transition to Pause-IR...'
  if state == :idle
    tms!(1)  # => Select-DR-Scan
    update_state :select_dr_scan
    tms!(1)  # => Select-IR-Scan
    update_state :select_ir_scan
    tms!(0)  # => Capture-IR
    update_state :capture_ir
    tms!(1)  # => Exit1-IR
    update_state :exit1_ir
    tms!(0)  # => Pause-IR
    update_state :pause_ir
    yield
    log 'Transition to Run-Test/Idle...'
    tms!(1)  # => Exit2-IR
    update_state :exit2_ir
    tms!(1)  # => Update-IR
    update_state :update_ir
    tms!(0)  # => Run-Test/Idle
    update_state :idle
  else # :shift_ir
    tms!(1)  # => Exit1-IR
    update_state :exit1_ir
    tms!(0)  # => Pause-IR
    update_state :pause_ir
    yield
    log 'Transition to Shift-IR...'
    tms!(1)  # => Exit2-IR
    update_state :exit2_ir
    tms!(0)  # => Shift-IR
    update_state :shift_ir
  end
end

#resetObject

Force state to Test-Logic-Reset regardless of the current state



343
344
345
346
347
# File 'lib/origen_jtag/tap_controller.rb', line 343

def reset
  log 'Force transition to Test-Logic-Reset...'
  # JTAG reset
  6.times { tms!(1) }
end

#shift_dr(options = {}) ⇒ Object

Goto Shift-DR state then exit back to Run-Test/Idle

This method can be nested inside of a pause_dr block to transition into the Shift-DR state and then back to Pause-DR

Examples:

Trandition into Shift-DR

# State is Run-Test/Idle
jtag.shift_dr do
  # State is Shift-DR
end
# State is Run-Test/Idle

Switching between Pause-DR and Shift-DR

# State is Run-Test/Idle
jtag.pause_dr do
  # State is Pause-DR
  jtag.shift_dr do
    # State is Shift-DR
  end
  # State is Pause-DR
end
# State is Run-Test/Idle


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/origen_jtag/tap_controller.rb', line 52

def shift_dr(options = {})
  options = {
    start_state: :idle,   # Allowed start states: :idle, :select_dr_scan, :update_ir, :update_dr
    end_state:   :idle    # Allowed end states: :idle, :update_dr
  }.merge(options)

  if options[:start_state] == :idle  # allow for pause_dr state also if called from pause_dr block
    validate_state(:idle, :pause_dr)
  elsif options[:state_state] == :select_dr_scan
    validate_state(:select_dr_scan, :pause_dr)
  elsif options[:state_state] == :update_dr
    validate_state(:update_dr, :pause_dr)
  elsif options[:state_state] == :update_ir
    validate_state(:update_ir, :pause_dr)
  end
  log 'Transition to Shift-DR...'
  if state == :idle || state == :select_dr_scan || state == :update_ir || state == :update_dr
    # Non-pause states
    unless state == :select_dr_scan
      tms!(1)  # => Select-DR-Scan
      update_state :select_dr_scan
    end
    tms!(0)  # => Capture-DR
    update_state :capture_dr
    tms!(0)  # => Shift-DR
    update_state :shift_dr
    if options[:write]
      msg = "Write DR: #{options[:write]}"
    elsif options[:read]
      msg = "Read DR: #{options[:read]}"
    else
      msg = 'DR Data'
    end
    log msg, always: true do
      yield
      log 'Transition to Run-Test/Idle...'
      if @last_data_vector_shifted
        @last_data_vector_shifted = false
      else
        tms!(1)  # => Exit1-DR
        update_state :exit1_dr
      end
    end
    tms!(1)  # => Update-DR
    update_state :update_dr
    if options[:end_state] == :idle
      tms!(0)  # => Run-Test/Idle
      update_state :idle
    end
  else # :pause_dr
    tms!(1)  # => Exit2-DR
    update_state :exit2_dr
    tms!(0)  # => Shift-DR
    update_state :shift_dr
    yield
    log 'Transition to Pause-DR...'
    tms!(1)  # => Exit1-DR
    update_state :exit1_dr
    tms!(0)  # => Pause-DR
    update_state :pause_dr
  end
end

#shift_ir(options = {}) ⇒ Object

Goto Shift-IR state then exit back to Run-Test/Idle

This method can be nested inside of a pause_ir block to transition into the Shift-IR state and then back to Pause-IR

Examples:

Trandition into Shift-IR

# State is Run-Test/Idle
jtag.shift_ir do
  # State is Shift-IR
end
# State is Run-Test/Idle

Switching between Pause-IR and Shift-IR

# State is Run-Test/Idle
jtag.pause_ir do
  # State is Pause-IR
  jtag.shift_ir do
    # State is Shift-IR
  end
  # State is Pause-IR
end
# State is Run-Test/Idle


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/origen_jtag/tap_controller.rb', line 195

def shift_ir(options = {})
  options = {
    start_state: :idle,   # Allowed start states: :idle, :select_ir_scan
    end_state:   :idle    # Allowed end states: :idle, :update_ir, :select_dr_scan
  }.merge(options)
  if options[:start_state] == :idle
    validate_state(:idle, :pause_ir)
  else
    validate_state(:select_ir_scan, :pause_ir)
  end
  log 'Transition to Shift-IR...'
  if state == :idle || state == :select_ir_scan
    unless state == :select_ir_scan
      tms!(1)  # => Select-DR-Scan
      update_state :select_dr_scan
      tms!(1)  # => Select-IR-Scan
      update_state :select_ir_scan
    end
    tms!(0)  # => Capture-IR
    update_state :capture_ir
    tms!(0)  # => Shift-IR
    update_state :shift_ir
    if options[:write]
      msg = "Write IR: #{options[:write]}"
    elsif options[:read]
      msg = "Read IR: #{options[:read]}"
    else
      msg = 'IR Data'
    end
    log msg, always: true do
      yield
      if options[:end_state] == :idle
        log 'Transition to Run-Test/Idle...'
      elsif options[:end_state] == :update_ir
        log 'Transition to Update-IR...'
      elsif options[:end_state] == :select_dr_scan
        log 'Transition to Select-DR-Scan...'
      end
      if @last_data_vector_shifted
        @last_data_vector_shifted = false
      else
        tms!(1)  # => Exit1-IR
        update_state :exit1_ir
      end
    end
    tms!(1)  # => Update-IR
    update_state :update_ir
    if options[:end_state] == :idle
      tms!(0)  # => Run-Test/Idle
      update_state :idle
    elsif options[:end_state] == :select_dr_scan
      tms!(1)  # => Select-DR-Scan
      update_state :select_dr_scan
    end
  else # :pause_ir
    tms!(1)  # => Exit2-IR
    update_state :exit2_ir
    tms!(0)  # => Shift-IR
    update_state :shift_ir
    yield
    log 'Transition to Pause-IR...'
    tms!(1)  # => Exit1-IR
    update_state :exit1_ir
    tms!(0)  # => Pause-IR
    update_state :pause_ir
  end
end

#state_strObject Also known as: current_state_str

Returns the current state as a human readable string



323
324
325
# File 'lib/origen_jtag/tap_controller.rb', line 323

def state_str
  STATES[state]
end

#update_state(state) ⇒ Object



349
350
351
352
353
354
# File 'lib/origen_jtag/tap_controller.rb', line 349

def update_state(state)
  @state = state
  log "Current state: #{state_str}" if log_state_changes
  @listeners ||= Origen.listeners_for(:on_jtag_state_change)
  @listeners.each { |l| l.on_jtag_state_change(@state) }
end