origen_jtag 0.17.2 → 0.18.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 +4 -4
- data/config/commands.rb +32 -0
- data/config/version.rb +2 -2
- data/lib/origen_jtag/driver.rb +48 -33
- data/lib/origen_jtag_dev/new_style.rb +107 -0
- data/pattern/two_port.rb +49 -0
- data/templates/web/index.md.erb +62 -0
- data/templates/web/index.md.erb~ +233 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f14027c16a759a2b51fa2b30d9f33cd7447f0a8b
|
4
|
+
data.tar.gz: 8e4c8ebb8dbc3fa97c1955a395ba478b4f2f20a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 874db41442a09c7c2ef8a9b6be7fcd2bdfe04da00e6a647af268da54bda9d41b5c69d609e639b0928bf4e0acb8b14eb1304ec734fffb2ac05070bfb13e5ed573
|
7
|
+
data.tar.gz: 2af49cdfdc543a9e1fa0a105dbb7b674aba124034aad6bf1398a89393cd8756f58befc8a247b9bca458a0422e85baaa0c56b942a7870412d16dc64df5967c5b2
|
data/config/commands.rb
CHANGED
@@ -55,6 +55,38 @@ when "examples", "test"
|
|
55
55
|
ARGV = %w(full_reg_ovly_cap -t debug_RH4 -e uflex.rb -r approved)
|
56
56
|
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
57
57
|
|
58
|
+
# Pattern generator tests -- confirm sub_block instanced jtag gives same results
|
59
|
+
ARGV = %w(jtag_workout -t new_style_RH1 -e v93k -r approved)
|
60
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
61
|
+
ARGV = %w(jtag_workout -t new_style_RH1 -e j750.rb -r approved)
|
62
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
63
|
+
ARGV = %w(jtag_workout -t new_style_RL1 -e j750.rb -r approved)
|
64
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
65
|
+
|
66
|
+
ARGV = %w(jtag_workout -t new_style_RH2.rb -e j750.rb -r approved)
|
67
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
68
|
+
ARGV = %w(jtag_workout -t new_style_RH2_1.rb -e j750.rb -r approved)
|
69
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
70
|
+
|
71
|
+
ARGV = %w(jtag_workout -t new_style_RH4 -e v93k -r approved)
|
72
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
73
|
+
ARGV = %w(jtag_workout -t new_style_RH4 -e j750.rb -r approved)
|
74
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
75
|
+
ARGV = %w(jtag_workout -t new_style_RL4 -e j750.rb -r approved)
|
76
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
77
|
+
|
78
|
+
ARGV = %w(rww_test -t new_style_RH4 -e j750.rb -r approved)
|
79
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
80
|
+
|
81
|
+
ARGV = %w(global_label_test -t new_style_RH1 -e j750.rb -r approved)
|
82
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
83
|
+
|
84
|
+
ARGV = %w(full_reg_ovly_cap -t new_style_RH4 -e uflex.rb -r approved)
|
85
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
86
|
+
|
87
|
+
ARGV = %w(two_port -t new_2port_RH4 -e j750.rb -r approved)
|
88
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
89
|
+
|
58
90
|
if Origen.app.stats.changed_files == 0 &&
|
59
91
|
Origen.app.stats.new_files == 0 &&
|
60
92
|
Origen.app.stats.changed_patterns == 0 &&
|
data/config/version.rb
CHANGED
data/lib/origen_jtag/driver.rb
CHANGED
@@ -13,8 +13,9 @@ module OrigenJTAG
|
|
13
13
|
class Driver
|
14
14
|
REQUIRED_PINS = [:tclk, :tdi, :tdo, :tms]
|
15
15
|
|
16
|
+
include Origen::Model
|
16
17
|
include TAPController
|
17
|
-
include Origen::Registers
|
18
|
+
# include Origen::Registers
|
18
19
|
|
19
20
|
# Returns the object that instantiated the JTAG
|
20
21
|
attr_reader :owner
|
@@ -31,8 +32,13 @@ module OrigenJTAG
|
|
31
32
|
attr_accessor :log_state_changes
|
32
33
|
|
33
34
|
def initialize(owner, options = {})
|
34
|
-
|
35
|
-
|
35
|
+
if owner.is_a?(Hash)
|
36
|
+
@owner = parent
|
37
|
+
options = owner
|
38
|
+
else
|
39
|
+
@owner = owner
|
40
|
+
end
|
41
|
+
validate_pins(options)
|
36
42
|
|
37
43
|
# The parent can configure JTAG settings by defining this constant
|
38
44
|
if defined?(owner.class::JTAG_CONFIG)
|
@@ -145,27 +151,27 @@ module OrigenJTAG
|
|
145
151
|
# Set up pin actions for bit transaction (tclk cycle)
|
146
152
|
|
147
153
|
# TDI
|
148
|
-
|
154
|
+
@tdi_pin.drive(tdi_reg[i])
|
149
155
|
|
150
156
|
# TDO
|
151
|
-
|
157
|
+
@tdo_pin.dont_care # default setting
|
152
158
|
if tdo_reg[i]
|
153
159
|
if tdo_reg[i].is_to_be_stored? # store
|
154
160
|
store_tdo_this_tclk = true
|
155
|
-
|
161
|
+
@tdo_pin.dont_care if Origen.tester.j750?
|
156
162
|
elsif tdo_reg[i].is_to_be_read? # compare/assert
|
157
|
-
|
163
|
+
@tdo_pin.assert(tdo_reg[i])
|
158
164
|
end
|
159
165
|
end
|
160
166
|
|
161
167
|
# TMS
|
162
|
-
|
168
|
+
@tms_pin.drive(0)
|
163
169
|
|
164
170
|
# let tester handle overlay if implemented
|
165
171
|
overlay_options = {}
|
166
172
|
if tester.respond_to?(:source_memory)
|
167
173
|
if ovl_reg[i] && ovl_reg[i].has_overlay? && !Origen.mode.simulation?
|
168
|
-
overlay_options[:pins] =
|
174
|
+
overlay_options[:pins] = @tdi_pin
|
169
175
|
if global_ovl
|
170
176
|
overlay_options[:overlay_str] = global_ovl
|
171
177
|
else
|
@@ -179,8 +185,8 @@ module OrigenJTAG
|
|
179
185
|
end
|
180
186
|
end
|
181
187
|
tester_subr_overlay = !(options[:no_subr] || global_ovl) && tester.overlay_style == :subroutine
|
182
|
-
|
183
|
-
|
188
|
+
@tdi_pin.drive(0) if tester_subr_overlay
|
189
|
+
@tdo_pin.assert(tdo_reg[i]) if options[:read] unless tester_subr_overlay
|
184
190
|
# Force the last bit to be shifted from this method if overlay requested on the last bit
|
185
191
|
options[:cycle_last] = true if i == size - 1
|
186
192
|
end
|
@@ -193,9 +199,9 @@ module OrigenJTAG
|
|
193
199
|
$tester.label(ovl_reg[i].overlay_str)
|
194
200
|
last_overlay_label = ovl_reg[i].overlay_str
|
195
201
|
end
|
196
|
-
|
202
|
+
@tdo_pin.assert(tdo_reg[i]) if options[:read]
|
197
203
|
else
|
198
|
-
|
204
|
+
@tdi_pin.drive(0)
|
199
205
|
call_subroutine = ovl_reg[i].overlay_str
|
200
206
|
end
|
201
207
|
end
|
@@ -219,13 +225,13 @@ module OrigenJTAG
|
|
219
225
|
if i != size - 1 || options[:cycle_last]
|
220
226
|
if i == size - 1 && options[:includes_last_bit]
|
221
227
|
unless tester_subr_overlay
|
222
|
-
|
228
|
+
@tms_pin.drive(1)
|
223
229
|
@last_data_vector_shifted = true
|
224
230
|
end
|
225
231
|
end
|
226
232
|
tclk_cycle do
|
227
233
|
if store_tdo_this_tclk && @next_data_vector_to_be_stored
|
228
|
-
Origen.tester.store_next_cycle(
|
234
|
+
Origen.tester.store_next_cycle(@tdo_pin)
|
229
235
|
end
|
230
236
|
if overlay_options[:pins].nil?
|
231
237
|
Origen.tester.cycle
|
@@ -234,7 +240,7 @@ module OrigenJTAG
|
|
234
240
|
overlay_options[:change_data] = false # data change only on first cycle if overlay
|
235
241
|
end
|
236
242
|
end
|
237
|
-
|
243
|
+
@tdo_pin.dont_care
|
238
244
|
else
|
239
245
|
@deferred_compare = true
|
240
246
|
@deferred_store = true if store_tdo_this_tclk
|
@@ -272,11 +278,11 @@ module OrigenJTAG
|
|
272
278
|
((@tclk_format == :rh) && (@tdo_strobe == :tclk_low) && (@tclk_multiple > 1))
|
273
279
|
|
274
280
|
# determine whether TDO is set to capture for this TCLK cycle
|
275
|
-
tdo_to_be_captured =
|
281
|
+
tdo_to_be_captured = @tdo_pin.to_be_captured?
|
276
282
|
|
277
283
|
# If TDO is already suspended (by an application) then don't do the
|
278
284
|
# suspends below since the resume will clear the application's suspend
|
279
|
-
tdo_already_suspended =
|
285
|
+
tdo_already_suspended = @tdo_pin.suspended? && !@tdo_suspended_by_driver
|
280
286
|
|
281
287
|
@tclk_multiple.times do |i|
|
282
288
|
# 50% duty cycle if @tclk_multiple is even, otherwise slightly off
|
@@ -285,29 +291,29 @@ module OrigenJTAG
|
|
285
291
|
|
286
292
|
if i < (@tclk_multiple + 1) / 2
|
287
293
|
# first half of cycle
|
288
|
-
|
294
|
+
@tck_pin.drive(tclk_val)
|
289
295
|
unless tdo_already_suspended
|
290
296
|
unless tdo_to_be_captured
|
291
297
|
if mask_tdo_half0
|
292
298
|
@tdo_suspended_by_driver = true
|
293
|
-
|
299
|
+
@tdo_pin.suspend
|
294
300
|
else
|
295
301
|
@tdo_suspended_by_driver = false
|
296
|
-
|
302
|
+
@tdo_pin.resume
|
297
303
|
end
|
298
304
|
end
|
299
305
|
end
|
300
306
|
else
|
301
307
|
# second half of cycle
|
302
|
-
|
308
|
+
@tck_pin.drive(1 - tclk_val)
|
303
309
|
unless tdo_already_suspended
|
304
310
|
unless tdo_to_be_captured
|
305
311
|
if mask_tdo_half1
|
306
312
|
@tdo_suspended_by_driver = true
|
307
|
-
|
313
|
+
@tdo_pin.suspend
|
308
314
|
else
|
309
315
|
@tdo_suspended_by_driver = false
|
310
|
-
|
316
|
+
@tdo_pin.resume
|
311
317
|
end
|
312
318
|
end
|
313
319
|
end
|
@@ -315,7 +321,7 @@ module OrigenJTAG
|
|
315
321
|
yield
|
316
322
|
end
|
317
323
|
if @tdo_suspended_by_driver
|
318
|
-
|
324
|
+
@tdo_pin.resume
|
319
325
|
@tdo_suspended_by_driver = false
|
320
326
|
end
|
321
327
|
end
|
@@ -328,7 +334,7 @@ module OrigenJTAG
|
|
328
334
|
if @deferred_compare
|
329
335
|
@deferred_compare = nil
|
330
336
|
else
|
331
|
-
|
337
|
+
@tdo_pin.dont_care
|
332
338
|
end
|
333
339
|
|
334
340
|
if @deferred_store
|
@@ -341,9 +347,9 @@ module OrigenJTAG
|
|
341
347
|
|
342
348
|
tclk_cycle do
|
343
349
|
if store_tdo_this_tclk && @next_data_vector_to_be_stored
|
344
|
-
Origen.tester.store_next_cycle(
|
350
|
+
Origen.tester.store_next_cycle(@tdo_pin)
|
345
351
|
end
|
346
|
-
|
352
|
+
@tms_pin.drive!(val)
|
347
353
|
end
|
348
354
|
end
|
349
355
|
|
@@ -585,15 +591,24 @@ module OrigenJTAG
|
|
585
591
|
|
586
592
|
# Validates that the parent object (the owner) has defined the necessary
|
587
593
|
# pins to implement the JTAG
|
588
|
-
def validate_pins
|
589
|
-
|
590
|
-
|
591
|
-
|
594
|
+
def validate_pins(options)
|
595
|
+
@tck_pin = options[:tck_pin] if options[:tck_pin]
|
596
|
+
@tdi_pin = options[:tdi_pin] if options[:tdi_pin]
|
597
|
+
@tdo_pin = options[:tdo_pin] if options[:tdo_pin]
|
598
|
+
@tms_pin = options[:tms_pin] if options[:tms_pin]
|
599
|
+
|
600
|
+
@tck_pin = @owner.pin(:tclk) if @tck_pin.nil?
|
601
|
+
@tdi_pin = @owner.pin(:tdi) if @tdi_pin.nil?
|
602
|
+
@tdo_pin = @owner.pin(:tdo) if @tdo_pin.nil?
|
603
|
+
@tms_pin = @owner.pin(:tms) if @tms_pin.nil?
|
592
604
|
rescue
|
593
605
|
puts 'Missing JTAG pins!'
|
594
|
-
puts "In order to use the JTAG driver your #{owner.class} class must define"
|
606
|
+
puts "In order to use the JTAG driver your #{owner.class} class must either define"
|
595
607
|
puts 'the following pins (an alias is fine):'
|
596
608
|
puts REQUIRED_PINS
|
609
|
+
puts '-- or --'
|
610
|
+
puts 'Pass the pins in the initialization options:'
|
611
|
+
puts "sub_block :jtag, class_name: 'OrigenJTAG::Driver', tck_pin: dut.pin(:tclk), tdi_pin: dut.pin(:tdi), tdo_pin: dut.pin(:tdo), tms_pin: dut.pin(:tms)"
|
597
612
|
raise 'JTAG driver error!'
|
598
613
|
end
|
599
614
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module OrigenJTAGDev
|
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 NewStyle
|
8
|
+
include Origen::TopLevel
|
9
|
+
|
10
|
+
attr_reader :jtag_config
|
11
|
+
|
12
|
+
def initialize(options = {})
|
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
|
+
@jtag_config[:tclk_format] = options[:tclk_format] if options[:tclk_format]
|
22
|
+
@jtag_config[:tclk_multiple] = options[:tclk_multiple] if options[:tclk_multiple]
|
23
|
+
@jtag_config[:tdo_strobe] = options[:tdo_strobe] if options[:tdo_strobe]
|
24
|
+
@jtag_config[:tdo_store_cycle] = options[:tdo_store_cycle] if options[:tdo_store_cycle]
|
25
|
+
@jtag_config[:init_state] = options[:init_state] if options[:init_state]
|
26
|
+
|
27
|
+
instantiate_registers(options)
|
28
|
+
instantiate_pins(options)
|
29
|
+
sub_block :jtag, { class_name: 'OrigenJTAG::Driver' }.merge(@jtag_config)
|
30
|
+
if options[:extra_port]
|
31
|
+
sub_block :jtag2, { class_name: 'OrigenJTAG::Driver', tck_pin: pin(:tck_2), tdi_pin: pin(:tdi_2), tdo_pin: pin(:tdo_2), tms_pin: pin(:tms_2) }.merge(@jtag_config)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def instantiate_registers(options = {})
|
36
|
+
reg :test16, 0x0012, size: 16 do |reg|
|
37
|
+
reg.bit 15..8, :bus
|
38
|
+
reg.bit 0, :bit
|
39
|
+
end
|
40
|
+
|
41
|
+
reg :test32, 0x0014, size: 32 do |reg|
|
42
|
+
reg.bit 31..16, :bus
|
43
|
+
reg.bit 0, :bit
|
44
|
+
end
|
45
|
+
|
46
|
+
reg :full16, 0x0012, size: 16 do |reg|
|
47
|
+
reg.bit 15..0, :data
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def instantiate_pins(options = {})
|
52
|
+
if options[:invalid_pins]
|
53
|
+
add_pin :tck
|
54
|
+
else
|
55
|
+
add_pin :tclk
|
56
|
+
end
|
57
|
+
add_pin :tdi
|
58
|
+
add_pin :tdo
|
59
|
+
add_pin :tms
|
60
|
+
|
61
|
+
if options[:extra_port]
|
62
|
+
add_pin :tck_2
|
63
|
+
add_pin :tdi_2
|
64
|
+
add_pin :tdo_2
|
65
|
+
add_pin :tms_2
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def startup(options = {})
|
70
|
+
tester.set_timeset('nvmbist', 40)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Getter for top-level tclk_format setting
|
74
|
+
def tclk_format
|
75
|
+
@jtag_config[:tclk_format]
|
76
|
+
end
|
77
|
+
|
78
|
+
# Getter for top-level tclk_multiple setting
|
79
|
+
def tclk_multiple
|
80
|
+
@jtag_config[:tclk_multiple]
|
81
|
+
end
|
82
|
+
|
83
|
+
# Getter for top-level tdo_strobe setting
|
84
|
+
def tdo_strobe
|
85
|
+
@jtag_config[:tdo_strobe]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Getter for top-level tdo_store_cycle setting
|
89
|
+
def tdo_store_cycle
|
90
|
+
@jtag_config[:tdo_store_cycle]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Getter for top-level init_state setting
|
94
|
+
def init_state
|
95
|
+
@jtag_config[:init_state]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Wouldn't want to do this in reality, but allows some flexibility duing gem testing
|
99
|
+
def update_jtag_config(cfg, val)
|
100
|
+
if @jtag_config.key?(cfg)
|
101
|
+
@jtag_config[cfg] = val
|
102
|
+
else
|
103
|
+
fail "#{cfg} not a part of @jtag_config"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/pattern/two_port.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
Pattern.create(options = { name: 'two_port' }) do
|
3
|
+
|
4
|
+
ss 'test using first jtag port'
|
5
|
+
jtag = $dut.jtag
|
6
|
+
reg = $dut.reg(:full16)
|
7
|
+
|
8
|
+
cc 'TDO should be HLHL_LHLH_HLHL_LHLH'
|
9
|
+
jtag.write_dr 0xFFFF, size: 16, shift_out_data: 0xA5A5
|
10
|
+
|
11
|
+
cc 'TDO should be XXXX_XXXX_HHHH_HHHH'
|
12
|
+
reg.write(0xFFFF)
|
13
|
+
reg.bits[0..7].read
|
14
|
+
jtag.write_dr 0xFFFF, size: 16, shift_out_data: reg
|
15
|
+
|
16
|
+
|
17
|
+
cc 'TDO should be HLHL_LHLH_HLHL_LHLH'
|
18
|
+
reg.write(0xFFFF)
|
19
|
+
jtag.write_dr reg, shift_out_data: 0xA5A5
|
20
|
+
|
21
|
+
cc 'TDO should be XXXX_XXXX_HHHH_HHHH'
|
22
|
+
reg.write(0xFFFF)
|
23
|
+
reg2 = reg.dup
|
24
|
+
reg2.bits[0..7].read
|
25
|
+
jtag.write_dr reg, size: 16, shift_out_data: reg2
|
26
|
+
|
27
|
+
|
28
|
+
ss 'test using second jtag port'
|
29
|
+
jtag = $dut.jtag2
|
30
|
+
|
31
|
+
cc 'TDO should be HLHL_LHLH_HLHL_LHLH'
|
32
|
+
jtag.write_dr 0xFFFF, size: 16, shift_out_data: 0xA5A5
|
33
|
+
|
34
|
+
cc 'TDO should be XXXX_XXXX_HHHH_HHHH'
|
35
|
+
reg.write(0xFFFF)
|
36
|
+
reg.bits[0..7].read
|
37
|
+
jtag.write_dr 0xFFFF, size: 16, shift_out_data: reg
|
38
|
+
|
39
|
+
|
40
|
+
cc 'TDO should be HLHL_LHLH_HLHL_LHLH'
|
41
|
+
reg.write(0xFFFF)
|
42
|
+
jtag.write_dr reg, shift_out_data: 0xA5A5
|
43
|
+
|
44
|
+
cc 'TDO should be XXXX_XXXX_HHHH_HHHH'
|
45
|
+
reg.write(0xFFFF)
|
46
|
+
reg2 = reg.dup
|
47
|
+
reg2.bits[0..7].read
|
48
|
+
jtag.write_dr reg, size: 16, shift_out_data: reg2
|
49
|
+
end
|
data/templates/web/index.md.erb
CHANGED
@@ -30,6 +30,66 @@ __NOTE:__ You will also need to include <code>require 'origen_jtag'</code> somew
|
|
30
30
|
|
31
31
|
### How To Use
|
32
32
|
|
33
|
+
#### New Style Example
|
34
|
+
|
35
|
+
The driver no longer requires specific pin names (or aliases), supports sub_block instantiation and DUTs with multiple JTAG ports.
|
36
|
+
You are no longer required to include "OrigenJTAG" in your DUT class.
|
37
|
+
|
38
|
+
Here is an example integration:
|
39
|
+
|
40
|
+
~~~ruby
|
41
|
+
class Pioneer
|
42
|
+
|
43
|
+
include Origen::TopLevel
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
add_pin :tclk
|
47
|
+
add_pin :tdi
|
48
|
+
add_pin :tdo
|
49
|
+
add_pin :tms
|
50
|
+
|
51
|
+
add_pin :tck2
|
52
|
+
add_pin :tdi2
|
53
|
+
add_pin :tdo2
|
54
|
+
add_pin :tms2
|
55
|
+
|
56
|
+
|
57
|
+
# In this first instance TCK covers 4 tester cycles,
|
58
|
+
# 2 high then 2 low for each effective TCK pulse.
|
59
|
+
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
|
60
|
+
|
61
|
+
# several pluggins use dut.jtag, your default port driver should be named jtag for compatibility
|
62
|
+
sub_block :jtag, class_name: 'OrigenJTAG::Driver',
|
63
|
+
tclk_format: :rl,
|
64
|
+
tclk_multiple: 4,
|
65
|
+
tdo_strobe: :tclk_high,
|
66
|
+
tdo_store_cycle: 3,
|
67
|
+
tck_pin: pin(:tclk),
|
68
|
+
tdi_pin: pin(:tdi),
|
69
|
+
tdo_pin: pin(:tdo),
|
70
|
+
tms_pin: pin(:tms)
|
71
|
+
|
72
|
+
# create a driver for a 2nd port like this
|
73
|
+
# note different configuration settings can be used
|
74
|
+
sub_block :jtag_port2, class_name: 'OrigenJTAG::Driver',
|
75
|
+
tclk_format: :rh,
|
76
|
+
tclk_multiple: 2,
|
77
|
+
tdo_strobe: :tclk_high,
|
78
|
+
tdo_store_cycle: 1,
|
79
|
+
tck_pin: pin(:tck2),
|
80
|
+
tdi_pin: pin(:tdi2),
|
81
|
+
tdo_pin: pin(:tdo2),
|
82
|
+
tms_pin: pin(:tms2)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
dut.jtag # => jtag driver for the first port (tclk, tdi, tdo, tms)
|
88
|
+
dut.jtag_port2 # => jtag driver for the second port (tck2, tdi2, tdo2, tms2)
|
89
|
+
~~~
|
90
|
+
|
91
|
+
#### Legacy Example
|
92
|
+
|
33
93
|
Include the <code>OrigenJTAG</code> module to add a JTAG driver to your class and
|
34
94
|
define the required pins.
|
35
95
|
Normally the pins would be an alias to existing DUT pins and therefore the
|
@@ -75,6 +135,8 @@ end
|
|
75
135
|
Pioneer.new.jtag # => An instance of OrigenJTAG::Driver
|
76
136
|
~~~
|
77
137
|
|
138
|
+
#### APIs
|
139
|
+
|
78
140
|
Two APIs are provided, the primary one provides canned methods to read and
|
79
141
|
write to the IR and DR registers.
|
80
142
|
|
@@ -0,0 +1,233 @@
|
|
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
|
+
#### New Style Example
|
34
|
+
|
35
|
+
The driver no longer requires specific pin names (or aliases), supports sub_block instantiation and DUTs with multiple JTAG ports.
|
36
|
+
You are no longer required to include "OrigenJTAG" in your DUT class.
|
37
|
+
|
38
|
+
Here is an example integration:
|
39
|
+
|
40
|
+
~~~ruby
|
41
|
+
class Pioneer
|
42
|
+
|
43
|
+
include Origen::TopLevel
|
44
|
+
|
45
|
+
# TCK covers 4 tester cycles, 2 high then 2 low for each effective TCK pulse
|
46
|
+
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
|
47
|
+
JTAG_CONFIG = {
|
48
|
+
:tclk_format => :rl,
|
49
|
+
:tclk_multiple => 4,
|
50
|
+
:tdo_strobe => :tclk_high,
|
51
|
+
:tdo_store_cycle => 3,
|
52
|
+
}
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
add_pin :tclk
|
56
|
+
add_pin :tdi
|
57
|
+
add_pin :tdo
|
58
|
+
add_pin :tms
|
59
|
+
|
60
|
+
add_pin :tck2
|
61
|
+
add_pin :tdi2
|
62
|
+
add_pin :tdo2
|
63
|
+
add_pin :tms2
|
64
|
+
|
65
|
+
|
66
|
+
# In this first instance TCK covers 4 tester cycles,
|
67
|
+
# 2 high then 2 low for each effective TCK pulse.
|
68
|
+
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
|
69
|
+
|
70
|
+
# several pluggins use dut.jtag, your default port driver should be named jtag for compatibility
|
71
|
+
sub_block :jtag, class_name: 'OrigenJTAG::Driver',
|
72
|
+
tclk_format: :rl,
|
73
|
+
tclk_multiple: 4,
|
74
|
+
tdo_strobe: :tclk_high,
|
75
|
+
tdo_store_cycle: 3,
|
76
|
+
tck_pin: pin(:tclk),
|
77
|
+
tdi_pin: pin(:tdi),
|
78
|
+
tdo_pin: pin(:tdo),
|
79
|
+
tms_pin: pin(:tms)
|
80
|
+
|
81
|
+
# create a driver for a 2nd port like this
|
82
|
+
# note different configuration settings can be used
|
83
|
+
sub_block :jtag_port2, class_name: 'OrigenJTAG::Driver',
|
84
|
+
tclk_format: :rh,
|
85
|
+
tclk_multiple: 2,
|
86
|
+
tdo_strobe: :tclk_high,
|
87
|
+
tdo_store_cycle: 1,
|
88
|
+
tck_pin: pin(:tck2),
|
89
|
+
tdi_pin: pin(:tdi2),
|
90
|
+
tdo_pin: pin(:tdo2),
|
91
|
+
tms_pin: pin(:tms2)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
dut.jtag # => jtag driver for the first port (tclk, tdi, tdo, tms)
|
97
|
+
dut.jtag_port2 # => jtag driver for the second port (tck2, tdi2, tdo2, tms2)
|
98
|
+
~~~
|
99
|
+
|
100
|
+
#### Legacy Example
|
101
|
+
|
102
|
+
Include the <code>OrigenJTAG</code> module to add a JTAG driver to your class and
|
103
|
+
define the required pins.
|
104
|
+
Normally the pins would be an alias to existing DUT pins and therefore the
|
105
|
+
JTAG driver module cannot assume them.
|
106
|
+
|
107
|
+
Including the module adds a <code>jtag</code> method which will return an instance of
|
108
|
+
[<code>OrigenJTAG::Driver</code>](<%= path "api/OrigenJTAG/Driver.html" %>).
|
109
|
+
|
110
|
+
The following attributes can be customized by defining a <code>JTAG_CONFIG</code>
|
111
|
+
hash:
|
112
|
+
|
113
|
+
* **tclk_format** - TCLK timing format, Return High (:rh) or Return Low (:rl). Default is :rh.
|
114
|
+
* **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.
|
115
|
+
* **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.
|
116
|
+
* **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
|
117
|
+
|
118
|
+
Here is an example integration:
|
119
|
+
|
120
|
+
~~~ruby
|
121
|
+
class Pioneer
|
122
|
+
|
123
|
+
include OrigenJTAG
|
124
|
+
include Origen::Pins
|
125
|
+
|
126
|
+
# TCK covers 4 tester cycles, 2 high then 2 low for each effective TCK pulse
|
127
|
+
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
|
128
|
+
JTAG_CONFIG = {
|
129
|
+
:tclk_format => :rl,
|
130
|
+
:tclk_multiple => 4,
|
131
|
+
:tdo_strobe => :tclk_high,
|
132
|
+
:tdo_store_cycle => 3,
|
133
|
+
}
|
134
|
+
|
135
|
+
def initialize
|
136
|
+
add_pin :tclk
|
137
|
+
add_pin :tdi
|
138
|
+
add_pin :tdo
|
139
|
+
add_pin :tms
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
Pioneer.new.jtag # => An instance of OrigenJTAG::Driver
|
145
|
+
~~~
|
146
|
+
|
147
|
+
#### APIs
|
148
|
+
|
149
|
+
Two APIs are provided, the primary one provides canned methods to read and
|
150
|
+
write to the IR and DR registers.
|
151
|
+
|
152
|
+
These accept either an absolute data value or an Origen register/bit collection.
|
153
|
+
|
154
|
+
~~~ruby
|
155
|
+
jtag.write_dr 0x1234, :size => 16
|
156
|
+
|
157
|
+
# The size option is not required when a register is supplied
|
158
|
+
jtag.write_dr $dut.reg(:clkdiv)
|
159
|
+
|
160
|
+
# Although it can still be added if the register is not the full data width
|
161
|
+
jtag.write_dr $dut.reg(:clkdiv), :size => 32
|
162
|
+
|
163
|
+
# A rich read method is available which supports bit-level read, store and overlay operations
|
164
|
+
$dut.reg(:clkdiv).bits(:div).read(0x55)
|
165
|
+
jtag.read $dut.reg(:clkdiv)
|
166
|
+
|
167
|
+
# In cases where both shift in (TDI) and shift out data (TDO) are critical, (e.g. compare shift
|
168
|
+
# out data on a write, or shfit in specific data on a read) the shift_in_data and
|
169
|
+
# shift_out_data options can be specified. By default, TDO will be dont care on writes
|
170
|
+
# and TDI will be 0 on reads.
|
171
|
+
jtag.write_dr $dut.reg(:clkdiv), :shift_out_data => 0x4321
|
172
|
+
jtag.read_dr $udt.reg(:clkdiv), :shift_in_data => 0x5678
|
173
|
+
|
174
|
+
# Similar methods exist for the instruction register
|
175
|
+
jtag.write_ir 0x1F, :size => 5
|
176
|
+
jtag.read_ir 0x1F, :size => 5
|
177
|
+
~~~
|
178
|
+
|
179
|
+
A secondary API provides low level control of the TAP Controller state machine.
|
180
|
+
|
181
|
+
~~~ruby
|
182
|
+
jtag.pause_dr do
|
183
|
+
jtag.shift_dr do
|
184
|
+
# The shift method accepts the same arguments as the canned read/write methods
|
185
|
+
jtag.shift 0x55, :size => 32
|
186
|
+
end
|
187
|
+
end
|
188
|
+
~~~
|
189
|
+
|
190
|
+
See the [<code>OrigenJTAG::Driver</code>](<%= path "api/OrigenJTAG/Driver.html" %>) and
|
191
|
+
[<code>OrigenJTAG::TAPController</code>](<%= path "api/OrigenJTAG/TAPController.html" %>)
|
192
|
+
APIs for more details about the available driver methods.
|
193
|
+
|
194
|
+
Any model/controller within a target runtime environment can listen out for JTAG state
|
195
|
+
changes by implementing the following callback handler:
|
196
|
+
|
197
|
+
~~~ruby
|
198
|
+
def on_jtag_state_change(new_state)
|
199
|
+
if new_state == :update_dr
|
200
|
+
# Do something every time we enter this state
|
201
|
+
end
|
202
|
+
end
|
203
|
+
~~~
|
204
|
+
|
205
|
+
|
206
|
+
### How To Setup a Development Environment
|
207
|
+
|
208
|
+
[Clone the repository from Github](https://github.com/Origen-SDK/origen_jtag).
|
209
|
+
|
210
|
+
An instance of the OrigenJTAG driver is hooked up to a dummy DUT
|
211
|
+
object for use in the console:
|
212
|
+
|
213
|
+
~~~
|
214
|
+
origen i
|
215
|
+
|
216
|
+
> $dut.jtag
|
217
|
+
=> #<OrigenJTAG::Driver:0x0000001ee48e78>
|
218
|
+
~~~
|
219
|
+
|
220
|
+
Follow the instructions here if you want to make a 3rd party app
|
221
|
+
workspace use your development copy of the OrigenJTAG plugin:
|
222
|
+
[Setting up a Plugin Development Environment](http://origen-sdk.org/origen/latest/guides/plugins)
|
223
|
+
|
224
|
+
This plugin also contains a test suite, makes sure this passes before committing
|
225
|
+
any changes!
|
226
|
+
|
227
|
+
~~~
|
228
|
+
origen examples
|
229
|
+
~~~
|
230
|
+
|
231
|
+
<%= disqus_comments %>
|
232
|
+
|
233
|
+
% end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen_jtag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -59,12 +59,15 @@ files:
|
|
59
59
|
- lib/origen_jtag.rb
|
60
60
|
- lib/origen_jtag/driver.rb
|
61
61
|
- lib/origen_jtag/tap_controller.rb
|
62
|
+
- lib/origen_jtag_dev/new_style.rb
|
62
63
|
- lib/origen_jtag_dev/top_level.rb
|
63
64
|
- pattern/full_reg_ovly_cap.rb
|
64
65
|
- pattern/global_label_test.rb
|
65
66
|
- pattern/jtag_workout.rb
|
66
67
|
- pattern/rww_test.rb
|
68
|
+
- pattern/two_port.rb
|
67
69
|
- templates/web/index.md.erb
|
70
|
+
- templates/web/index.md.erb~
|
68
71
|
- templates/web/layouts/_basic.html.erb
|
69
72
|
- templates/web/partials/_navbar.html.erb
|
70
73
|
- templates/web/release_notes.md.erb
|