origen_jtag 0.12.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.
@@ -0,0 +1,64 @@
1
+ module OrigenJTAG
2
+ # This is a dummy DUT model which is used
3
+ # to instantiate and test the JTAG locally
4
+ # during development.
5
+ #
6
+ # It is not included when this library is imported.
7
+ class DUT
8
+ include OrigenJTAG
9
+ include Origen::Callbacks
10
+ include Origen::Registers
11
+ include Origen::Pins
12
+
13
+ JTAG_CONFIG = {
14
+ verbose: true,
15
+ tclk_format: :rh,
16
+ tclk_multiple: 1,
17
+ tdo_strobe: :tclk_high,
18
+ tdo_store_cycle: 0,
19
+ init_state: :unknown
20
+ }
21
+
22
+ def initialize(options = {})
23
+ JTAG_CONFIG[:tclk_format] = options[:tclk_format] if options[:tclk_format]
24
+ JTAG_CONFIG[:tclk_multiple] = options[:tclk_multiple] if options[:tclk_multiple]
25
+ JTAG_CONFIG[:tdo_strobe] = options[:tdo_strobe] if options[:tdo_strobe]
26
+ JTAG_CONFIG[:tdo_store_cycle] = options[:tdo_store_cycle] if options[:tdo_store_cycle]
27
+ JTAG_CONFIG[:init_state] = options[:init_state] if options[:init_state]
28
+ end
29
+
30
+ def tclk_format
31
+ JTAG_CONFIG[:tclk_format]
32
+ end
33
+
34
+ def tclk_multiple
35
+ JTAG_CONFIG[:tclk_multiple]
36
+ end
37
+
38
+ def tdo_strobe
39
+ JTAG_CONFIG[:tdo_strobe]
40
+ end
41
+
42
+ def tdo_store_cycle
43
+ JTAG_CONFIG[:tdo_store_cycle]
44
+ end
45
+
46
+ def init_state
47
+ JTAG_CONFIG[:init_state]
48
+ end
49
+
50
+ def on_create
51
+ add_reg :test16, 0x0012, 16, bus: { pos: 8, bits: 8 },
52
+ bit: { pos: 0 }
53
+
54
+ add_reg :test32, 0x0014, 32, bus: { pos: 16, bits: 16 },
55
+ bit: { pos: 0 }
56
+
57
+ $tester.set_timeset('nvmbist', 40)
58
+ add_pin :tclk
59
+ add_pin :tdi
60
+ add_pin :tdo
61
+ add_pin :tms
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,299 @@
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
53
+ validate_state(:idle, :pause_dr)
54
+ log 'Transition to Shift-DR...'
55
+ if state == :idle
56
+ tms!(1) # => Select-DR-Scan
57
+ tms!(0) # => Capture-DR
58
+ tms!(0) # => Shift-DR
59
+ update_state :shift_dr
60
+ log '**** Data start ****', always: true
61
+ yield
62
+ log 'Transition to Run-Test/Idle...'
63
+ if @last_data_vector_shifted
64
+ @last_data_vector_shifted = false
65
+ else
66
+ tms!(1) # => Exit1-DR
67
+ end
68
+ log '**** Data stop ****', always: true
69
+ tms!(1) # => Update-DR
70
+ tms!(0) # => Run-Test/Idle
71
+ update_state :idle
72
+ else # :pause_dr
73
+ tms!(1) # => Exit2-DR
74
+ tms!(0) # => Shift-DR
75
+ update_state :shift_dr
76
+ yield
77
+ log 'Transition to Pause-DR...'
78
+ tms!(1) # => Exit1-DR
79
+ tms!(0) # => Pause-DR
80
+ update_state :pause_dr
81
+ end
82
+ end
83
+
84
+ # Goto Pause-DR state then exit back to Run-Test/Idle
85
+ #
86
+ # @example Trandition into Pause-DR
87
+ # # State is Run-Test/Idle
88
+ # jtag.pause_dr do
89
+ # # State is Pause-DR
90
+ # end
91
+ # # State is Run-Test/Idle
92
+ #
93
+ # This method can be nested inside of a shift_dr block
94
+ # to transition into the Pause-DR state and then back
95
+ # to Shift-DR
96
+ #
97
+ # @example Switching between Shift-DR and Pause-DR
98
+ # # State is Run-Test/Idle
99
+ # jtag.shift_dr do
100
+ # # State is Shift-DR
101
+ # jtag.pause_dr do
102
+ # # State is Pause-DR
103
+ # end
104
+ # # State is Shift-DR
105
+ # end
106
+ # # State is Run-Test/Idle
107
+ def pause_dr
108
+ validate_state(:idle, :shift_dr)
109
+ log 'Transition to Pause-DR...'
110
+ if state == :idle
111
+ tms!(1) # => Select-DR-Scan
112
+ tms!(0) # => Capture-DR
113
+ tms!(1) # => Exit1-DR
114
+ tms!(0) # => Pause-DR
115
+ update_state :pause_dr
116
+ yield
117
+ log 'Transition to Run-Test/Idle...'
118
+ tms!(1) # => Exit2-DR
119
+ tms!(1) # => Update-DR
120
+ tms!(0) # => Run-Test/Idle
121
+ update_state :idle
122
+ else # shift_dr
123
+ tms!(1) # => Exit1-DR
124
+ tms!(0) # => Pause-DR
125
+ update_state :pause_dr
126
+ yield
127
+ log 'Transition to Shift-DR...'
128
+ tms!(1) # => Exit2-DR
129
+ tms!(0) # => Shift-DR
130
+ update_state :shift_dr
131
+ end
132
+ end
133
+
134
+ # Goto Shift-IR state then exit back to Run-Test/Idle
135
+ #
136
+ # @example Trandition into Shift-IR
137
+ # # State is Run-Test/Idle
138
+ # jtag.shift_ir do
139
+ # # State is Shift-IR
140
+ # end
141
+ # # State is Run-Test/Idle
142
+ #
143
+ # This method can be nested inside of a pause_ir block
144
+ # to transition into the Shift-IR state and then back
145
+ # to Pause-IR
146
+ #
147
+ # @example Switching between Pause-IR and Shift-IR
148
+ # # State is Run-Test/Idle
149
+ # jtag.pause_ir do
150
+ # # State is Pause-IR
151
+ # jtag.shift_ir do
152
+ # # State is Shift-IR
153
+ # end
154
+ # # State is Pause-IR
155
+ # end
156
+ # # State is Run-Test/Idle
157
+ def shift_ir
158
+ validate_state(:idle, :pause_ir)
159
+ log 'Transition to Shift-IR...'
160
+ if state == :idle
161
+ tms!(1) # => Select-DR-Scan
162
+ tms!(1) # => Select-IR-Scan
163
+ tms!(0) # => Capture-IR
164
+ tms!(0) # => Shift-IR
165
+ update_state :shift_ir
166
+ log '**** Data start ****', always: true
167
+ yield
168
+ log 'Transition to Run-Test/Idle...'
169
+ if @last_data_vector_shifted
170
+ @last_data_vector_shifted = false
171
+ else
172
+ tms!(1) # => Exit1-DR
173
+ end
174
+ log '**** Data stop ****', always: true
175
+ tms!(1) # => Update-IR
176
+ tms!(0) # => Run-Test/Idle
177
+ update_state :idle
178
+ else # :pause_ir
179
+ tms!(1) # => Exit2-IR
180
+ tms!(0) # => Shift-IR
181
+ update_state :shift_ir
182
+ yield
183
+ log 'Transition to Pause-IR...'
184
+ tms!(1) # => Exit1-IR
185
+ tms!(0) # => Pause-IR
186
+ update_state :pause_ir
187
+ end
188
+ end
189
+
190
+ # Goto Pause-IR state then exit back to Run-Test/Idle
191
+ #
192
+ # @example Trandition into Pause-iR
193
+ # # State is Run-Test/Idle
194
+ # jtag.pause_ir do
195
+ # # State is Pause-IR
196
+ # end
197
+ # # State is Run-Test/Idle
198
+ #
199
+ # This method can be nested inside of a shift_ir block
200
+ # to transition into the Pause-IR state and then back
201
+ # to Shift-IR
202
+ #
203
+ # @example Switching between Shift-IR and Pause-IR
204
+ # # State is Run-Test/Idle
205
+ # jtag.shift_ir do
206
+ # # State is Shift-IR
207
+ # jtag.pause_ir do
208
+ # # State is Pause-IR
209
+ # end
210
+ # # State is Shift-IR
211
+ # end
212
+ # # State is Run-Test/Idle
213
+ def pause_ir
214
+ validate_state(:idle, :shift_ir)
215
+ log 'Transition to Pause-IR...'
216
+ if state == :idle
217
+ tms!(1) # => Select-DR-Scan
218
+ tms!(1) # => Select-IR-Scan
219
+ tms!(0) # => Capture-IR
220
+ tms!(1) # => Exit1-IR
221
+ tms!(0) # => Pause-IR
222
+ update_state :pause_ir
223
+ yield
224
+ log 'Transition to Run-Test/Idle...'
225
+ tms!(1) # => Exit2-IR
226
+ tms!(1) # => Update-IR
227
+ tms!(0) # => Run-Test/Idle
228
+ update_state :idle
229
+ else # :shift_ir
230
+ tms!(1) # => Exit1-IR
231
+ tms!(0) # => Pause-IR
232
+ update_state :pause_ir
233
+ yield
234
+ log 'Transition to Shift-IR...'
235
+ tms!(1) # => Exit2-IR
236
+ tms!(0) # => Shift-IR
237
+ update_state :shift_ir
238
+ end
239
+ end
240
+
241
+ # Returns the current state as a human readable string
242
+ def state_str
243
+ STATES[state]
244
+ end
245
+ alias_method :current_state_str, :state_str
246
+
247
+ # Forces the state to Run-Test/Idle regardless of the current
248
+ # state.
249
+ def idle
250
+ log 'Force transition to Run-Test/Idle...'
251
+ # From the JTAG2IPS block guide holding TMS high for 5 cycles
252
+ # will force it to reset regardless of the state, let's give
253
+ # it 6 for luck:
254
+ 6.times { tms!(1) }
255
+ # Now a couple of cycles low to get it into idle
256
+ 2.times { tms!(0) }
257
+ update_state :idle
258
+ end
259
+
260
+ # Force state to Test-Logic-Reset regardless of the current
261
+ # state
262
+ def reset
263
+ log 'Force transition to Test-Logic-Reset...'
264
+ # JTAG reset
265
+ 6.times { tms!(1) }
266
+ end
267
+
268
+ private
269
+
270
+ def init_tap_controller(options = {})
271
+ options = {
272
+ }.merge(options)
273
+ end
274
+
275
+ def update_state(state)
276
+ @state = state
277
+ log "Current state: #{state_str}"
278
+ end
279
+
280
+ # Ensures that the current state matches one of the given acceptable
281
+ # states.
282
+ #
283
+ # Additionally if the current state is unknown and idle is acceptable
284
+ # then the state will be transitioned to idle.
285
+ def validate_state(*acceptable_states)
286
+ if current_state == :unknown && acceptable_states.include?(:idle)
287
+ idle
288
+ elsif acceptable_states.include?(current_state)
289
+ return
290
+ else
291
+ fail 'JTAG TAP Controller - An invalid state sequence has occurred!'
292
+ end
293
+ end
294
+
295
+ def log(msg, options = {})
296
+ cc "JTAG::TAPController - #{msg}" if verbose? || options[:always]
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,13 @@
1
+ require 'origen'
2
+ require_relative '../config/application.rb'
3
+
4
+ # Include this module to add a JTAG driver to your class
5
+ module OrigenJTAG
6
+ autoload :TAPController, 'origen_jtag/tap_controller'
7
+ autoload :Driver, 'origen_jtag/driver'
8
+
9
+ # Returns an instance of the OrigenJTAG::Driver
10
+ def jtag
11
+ @jtag ||= Driver.new(self)
12
+ end
13
+ end
@@ -0,0 +1,184 @@
1
+ Pattern.create(options={:name => "jtag_workout_#{$dut.tclk_format.upcase}#{$dut.tclk_multiple}"}) do
2
+ def test(msg)
3
+ ss "Test - #{msg}"
4
+ end
5
+
6
+ jtag = $dut.jtag
7
+ reg = $dut.reg(:test16)
8
+
9
+ # First tests of the TAP Controller
10
+
11
+ test "Transition TAP controller in and out of Shift-DR"
12
+ jtag.shift_dr { }
13
+
14
+ test "Transition TAP controller in and out of Pause-DR"
15
+ jtag.pause_dr { }
16
+
17
+ test "Transition TAP controller in and out of Shift-IR"
18
+ jtag.shift_ir { }
19
+
20
+ test "Transition TAP controller in and out of Pause-IR"
21
+ jtag.pause_ir { }
22
+
23
+ test "Transition into Shift-DR, then back and forth into Pause-DR"
24
+ jtag.shift_dr do
25
+ jtag.pause_dr { }
26
+ jtag.pause_dr { }
27
+ end
28
+
29
+ test "Transition into Pause-DR, then back and forth into Shift-DR"
30
+ jtag.pause_dr do
31
+ jtag.shift_dr { }
32
+ jtag.shift_dr { }
33
+ end
34
+
35
+ test "Transition into Shift-IR, then back and forth into Pause-IR"
36
+ jtag.shift_ir do
37
+ jtag.pause_ir { }
38
+ jtag.pause_ir { }
39
+ end
40
+
41
+ test "Transition into Pause-IR, then back and forth into Shift-IR"
42
+ jtag.pause_ir do
43
+ jtag.shift_ir { }
44
+ jtag.shift_ir { }
45
+ end
46
+
47
+ # Tests of the shift method, make sure it handles registers with
48
+ # bit-level flags set in additional to dumb values
49
+
50
+ test "Shifting an explicit value into TDI"
51
+ jtag.shift 0x1234, :size => 16, :cycle_last => true
52
+
53
+ test "Shifting an explicit value out of TDO"
54
+ jtag.shift 0x1234, :size => 16, :cycle_last => true, :read => true
55
+
56
+ test "Shift register into TDI"
57
+ reg.write(0xFF01)
58
+ cc "Full register (16 bits)"
59
+ jtag.shift reg, :cycle_last => true
60
+ cc "Full register with additional size (32 bits)"
61
+ jtag.shift reg, :cycle_last => true, :size => 32
62
+ cc "Full register with reduced size (8 bits)"
63
+ jtag.shift reg, :cycle_last => true, :size => 8, :includes_last_bit => false
64
+
65
+ test "Shift register into TDI with overlay"
66
+ reg.overlay("write_overlay")
67
+ cc "Full register (16 bits)"
68
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
69
+ jtag.shift reg, :cycle_last => true
70
+ cc "Full register with additional size (32 bits)"
71
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
72
+ jtag.shift reg, :cycle_last => true, :size => 32
73
+ cc "Full register with reduced size (8 bits)"
74
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
75
+ jtag.shift reg, :cycle_last => true, :size => 8, :includes_last_bit => false
76
+ cc "It should in-line overlays when running in simulation mode"
77
+ Origen.mode = :simulation
78
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
79
+ jtag.shift reg, :cycle_last => true
80
+ Origen.mode = :debug
81
+
82
+ test "Shift register into TDI with single bit overlay"
83
+ reg.overlay(nil)
84
+ reg.bit(:bit).overlay("write_overlay")
85
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
86
+ jtag.shift reg, :cycle_last => true
87
+ reg.overlay(nil)
88
+
89
+ test "Read register out of TDO"
90
+ cc "Full register (16 bits)"
91
+ reg.read
92
+ jtag.shift reg, :cycle_last => true, :read => true
93
+ cc "Full register with additional size (32 bits)"
94
+ reg.read
95
+ jtag.shift reg, :cycle_last => true, :size => 32, :read => true
96
+ cc "Full register with reduced size (8 bits)"
97
+ reg.read
98
+ jtag.shift reg, :cycle_last => true, :size => 8, :read => true, :includes_last_bit => false
99
+
100
+ test "Read single bit out of TDO"
101
+ reg.bit(:bit).read
102
+ jtag.shift reg, :cycle_last => true, :read => true
103
+
104
+ test "Store register out of TDO"
105
+ cc "Full register (16 bits)"
106
+ reg.store
107
+ jtag.shift reg, :cycle_last => true, :read => true
108
+ cc "Full register with additional size (32 bits)"
109
+ reg.store
110
+ jtag.shift reg, :cycle_last => true, :size => 32, :read => true
111
+ cc "Full register with reduced size (8 bits)"
112
+ reg.store
113
+ jtag.shift reg, :cycle_last => true, :size => 8, :read => true, :includes_last_bit => false
114
+
115
+ test "Store single bit out of TDO"
116
+ reg.bit(:bit).store
117
+ jtag.shift reg, :cycle_last => true, :read => true
118
+
119
+ test "Test flag clear, bit 0 should be read, but not stored"
120
+ reg.bit(:bit).read
121
+ jtag.shift reg, :cycle_last => true, :read => true
122
+
123
+ test "Shift register out of TDO with overlay"
124
+ reg.overlay("read_overlay")
125
+ cc "Full register (16 bits)"
126
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
127
+ jtag.shift reg, :cycle_last => true, :read => true
128
+ cc "Full register with additional size (32 bits)"
129
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
130
+ jtag.shift reg, :cycle_last => true, :size => 32, :read => true
131
+ cc "Full register with reduced size (8 bits)"
132
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
133
+ jtag.shift reg, :cycle_last => true, :size => 8, :read => true, :includes_last_bit => false
134
+ cc "It should in-line overlays when running in simulation mode"
135
+ Origen.mode = :simulation
136
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
137
+ jtag.shift reg, :cycle_last => true, :read => true
138
+ Origen.mode = :debug
139
+
140
+ test "Shift register out of TDO with single bit overlay"
141
+ reg.overlay(nil)
142
+ reg.bit(:bit).overlay("read_overlay")
143
+ Origen.tester.cycle # Give a padding cycle as a place for the subroutine call to go
144
+ jtag.shift reg, :cycle_last => true
145
+ reg.overlay(nil)
146
+
147
+ # Finally integration tests of the TAPController + shift
148
+
149
+ test "Write value into DR"
150
+ jtag.write_dr 0xFFFF, :size => 16, :msg => "Write value into DR"
151
+
152
+ test "Write register into DR with full-width overlay"
153
+ r = $dut.reg(:test32).overlay("write_overlay")
154
+ jtag.write_dr r
155
+
156
+ test "Read value out of DR"
157
+ jtag.read_dr 0xFFFF, :size => 16, :msg => "Read value out of DR"
158
+
159
+ test "Write value into IR"
160
+ jtag.write_ir 0xF, :size => 4, :msg => "Write value into IR"
161
+
162
+ test "Read value out of IR"
163
+ jtag.read_ir 0xF, :size => 4, :msg => "Read value out of IR"
164
+
165
+ test "The IR value is tracked and duplicate writes are inhibited"
166
+ jtag.write_ir 0xF, :size => 4
167
+
168
+ test "Unless forced"
169
+ jtag.write_ir 0xF, :size => 4, :force => true
170
+
171
+ test "Reset"
172
+ jtag.reset
173
+
174
+ test "Suspend of compare on TDO works"
175
+ cc "TDO should be H"
176
+ jtag.read_dr 0xFFFF, :size => 16, :msg => "Read value out of DR"
177
+ $tester.ignore_fails($dut.pin(:tdo)) do
178
+ cc "TDO should be X"
179
+ jtag.read_dr 0xFFFF, :size => 16, :msg => "Read value out of DR"
180
+ end
181
+ cc "TDO should be H"
182
+ jtag.read_dr 0xFFFF, :size => 16, :msg => "Read value out of DR"
183
+
184
+ end
@@ -0,0 +1,139 @@
1
+ % render "layouts/basic.html" do
2
+
3
+ %# HTML tags can be embedded in mark down files if you want to do specific custom
4
+ %# formatting like this, but in most cases that is not required.
5
+ <h1><%= Origen.app.namespace %> <span style="font-size: 14px">(<%= Origen.app.version %>)</span></h1>
6
+
7
+ ### Purpose
8
+
9
+ This plugin provides an ATE driver for an IEEE 1149.1 compliant JTAG interface.
10
+
11
+ It makes no assumptions about the instruction or data register attributes or higher
12
+ level protocol concerns. For use at DUT model level this plugin would be normally be wrapped in
13
+ a higher level protocol such as [Nexus](http://origen-sdk.org/nexus/).
14
+
15
+ ### How To Import
16
+
17
+ In your Gemfile add:
18
+
19
+ ~~~ruby
20
+ gem "origen_jtag", ">= <%= Origen.app.version %>"
21
+ ~~~
22
+
23
+ or if your application is a plugin add this to your <code>.gemspec</code>
24
+
25
+ ~~~ruby
26
+ spec.add_development_dependency "origen_jtag", ">= <%= Origen.app.version %>"
27
+ ~~~
28
+
29
+ __NOTE:__ You will also need to include <code>require 'origen_jtag'</code> somewhere in your environment. This can be done in <code>config/environment.rb</code> for example.
30
+
31
+ ### How To Use
32
+
33
+ Include the <code>OrigenJTAG</code> module to add a JTAG driver to your class and
34
+ define the required pins.
35
+ Normally the pins would be an alias to existing DUT pins and therefore the
36
+ JTAG driver module cannot assume them.
37
+
38
+ Including the module adds a <code>jtag</code> method which will return an instance of
39
+ [<code>OrigenJTAG::Driver</code>](<%= path "api/OrigenJTAG/Driver.html" %>).
40
+
41
+ The following attributes can be customized by defining a <code>JTAG_CONFIG</code>
42
+ hash:
43
+
44
+ * **tclk_format** - TCLK timing format, Return High (:rh) or Return Low (:rl). Default is :rh.
45
+ * **tclk_multiple** - Number of cycles for a single TCLK pulse to cover, to support cases where TCLK needs to be a fraction of another clock period. Assumes 50% duty cycle, specify only even numbers if > 1. Default is :r1.
46
+ * **tdo_strobe** - When using multiple cycles for TCK, which state of TCK to strobe for TDO, :tclk_high or :tclk_low or :tclk_all. Default :tclk_high.
47
+ * **tdo_store_cycle** - When using multiple cycles for TCK, which cycle of TCK to store for TDO if store requested (0 to number of tclk_multiple-1). Default 0
48
+
49
+ Here is an example integration:
50
+
51
+ ~~~ruby
52
+ class Pioneer
53
+
54
+ include OrigenJTAG
55
+ include Origen::Pins
56
+
57
+ # TCK covers 4 tester cycles, 2 high then 2 low for each effective TCK pulse
58
+ # Strobe TDO only when TCK high. Only store TDO on last cycle (3)
59
+ JTAG_CONFIG = {
60
+ :tclk_format => :rl,
61
+ :tclk_multiple => 4,
62
+ :tdo_strobe => :tclk_high,
63
+ :tdo_store_cycle => 3,
64
+ }
65
+
66
+ def initialize
67
+ add_pin :tclk
68
+ add_pin :tdi
69
+ add_pin :tdo
70
+ add_pin :tms
71
+ end
72
+
73
+ end
74
+
75
+ Pioneer.new.jtag # => An instance of OrigenJTAG::Driver
76
+ ~~~
77
+
78
+ Two APIs are provided, the primary one provides canned methods to read and
79
+ write to the IR and DR registers.
80
+
81
+ These accept either an absolute data value or an Origen register/bit collection.
82
+
83
+ ~~~ruby
84
+ jtag.write_dr 0x1234, :size => 16
85
+ # The size option is not required when a register is supplied
86
+ jtag.write_dr $dut.reg(:clkdiv)
87
+ # Although it can still be added if the register is not the full data width
88
+ jtag.write_dr $dut.reg(:clkdiv), :size => 32
89
+ # A rich read method is available which supports bit-level read, store and
90
+ # overlay operations
91
+ $dut.reg(:clkdiv).bits(:div).read(0x55)
92
+ jtag.read $dut.reg(:clkdiv)
93
+ # Similar methods exist for the instruction register
94
+ jtag.write_ir 0x1F, :size => 5
95
+ jtag.read_ir 0x1F, :size => 5
96
+ ~~~
97
+
98
+ A secondary API provides low level control of the TAP Controller state machine.
99
+
100
+ ~~~ruby
101
+ jtag.pause_dr do
102
+ jtag.shift_dr do
103
+ # The shift method accepts the same arguments as the canned read/write methods
104
+ jtag.shift 0x55, :size => 32
105
+ end
106
+ end
107
+ ~~~
108
+
109
+ See the [<code>OrigenJTAG::Driver</code>](<%= path "api/OrigenJTAG/Driver.html" %>) and
110
+ [<code>OrigenJTAG::TAPController</code>](<%= path "api/OrigenJTAG/TAPController.html" %>)
111
+ APIs for more details about the available driver methods.
112
+
113
+ ### How To Setup a Development Environment
114
+
115
+ [Clone the repository from Github](https://github.com/Origen-SDK/origen_jtag).
116
+
117
+ An instance of the OrigenJTAG driver is hooked up to a dummy DUT
118
+ object for use in the console:
119
+
120
+ ~~~
121
+ origen i
122
+
123
+ > $dut.jtag
124
+ => #<OrigenJTAG::Driver:0x0000001ee48e78>
125
+ ~~~
126
+
127
+ Follow the instructions here if you want to make a 3rd party app
128
+ workspace use your development copy of the OrigenJTAG plugin:
129
+ [Setting up a Plugin Development Environment](http://origen-sdk.org/origen/latest/guides/plugins)
130
+
131
+ This plugin also contains a test suite, makes sure this passes before committing
132
+ any changes!
133
+
134
+ ~~~
135
+ origen examples
136
+ ~~~
137
+
138
+
139
+ % end