origen_jtag 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e06b3dca12b20579f6fbfbc389dac204e960a93b
4
+ data.tar.gz: dc97efa495078334d68ce6ac8bd43fcea8b2467d
5
+ SHA512:
6
+ metadata.gz: 43f03422ef2359a8e10a527300824d84e29f92cd97934b535d69f12e73aa480163790a06041b991bb25d5c05a76c491dcef9428db0cdaed7b5f3b7c33359e134
7
+ data.tar.gz: b84f766c5f4dd19cc111fad60e4f55c2162f2b09c4abff4c2d4016b5a97b0ff036e75393517e8488b87af9da552d26b0fc28a0e8fe48d1f9765f449bf15e0433
@@ -0,0 +1,64 @@
1
+ class OrigenJTAGApplication < Origen::Application
2
+
3
+ # This file contains examples of some of the most common configuration options,
4
+ # to see a real production example from a large application have a look at:
5
+ # sync://sync-15088:15088/Projects/common_tester_blocks/blocks/C90TFS_NVM_tester/tool_data/origen_v2/config/application.rb
6
+
7
+ # This information is used in headers and email templates, set it specific
8
+ # to your application
9
+ config.name = "Origen JTAG"
10
+ config.initials = "OrigenJTAG"
11
+ # Force naming for gem, done here because JTAG will not automatically convert to
12
+ # 'jtag' when OrigenJTAG is snakecased
13
+ self.name = "origen_jtag"
14
+ self.namespace = "OrigenJTAG"
15
+ config.rc_url = "git@github.com:Origen-SDK/origen_jtag.git"
16
+ config.release_externally = true
17
+
18
+ # To enable deployment of your documentation to a web server (via the 'origen web'
19
+ # command) fill in these attributes.
20
+ config.web_directory = "git@github.com:Origen-SDK/Origen-SDK.github.io.git/jtag"
21
+ config.web_domain = "http://origen-sdk.org/jtag"
22
+
23
+ config.semantically_version = true
24
+
25
+ config.lint_test = {
26
+ # Require the lint tests to pass before allowing a release to proceed
27
+ run_on_tag: true,
28
+ # Auto correct violations where possible whenever 'origen lint' is run
29
+ auto_correct: true,
30
+ # Limit the testing for large legacy applications
31
+ #level: :easy,
32
+ # Run on these directories/files by default
33
+ #files: ["lib", "config/application.rb"],
34
+ }
35
+
36
+ # Ensure that all tests pass before allowing a release to continue
37
+ def validate_release
38
+ if !system("origen examples") #|| !system("origen specs")
39
+ puts "Sorry but you can't release with failing tests, please fix them and try again."
40
+ exit 1
41
+ else
42
+ puts "All tests passing, proceeding with release process!"
43
+ end
44
+ end
45
+
46
+ # Run code coverage when deploying the web site
47
+ def before_deploy_site
48
+ Dir.chdir Origen.root do
49
+ system "origen examples -c"
50
+ dir = "#{Origen.root}/web/output/coverage"
51
+ FileUtils.remove_dir(dir, true) if File.exists?(dir)
52
+ system "mv #{Origen.root}/coverage #{dir}"
53
+ end
54
+ end
55
+
56
+ # Deploy the website automatically after a production tag
57
+ def after_release_email(tag, note, type, selector, options)
58
+ command = "origen web compile --remote --api"
59
+ Dir.chdir Origen.root do
60
+ system command
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,90 @@
1
+ # This file should be used to extend the origen command line tool with tasks
2
+ # specific to your application.
3
+ # The comments below should help to get started and you can also refer to
4
+ # lib/origen/commands.rb in your Origen core workspace for more examples and
5
+ # inspiration.
6
+ #
7
+ # Also see the official docs on adding commands:
8
+ # http://origen.freescale.net/origen/latest/guides/custom/commands/
9
+
10
+ # Map any command aliases here, for example to allow origen -x to refer to a
11
+ # command called execute you would add a reference as shown below:
12
+ aliases ={
13
+ # "-x" => "execute",
14
+ }
15
+
16
+ # The requested command is passed in here as @command, this checks it against
17
+ # the above alias table and should not be removed.
18
+ @command = aliases[@command] || @command
19
+
20
+ def path_to_coverage_report
21
+ require 'pathname'
22
+ Pathname.new("#{Origen.root}/coverage/index.html").relative_path_from(Pathname.pwd)
23
+ end
24
+
25
+ def enable_coverage(name, merge=true)
26
+ if ARGV.delete("-c") || ARGV.delete("--coverage")
27
+ require 'simplecov'
28
+ SimpleCov.start do
29
+ command_name name
30
+
31
+ at_exit do
32
+ SimpleCov.result.format!
33
+ puts ""
34
+ puts "To view coverage report:"
35
+ puts " firefox #{path_to_coverage_report} &"
36
+ puts ""
37
+ end
38
+ end
39
+ yield
40
+ else
41
+ yield
42
+ end
43
+ end
44
+
45
+ # Now branch to the specific task code
46
+ case @command
47
+
48
+ when "examples"
49
+ Origen.load_application
50
+ enable_coverage("examples") do
51
+
52
+ # Pattern generator tests
53
+ ARGV = %w(jtag_workout -t v93k.rb -r approved)
54
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
55
+ ARGV = %w(jtag_workout -t debug_RH1 -r approved)
56
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
57
+ ARGV = %w(jtag_workout -t debug_RL1 -r approved)
58
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
59
+
60
+ ARGV = %w(jtag_workout -t v93k_RH4.rb -r approved)
61
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
62
+ ARGV = %w(jtag_workout -t debug_RH4 -r approved)
63
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
64
+ ARGV = %w(jtag_workout -t debug_RL4 -r approved)
65
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
66
+
67
+ if Origen.app.stats.changed_files == 0 &&
68
+ Origen.app.stats.new_files == 0 &&
69
+ Origen.app.stats.changed_patterns == 0 &&
70
+ Origen.app.stats.new_patterns == 0
71
+
72
+ Origen.app.stats.report_pass
73
+ else
74
+ Origen.app.stats.report_fail
75
+ end
76
+ puts ""
77
+ end
78
+ exit 0
79
+
80
+ # Always leave an else clause to allow control to fall back through to the
81
+ # Origen command handler.
82
+ # You probably want to also add the command details to the help shown via
83
+ # origen -h, you can do this be assigning the required text to @application_commands
84
+ # before handing control back to Origen. Un-comment the example below to get started.
85
+ else
86
+ @application_commands = <<-EOT
87
+ examples Run the examples (tests), -c will enable coverage
88
+ EOT
89
+
90
+ end
@@ -0,0 +1,15 @@
1
+ # This file is similar to environment.rb and will be loaded
2
+ # automatically at the start of each invocation of Origen.
3
+ #
4
+ # However the major difference is that it will not be loaded
5
+ # if the application is imported by a 3rd party app - in that
6
+ # case only environment.rb is loaded.
7
+ #
8
+ # Therefore this file should be used to load anything you need
9
+ # to setup a development environment for this app, normally
10
+ # this would be used to define some dummy classes to instantiate
11
+ # your objects so that they can be tested and/or interacted with
12
+ # in the console.
13
+ module OrigenJTAG
14
+ autoload :DUT, "origen_jtag/dut"
15
+ end
@@ -0,0 +1 @@
1
+ require "origen_jtag"
data/config/users.rb ADDED
@@ -0,0 +1,19 @@
1
+ # This file defines the users associated with your project, it is basically the
2
+ # mailing list for release notes.
3
+ #
4
+ # You can split your users into "admin" and "user" groups, the main difference
5
+ # between the two is that admin users will get all tag emails, users will get
6
+ # emails on external/official releases only.
7
+ #
8
+ # Users are also prohibited from running the "origen tag" task, but this is
9
+ # really just to prevent a casual user from executing it inadvertently and is
10
+ # not intended to be a serious security gate.
11
+ module Origen
12
+ module Users
13
+ def users
14
+ @users ||= [
15
+
16
+ ]
17
+ end
18
+ end
19
+ end
data/config/version.rb ADDED
@@ -0,0 +1,8 @@
1
+ module OrigenJTAG
2
+ MAJOR = 0
3
+ MINOR = 12
4
+ BUGFIX = 0
5
+ DEV = nil
6
+
7
+ VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
+ end
@@ -0,0 +1,449 @@
1
+ module OrigenJTAG
2
+ # This driver provides methods to read and write from a JTAG instruction
3
+ # and data registers.
4
+ #
5
+ # Low level methods are also provided for fine control of the TAP Controller
6
+ # state machine via the TAPController module.
7
+ #
8
+ # To use this driver the parent model must define the following pins (an alias is fine):
9
+ # :tclk
10
+ # :tdi
11
+ # :tdo
12
+ # :tms
13
+ class Driver
14
+ REQUIRED_PINS = [:tclk, :tdi, :tdo, :tms]
15
+
16
+ include TAPController
17
+ include Origen::Registers
18
+
19
+ # Returns the object that instantiated the JTAG
20
+ attr_reader :owner
21
+
22
+ # Returns the current value in the instruction register
23
+ attr_reader :ir_value
24
+
25
+ attr_accessor :tclk_format
26
+ # Set true to print out debug comments about all state transitions
27
+ attr_accessor :verbose
28
+ alias_method :verbose?, :verbose
29
+
30
+ def initialize(owner, options = {})
31
+ @owner = owner
32
+ validate_pins
33
+
34
+ # The parent can configure JTAG settings by defining this constant
35
+ if defined?(owner.class::JTAG_CONFIG)
36
+ options = owner.class::JTAG_CONFIG.merge(options)
37
+ end
38
+
39
+ # Fallback defaults
40
+ options = {
41
+ verbose: false,
42
+ tclk_format: :rh, # format of JTAG clock used: ReturnHigh (:rh), ReturnLo (:rl)
43
+ tclk_multiple: 1, # number of cycles for one clock pulse, assumes 50% duty cycle. Uses tester non-return format to spread TCK across multiple cycles.
44
+ # e.g. @tclk_multiple = 2, @tclk_format = :rh, means one cycle with Tck low (non-return), one with Tck high (NR)
45
+ # @tclk_multiple = 4, @tclk_format = :rl, means 2 cycles with Tck high (NR), 2 with Tck low (NR)
46
+ tdo_strobe: :tclk_high, # when using multiple cycles for TCK, when to strobe for TDO, options include:
47
+ # :tclk_high - strobe TDO only when TCK is high
48
+ # :tclk_low - strobe TDO only when TCK is low
49
+ # :tclk_all - strobe TDO throughout TCK cycle
50
+ tdo_store_cycle: 0, # store vector cycle within TCK (i.e. when to indicate to tester to store vector within TCK cycle. 0 is first vector, 1 is second, etc.)
51
+ # NOTE: only when user indicates to store TDO, which will mean we don't care the 1 or 0 value on TDO (overriding effectively :tdo_strobe option above)
52
+ init_state: :unknown
53
+ }.merge(options)
54
+
55
+ init_tap_controller(options)
56
+
57
+ @verbose = options[:verbose]
58
+ @ir_value = :unknown
59
+ @tclk_format = options[:tclk_format]
60
+ @tclk_multiple = options[:tclk_multiple]
61
+ @tdo_strobe = options[:tdo_strobe]
62
+ @tdo_store_cycle = options[:tdo_store_cycle]
63
+ @state = options[:init_state]
64
+ end
65
+
66
+ # Shift data into the TDI pin or out of the TDO pin.
67
+ #
68
+ # There is no TAP controller state checking or handling here, it just
69
+ # shifts some data directly into the pattern, so it is assumed that some
70
+ # higher level logic is co-ordinating the TAP Controller.
71
+ #
72
+ # Most applications should not call this method directly and should instead
73
+ # use the pre-packaged read/write_dr/ir methods.
74
+ # However it is provided as a public API for the corner cases like generating
75
+ # an overlay subroutine pattern where it would be necessary to generate some JTAG
76
+ # vectors outwith the normal state controller wrapper.
77
+ #
78
+ # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
79
+ # Value to be shifted. If a reg/bit collection is supplied this can be pre-marked for
80
+ # read, store or overlay and which will result in the requested action being applied to
81
+ # the cycles corresponding to those bits only (don't care cycles will be generated for the others).
82
+ # @param [Hash] options Options to customize the operation
83
+ # @option options [Integer] :size The number of bits to shift. This is optional
84
+ # when supplying a register or bit collection in which case the size will be derived from
85
+ # the number of bits supplied. If this option is supplied then it will override
86
+ # the size derived from the bits. If the size is greater than the number of bits
87
+ # provided then the additional space will be padded by 0s or don't cares as appropriate.
88
+ # @option options [Boolean] :read (false) When true the given value will be compared on the TDO pin
89
+ # instead of being shifted into the TDI pin. In the case of a register object being provided
90
+ # only those bits that are actually marked for read will be compared.
91
+ # @option options [Boolean] :cycle_last (false) Normally the last data bit is applied to the
92
+ # pins but not cycled, this is to integrate with the TAPController which usually
93
+ # requires that the TMS value is also changed on the last data bit. To override this
94
+ # default behavior and force a cycle for the last data bit set this to true.
95
+ # @option options [Boolean] :includes_last_bit (true) When true the TMS pin will be driven
96
+ # to 1 on the last cycle of the shift if :cycle_last has been specified. To override this
97
+ # and keep TMS low on the last cycle set this to false. One reason for doing this would be
98
+ # if generating some subroutine vectors which only represented a partial section of a shift
99
+ # operation.
100
+ def shift(reg_or_val, options = {})
101
+ options = {
102
+ read: false,
103
+ cycle_last: false,
104
+ includes_last_bit: true
105
+ }.merge(options)
106
+ size = extract_size(reg_or_val, options)
107
+ if options.key?(:arm_debug_comment)
108
+ cc options[:arm_debug_comment]
109
+ end
110
+ if options.key?(:arm_debug_overlay)
111
+ $tester.label(options[:arm_debug_overlay])
112
+ end
113
+ size = extract_size(reg_or_val, options)
114
+ contains_bits = (contains_bits?(reg_or_val) || is_a_bit?(reg_or_val))
115
+ owner.pin(:tdi).drive(0) # Drive state when reading out
116
+ owner.pin(:tms).drive(0)
117
+ size.times do |i|
118
+ call_subroutine = false
119
+ if options[:read]
120
+ # If it's a register support bit-wise reads
121
+ if contains_bits
122
+ if reg_or_val[i]
123
+ if reg_or_val[i].is_to_be_stored?
124
+ Origen.tester.store_next_cycle(owner.pin(:tdo))
125
+ owner.pin(:tdo).dont_care if Origen.tester.j750?
126
+ elsif reg_or_val[i].has_overlay?
127
+ if Origen.mode.simulation?
128
+ owner.pin(:tdo).dont_care
129
+ else
130
+ call_subroutine = reg_or_val[i].overlay_str
131
+ end
132
+ elsif reg_or_val[i].is_to_be_read?
133
+ owner.pin(:tdo).assert(reg_or_val[i] ? reg_or_val[i] : 0)
134
+ elsif options.key?(:compare_data)
135
+ if i.eql?(0) || i.eql?(1) || i.eql?(2)
136
+ # Skip comparing first three status bits
137
+ owner.pin(:tdo).dont_care
138
+ else
139
+ owner.pin(:tdo).assert(reg_or_val[i] ? reg_or_val[i] : 0)
140
+ end
141
+ else
142
+ owner.pin(:tdo).dont_care
143
+ end
144
+ # If the read width extends beyond the register boundary, don't care
145
+ # the extra bits
146
+ else
147
+ owner.pin(:tdo).dont_care
148
+ end
149
+ # Otherwise read the whole thing
150
+ else
151
+ owner.pin(:tdo).assert(reg_or_val[i] ? reg_or_val[i] : 0)
152
+ end
153
+ else
154
+ if contains_bits && reg_or_val[i] && reg_or_val[i].has_overlay?
155
+ if Origen.mode.simulation?
156
+ owner.pin(:tdi).drive(reg_or_val[i] ? reg_or_val[i] : 0)
157
+ else
158
+ call_subroutine = reg_or_val[i].overlay_str
159
+ end
160
+ elsif options.key?(:arm_debug_overlay)
161
+ if Origen.mode.simulation?
162
+ owner.pin(:tdi).drive(reg_or_val[i] ? reg_or_val[i] : 0)
163
+ else
164
+ $tester.label('// JTAG DATA Pin: ' + i.to_s)
165
+ owner.pin(:tdi).drive(reg_or_val[i] ? reg_or_val[i] : 0)
166
+ end
167
+ else
168
+ owner.pin(:tdi).drive(reg_or_val[i] ? reg_or_val[i] : 0)
169
+ end
170
+ end
171
+ if call_subroutine
172
+ Origen.tester.call_subroutine(call_subroutine)
173
+ @last_data_vector_shifted = true
174
+ else
175
+ @last_data_vector_shifted = false
176
+ # Don't latch the last bit, that will be done when
177
+ # leaving the state.
178
+ if i != size - 1 || options[:cycle_last]
179
+ if i == size - 1 && options[:includes_last_bit]
180
+ owner.pin(:tms).drive(1)
181
+ end
182
+ tclk_cycle do
183
+ Origen.tester.cycle
184
+ end
185
+ owner.pin(:tdo).dont_care
186
+ else
187
+ @deferred_compare = true
188
+ end
189
+ end
190
+ end
191
+ # Clear read and similar flags to reflect that the request has just
192
+ # been fulfilled
193
+ reg_or_val.clear_flags if reg_or_val.respond_to?(:clear_flags)
194
+ end
195
+
196
+ # Cycles the tester through one TCLK cycle
197
+ # Adjusts for the TCLK format and cycle span
198
+ # Assumes caller will drive pattern to tester
199
+ # via .drive or similar
200
+ def tclk_cycle
201
+ case @tclk_format
202
+ when :rh
203
+ tclk_val = 0
204
+ when :rl
205
+ tclk_val = 1
206
+ else
207
+ fail 'ERROR: Invalid Tclk timing format!'
208
+ end
209
+
210
+ # determine whether to mask TDO on first half cycle
211
+ mask_tdo_half0 = ((@tclk_format == :rl) && (@tdo_strobe == :tclk_low) && (@tclk_multiple > 1)) ||
212
+ ((@tclk_format == :rh) && (@tdo_strobe == :tclk_high) && (@tclk_multiple > 1))
213
+
214
+ # determine whether to mask TDO on second half cycle
215
+ mask_tdo_half1 = ((@tclk_format == :rl) && (@tdo_strobe == :tclk_high) && (@tclk_multiple > 1)) ||
216
+ ((@tclk_format == :rh) && (@tdo_strobe == :tclk_low) && (@tclk_multiple > 1))
217
+
218
+ # determine whether TDO is set to capture for this TCK cycle
219
+ tdo_to_be_captured = owner.pin(:tdo).to_be_captured?
220
+
221
+ # If TDO is already suspended (by an application) then don't do the
222
+ # suspends below since the resume will clear the application's suspend
223
+ tdo_already_suspended = owner.pin(:tdo).suspended? && !@tdo_suspended_by_driver
224
+
225
+ @tclk_multiple.times do |i|
226
+ # 50% duty cycle if @tclk_multiple is even, otherwise slightly off
227
+
228
+ if tdo_to_be_captured
229
+ owner.pin(:tdo).state = @tdo_store_cycle == i ? :capture : :dont_care
230
+ end
231
+
232
+ if i < (@tclk_multiple + 1) / 2
233
+ # first half of cycle
234
+ owner.pin(:tclk).drive(tclk_val)
235
+ unless tdo_already_suspended
236
+ unless tdo_to_be_captured
237
+ if mask_tdo_half0
238
+ @tdo_suspended_by_driver = true
239
+ owner.pin(:tdo).suspend
240
+ else
241
+ @tdo_suspended_by_driver = false
242
+ owner.pin(:tdo).resume
243
+ end
244
+ end
245
+ end
246
+ else
247
+ # second half of cycle
248
+ owner.pin(:tclk).drive(1 - tclk_val)
249
+ unless tdo_already_suspended
250
+ unless tdo_to_be_captured
251
+ if mask_tdo_half1
252
+ @tdo_suspended_by_driver = true
253
+ owner.pin(:tdo).suspend
254
+ else
255
+ @tdo_suspended_by_driver = false
256
+ owner.pin(:tdo).resume
257
+ end
258
+ end
259
+ end
260
+ end
261
+ yield
262
+ end
263
+ if @tdo_suspended_by_driver
264
+ owner.pin(:tdo).resume
265
+ @tdo_suspended_by_driver = false
266
+ end
267
+ end
268
+
269
+ # Applies the given value to the TMS pin and then
270
+ # cycles the tester for one TCLK
271
+ #
272
+ # @param [Integer] val Value to drive on the TMS pin, 0 or 1
273
+ def tms!(val)
274
+ if @deferred_compare
275
+ @deferred_compare = nil
276
+ else
277
+ owner.pin(:tdo).dont_care
278
+ end
279
+
280
+ tclk_cycle do
281
+ owner.pin(:tms).drive!(val)
282
+ end
283
+ end
284
+
285
+ # Write the given value, register or bit collection to the data register.
286
+ # This is a self contained method that will take care of the TAP controller
287
+ # state transitions, exiting with the TAP controller in Run-Test/Idle.
288
+ #
289
+ # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
290
+ # Value to be written. If a reg/bit collection is supplied this can be pre-marked for overlay.
291
+ # @param [Hash] options Options to customize the operation
292
+ # @option options [Integer] :size The number of bits to write. This is optional
293
+ # when supplying a register or bit collection in which case the size will be derived from
294
+ # the number of bits supplied. If this option is supplied then it will override
295
+ # the size derived from the bits. If the size is greater than the number of bits
296
+ # provided then the additional space will be padded by 0s.
297
+ # @option options [String] :msg By default will not make any comments directly here. Can pass
298
+ # a msg to be written out prior to shifting data.
299
+ def write_dr(reg_or_val, options = {})
300
+ if Origen.tester.respond_to?(:write_dr)
301
+ Origen.tester.write_dr(reg_or_val, options)
302
+ else
303
+ if options[:msg]
304
+ cc "#{options[:msg]}\n"
305
+ end
306
+ shift_dr do
307
+ if options[:overlay] == true
308
+ $tester.label(options[:overlay_label], true) # apply global label
309
+ end
310
+ shift(reg_or_val, options)
311
+ end
312
+ end
313
+ end
314
+
315
+ # Read the given value, register or bit collection from the data register.
316
+ # This is a self contained method that will take care of the TAP controller
317
+ # state transitions, exiting with the TAP controller in Run-Test/Idle.
318
+ #
319
+ # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
320
+ # Value to be read. If a reg/bit collection is supplied this can be pre-marked for read in which
321
+ # case only the marked bits will be read and the vectors corresponding to the data from the non-read
322
+ # bits will be set to don't care. Similarly the bits can be pre-marked for store (capture) or
323
+ # overlay.
324
+ # @param [Hash] options Options to customize the operation
325
+ # @option options [Integer] :size The number of bits to read. This is optional
326
+ # when supplying a register or bit collection in which case the size will be derived from
327
+ # the number of bits supplied. If the size is supplied then it will override
328
+ # the size derived from the bits. If the size is greater than the number of bits
329
+ # provided then the additional space will be padded by don't care cycles.
330
+ # @option options [String] :msg By default will not make any comments directly here. Can pass
331
+ # a msg to be written out prior to shifting data.
332
+ def read_dr(reg_or_val, options = {})
333
+ if Origen.tester.respond_to?(:read_dr)
334
+ Origen.tester.read_dr(reg_or_val, options)
335
+ else
336
+ options = {
337
+ read: true
338
+ }.merge(options)
339
+ if options[:msg]
340
+ cc "#{options[:msg]}\n"
341
+ end
342
+ shift_dr do
343
+ if options[:overlay] == true
344
+ $tester.label(options[:overlay_label], true) # apply global label
345
+ end
346
+ shift(reg_or_val, options)
347
+ end
348
+ end
349
+ end
350
+
351
+ # Write the given value, register or bit collection to the instruction register.
352
+ # This is a self contained method that will take care of the TAP controller
353
+ # state transitions, exiting with the TAP controller in Run-Test/Idle.
354
+ #
355
+ # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
356
+ # Value to be written. If a reg/bit collection is supplied this can be pre-marked for overlay.
357
+ # @param [Hash] options Options to customize the operation
358
+ # @option options [Integer] :size The number of bits to write. This is optional
359
+ # when supplying a register or bit collection in which case the size will be derived from
360
+ # the number of bits supplied. If this option is supplied then it will override
361
+ # the size derived from the bits. If the size is greater than the number of bits
362
+ # provided then the additional space will be padded by 0s.
363
+ # @option options [Boolean] :force By default multiple calls to this method will not generate
364
+ # multiple writes. This is to allow wrapper algorithms to remain efficient yet not have to
365
+ # manually track the IR state (and in many cases this may be impossible due to multiple
366
+ # protocols using the same JTAG). To force a write regardless of what the driver thinks the IR
367
+ # contains set this to true.
368
+ # @option options [String] :msg By default will not make any comments directly here. Can pass
369
+ # a msg to be written out prior to shifting in IR data. Will not write comment only if write
370
+ # occurs.
371
+ def write_ir(reg_or_val, options = {})
372
+ if Origen.tester.respond_to?(:write_ir)
373
+ Origen.tester.write_ir(reg_or_val, options)
374
+ else
375
+ val = reg_or_val.respond_to?(:data) ? reg_or_val.data : reg_or_val
376
+ if val != ir_value || options[:force]
377
+ if options[:msg]
378
+ cc "#{options[:msg]}\n"
379
+ end
380
+ shift_ir do
381
+ shift(reg_or_val, options)
382
+ end
383
+ @ir_value = val
384
+ end
385
+ end
386
+ end
387
+
388
+ # Read the given value, register or bit collection from the instruction register.
389
+ # This is a self contained method that will take care of the TAP controller
390
+ # state transitions, exiting with the TAP controller in Run-Test/Idle.
391
+ #
392
+ # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
393
+ # Value to be read. If a reg/bit collection is supplied this can be pre-marked for read in which
394
+ # case only the marked bits will be read and the vectors corresponding to the data from the non-read
395
+ # bits will be set to don't care. Similarly the bits can be pre-marked for store (capture) or
396
+ # overlay.
397
+ # @param [Hash] options Options to customize the operation
398
+ # @option options [Integer] :size The number of bits to read. This is optional
399
+ # when supplying a register or bit collection in which case the size will be derived from
400
+ # the number of bits supplied. If the size is supplied then it will override
401
+ # the size derived from the bits. If the size is greater than the number of bits
402
+ # provided then the additional space will be padded by don't care cycles.
403
+ # @option options [String] :msg By default will not make any comments directly here. Can pass
404
+ # a msg to be written out prior to shifting data.
405
+ def read_ir(reg_or_val, options = {})
406
+ if Origen.tester.respond_to?(:read_ir)
407
+ Origen.tester.read_ir(reg_or_val, options)
408
+ else
409
+ options = {
410
+ read: true
411
+ }.merge(options)
412
+ if options[:msg]
413
+ cc "#{options[:msg]}\n"
414
+ end
415
+ shift_ir do
416
+ shift(reg_or_val, options)
417
+ end
418
+ end
419
+ end
420
+
421
+ private
422
+
423
+ def extract_size(reg_or_val, options = {})
424
+ size = options[:size]
425
+ unless size
426
+ if reg_or_val.is_a?(Fixnum) || !reg_or_val.respond_to?(:size)
427
+ fail 'When suppling a value to JTAG::Driver#shift you must supply a :size in the options!'
428
+ else
429
+ size = reg_or_val.size
430
+ end
431
+ end
432
+ size
433
+ end
434
+
435
+ # Validates that the parent object (the owner) has defined the necessary
436
+ # pins to implement the JTAG
437
+ def validate_pins
438
+ REQUIRED_PINS.each do |name|
439
+ owner.pin(name)
440
+ end
441
+ rescue
442
+ puts 'Missing JTAG pins!'
443
+ puts "In order to use the JTAG driver your #{owner.class} class must define"
444
+ puts 'the following pins (an alias is fine):'
445
+ puts REQUIRED_PINS
446
+ raise 'JTAG driver error!'
447
+ end
448
+ end
449
+ end