origen_link 0.1.0 → 0.1.2
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/version.rb +1 -1
- data/lib/origen_link/capture_support.rb +94 -0
- data/lib/origen_link/configuration_commands.rb +84 -0
- data/lib/origen_link/server/sequencer.rb +14 -6
- data/lib/origen_link/server_com.rb +2 -0
- data/lib/origen_link/test/top_level_controller.rb +11 -11
- data/lib/origen_link/vector_based.rb +81 -177
- data/pattern/jtag_100_operations.rb +1 -1
- data/pattern/jtag_capture_id.rb +23 -0
- data/pattern/transaction_test.rb +19 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b819630a6b626e6c330114c40f70108f7850657
|
4
|
+
data.tar.gz: 51a6ddf9796af5b1569c3b61a9e8f8d2b3c955c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 379e3b256c9becd833c2d2fd76fcfba2c3b1b7c3f4922986e6ca8523eb0bda24919366189c06695577aea979be102a7a2a0fb84e4b8f55973d22cd14927b6117
|
7
|
+
data.tar.gz: 222fdaf6916110972cacb9a25f1f2cf0b60ba8406770f8518f8777b00e771c1755eff011ecc46465c4dac7f5035e5ff19eb57ed8dd1a4acf60a423d4db174941
|
data/config/version.rb
CHANGED
@@ -0,0 +1,94 @@
|
|
1
|
+
module OrigenLink
|
2
|
+
module CaptureSupport
|
3
|
+
# Capture a vector
|
4
|
+
#
|
5
|
+
# This method applies a store vector request to the previous vector, note that is does
|
6
|
+
# not actually generate a new vector.
|
7
|
+
#
|
8
|
+
# The captured data is added to the captured_data array.
|
9
|
+
#
|
10
|
+
# This method is indended to be used by pin drivers, see the #capture method for the application
|
11
|
+
# level API.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# $tester.cycle # This is the vector you want to capture
|
15
|
+
# $tester.store # This applies the store request
|
16
|
+
def store(*pins)
|
17
|
+
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
18
|
+
fail 'The store is not implemented yet on Link'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Capture the next vector generated
|
22
|
+
#
|
23
|
+
# This method applies a store request to the next vector to be generated,
|
24
|
+
# note that is does not actually generate a new vector.
|
25
|
+
#
|
26
|
+
# The captured data is added to the captured_data array.
|
27
|
+
#
|
28
|
+
# This method is indended to be used by pin drivers, see the #capture method for the application
|
29
|
+
# level API.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# tester.store_next_cycle
|
33
|
+
# tester.cycle # This is the vector that will be captured
|
34
|
+
def store_next_cycle(*pins)
|
35
|
+
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
36
|
+
flush_vector
|
37
|
+
@store_pins = pins
|
38
|
+
end
|
39
|
+
|
40
|
+
# Capture any store data within the given block, return it and then internally clear the tester's
|
41
|
+
# capture memory.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
#
|
45
|
+
# v = tester.capture do
|
46
|
+
# my_reg.store!
|
47
|
+
# end
|
48
|
+
# v # => Data value read from my_reg on the DUT
|
49
|
+
def capture(*args)
|
50
|
+
if block_given?
|
51
|
+
yield
|
52
|
+
synchronize
|
53
|
+
d = @captured_data
|
54
|
+
@captured_data = []
|
55
|
+
d
|
56
|
+
else
|
57
|
+
# On other testers capture is an alias of store
|
58
|
+
store(*args)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def capture_data(response)
|
65
|
+
if @store_pins.size > 1
|
66
|
+
fail 'Data capture on multiple pins is not implemented yet'
|
67
|
+
else
|
68
|
+
captured_data[0] ||= 0
|
69
|
+
captured_data[0] = (captured_data[0] << 1) | extract_value(response, @store_pins[0])
|
70
|
+
@store_pins = []
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def extract_value(response, pin)
|
75
|
+
v = response[index_of(pin) + 2]
|
76
|
+
if v == '`'
|
77
|
+
1
|
78
|
+
elsif v == '.'
|
79
|
+
0
|
80
|
+
else
|
81
|
+
fail "Failed to extract value for pin #{pin.name}, character in response is: #{v}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the vector index (position) of the given pin
|
86
|
+
def index_of(pin)
|
87
|
+
i = @pinorder.split(',').index(pin.name.to_s)
|
88
|
+
unless i
|
89
|
+
fail "Data capture of pin #{pin.name} has been requested, but it has not been included in the Link pinmap!"
|
90
|
+
end
|
91
|
+
i
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module OrigenLink
|
2
|
+
module ConfigurationCommands
|
3
|
+
# pinmap=
|
4
|
+
# This method is used to setup the pin map on the debugger device.
|
5
|
+
# The argument should be a string with <pin name>, <gpio #>, <pin name>
|
6
|
+
# <gpio #>, etc
|
7
|
+
#
|
8
|
+
# example:
|
9
|
+
# tester.pinmap = 'tclk,26,tms,19,tdi,16,tdo,23'
|
10
|
+
def pinmap=(pinmap)
|
11
|
+
@pinmap = pinmap.gsub(/\s+/, '')
|
12
|
+
response = send_cmd('pin_assign', @pinmap)
|
13
|
+
setup_cmd_response_logger('pin_assign', response)
|
14
|
+
end
|
15
|
+
|
16
|
+
# pinorder=
|
17
|
+
# This method is used to setup the pin order on the debugger device.
|
18
|
+
# The pin order will indicate the order that pin data appears in vector
|
19
|
+
# data.
|
20
|
+
#
|
21
|
+
# This is a duplicate of pattern_pin_order and can be handled behind the
|
22
|
+
# scenes in the future.
|
23
|
+
#
|
24
|
+
# example:
|
25
|
+
# tester.pinorder = 'tclk,tms,tdi,tdo'
|
26
|
+
def pinorder=(pinorder)
|
27
|
+
@pinorder = pinorder.gsub(/\s+/, '')
|
28
|
+
response = send_cmd('pin_patternorder', @pinorder)
|
29
|
+
setup_cmd_response_logger('pin_patternorder', response)
|
30
|
+
end
|
31
|
+
|
32
|
+
# pinformat=
|
33
|
+
# This method is used to setup the pin clock format on the debugger device.
|
34
|
+
# The supported formats are rl and rh
|
35
|
+
#
|
36
|
+
# example:
|
37
|
+
# tester.pinformat = 'func_25mhz,tclk,rl'
|
38
|
+
def pinformat=(pinformat)
|
39
|
+
@pinformat = replace_tset_name_w_number(pinformat.gsub(/\s+/, ''))
|
40
|
+
response = send_cmd('pin_format', @pinformat)
|
41
|
+
setup_cmd_response_logger('pin_format', response)
|
42
|
+
end
|
43
|
+
|
44
|
+
# pintiming=
|
45
|
+
# This method is used to setup the pin timing on the debugger device.
|
46
|
+
# Timing is relative to the rise and fall of a clock
|
47
|
+
#
|
48
|
+
# timing value: 0 1 2
|
49
|
+
# clock waveform: ___/***\___
|
50
|
+
#
|
51
|
+
# example:
|
52
|
+
# tester.pintiming = 'func_25mhz,tms,0,tdi,0,tdo,1'
|
53
|
+
def pintiming=(pintiming)
|
54
|
+
@pintiming = replace_tset_name_w_number(pintiming.gsub(/\s+/, ''))
|
55
|
+
response = send_cmd('pin_timing', @pintiming)
|
56
|
+
setup_cmd_response_logger('pin_timing', response)
|
57
|
+
end
|
58
|
+
|
59
|
+
# replace_tset_name_w_number(csl)
|
60
|
+
# This method is used by pinformat= and pintiming=
|
61
|
+
# This method receives a comma separated list of arguments
|
62
|
+
# the first of which is a timeset name. A comma
|
63
|
+
# separated list is returned with the timeset name replaced
|
64
|
+
# by it's lookup number. If it is a new timset, a lookup
|
65
|
+
# number is associated with the name.
|
66
|
+
def replace_tset_name_w_number(csl)
|
67
|
+
args = csl.split(',')
|
68
|
+
args[0] = get_tset_number(args[0])
|
69
|
+
args.join(',')
|
70
|
+
end
|
71
|
+
|
72
|
+
# get_tset_number(name)
|
73
|
+
# This method returns the test number associated with the
|
74
|
+
# passed in tset name. If the name is unknown a new lookup
|
75
|
+
# number is returned.
|
76
|
+
def get_tset_number(name)
|
77
|
+
unless @tsets_programmed.key?(name)
|
78
|
+
@tsets_programmed[name] = @tset_count
|
79
|
+
@tset_count += 1
|
80
|
+
end
|
81
|
+
@tsets_programmed[name]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -264,11 +264,17 @@ module OrigenLink
|
|
264
264
|
end
|
265
265
|
# process time 2 events
|
266
266
|
response = process_events(@cycletiming[tset]['timing'][2], pindata).merge(response)
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
267
|
+
# changing response format to return all data for easier debug, below is original method
|
268
|
+
# TODO: remove the commented code once return format and delay handling is finalized
|
269
|
+
# if (count == 0) || (@cycle_failure)
|
270
|
+
# message = ''
|
271
|
+
# @patternorder.each do |pin|
|
272
|
+
# message += response[pin]
|
273
|
+
# end
|
274
|
+
# end
|
275
|
+
message = message + ' ' unless count == 0
|
276
|
+
@patternorder.each do |pin|
|
277
|
+
message += response[pin]
|
272
278
|
end
|
273
279
|
end # end cycle through repeats
|
274
280
|
if @cycle_failure
|
@@ -276,7 +282,9 @@ module OrigenLink
|
|
276
282
|
else
|
277
283
|
rtnmsg = 'P:' + message
|
278
284
|
end
|
279
|
-
|
285
|
+
# no need to return repeat count since all data is returned
|
286
|
+
# TODO: remove the commented code once return format and delay handling is finalized
|
287
|
+
# rtnmsg += ' Repeat ' + repeat_count.to_s if repeat_count > 1
|
280
288
|
rtnmsg
|
281
289
|
end
|
282
290
|
|
@@ -45,6 +45,7 @@ module OrigenLink
|
|
45
45
|
@max_receive_time = (t4 - t3) if @max_receive_time < (t4 - t3)
|
46
46
|
@total_packets += 1
|
47
47
|
Origen.log.error 'nil response from server (likely died) for command(' + cmdstr + ':' + argstr + ')' if response.nil?
|
48
|
+
@pattern_link_messages << "#{cmdstr}:#{argstr}"
|
48
49
|
response # ensure the response is passed along
|
49
50
|
end
|
50
51
|
|
@@ -72,6 +73,7 @@ module OrigenLink
|
|
72
73
|
@total_recv_time += (t4 - t3)
|
73
74
|
@max_receive_time = (t4 - t3) if @max_receive_time < (t4 - t3)
|
74
75
|
@total_packets += 1
|
76
|
+
@pattern_link_messages.concat(vector_batch)
|
75
77
|
response
|
76
78
|
end
|
77
79
|
|
@@ -6,23 +6,23 @@ module OrigenLink
|
|
6
6
|
include OrigenJTAG
|
7
7
|
|
8
8
|
JTAG_CONFIG = {
|
9
|
-
|
10
|
-
tclk_format: :rh,
|
11
|
-
|
12
|
-
tclk_multiple: 4,
|
13
|
-
tdo_strobe:
|
14
|
-
tdo_store_cycle: 3,
|
15
|
-
init_state:
|
9
|
+
tclk_format: :rl,
|
10
|
+
# tclk_format: :rh,
|
11
|
+
tclk_multiple: 1,
|
12
|
+
# tclk_multiple: 4,
|
13
|
+
tdo_strobe: :tclk_high,
|
14
|
+
# tdo_store_cycle: 3,
|
15
|
+
init_state: :idle
|
16
16
|
}
|
17
17
|
|
18
18
|
def startup(options)
|
19
19
|
pp 'Enter test mode' do
|
20
20
|
# if tester.link?
|
21
21
|
if tester.to_s == 'OrigenLink::VectorBased'
|
22
|
-
tester.initialize_pattern
|
22
|
+
# tester.initialize_pattern
|
23
23
|
# below is for testing return format timing, requires tclk to be rl and multiple of 1
|
24
|
-
|
25
|
-
|
24
|
+
tester.pinformat = 'func_25mhz,tclk,rl'
|
25
|
+
tester.pintiming = 'func_25mhz,tdi,0,tms,0,tdo,1'
|
26
26
|
end
|
27
27
|
tester.set_timeset('func_25mhz', 40) # Where 40 is the period in ns
|
28
28
|
tester.wait time_in_us: 100
|
@@ -36,7 +36,7 @@ module OrigenLink
|
|
36
36
|
end
|
37
37
|
# if tester.link?
|
38
38
|
if tester.to_s == 'OrigenLink::VectorBased'
|
39
|
-
tester.finalize_pattern
|
39
|
+
# tester.finalize_pattern
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'origen_testers'
|
2
2
|
require 'origen_link/server_com'
|
3
|
+
require 'origen_link/capture_support'
|
4
|
+
require 'origen_link/configuration_commands'
|
3
5
|
require 'origen_link/callback_handlers'
|
4
6
|
module OrigenLink
|
5
7
|
# OrigenLink::VectorBased
|
@@ -30,6 +32,8 @@ module OrigenLink
|
|
30
32
|
class VectorBased
|
31
33
|
include OrigenTesters::VectorBasedTester
|
32
34
|
include ServerCom
|
35
|
+
include CaptureSupport
|
36
|
+
include ConfigurationCommands
|
33
37
|
|
34
38
|
# these attributes are exposed for testing purposes, a user would not need to read them
|
35
39
|
attr_reader :fail_count, :vector_count, :total_comm_time, :total_connect_time, :total_xmit_time
|
@@ -62,6 +66,8 @@ module OrigenLink
|
|
62
66
|
@store_pins_batch = {}
|
63
67
|
@comment_batch = {}
|
64
68
|
@batch_vectors = true
|
69
|
+
@pattern_link_messages = []
|
70
|
+
@pattern_comments = {}
|
65
71
|
end
|
66
72
|
|
67
73
|
# push_comment
|
@@ -75,6 +81,8 @@ module OrigenLink
|
|
75
81
|
else
|
76
82
|
@comment_batch[key] = msg
|
77
83
|
end
|
84
|
+
pattern_key = @pattern_link_messages.length + key
|
85
|
+
@pattern_comments[pattern_key] = @comment_batch[key]
|
78
86
|
else
|
79
87
|
microcode msg
|
80
88
|
end
|
@@ -111,65 +119,6 @@ module OrigenLink
|
|
111
119
|
@vector_count += 1
|
112
120
|
end
|
113
121
|
|
114
|
-
# Capture a vector
|
115
|
-
#
|
116
|
-
# This method applies a store vector request to the previous vector, note that is does
|
117
|
-
# not actually generate a new vector.
|
118
|
-
#
|
119
|
-
# The captured data is added to the captured_data array.
|
120
|
-
#
|
121
|
-
# This method is indended to be used by pin drivers, see the #capture method for the application
|
122
|
-
# level API.
|
123
|
-
#
|
124
|
-
# @example
|
125
|
-
# $tester.cycle # This is the vector you want to capture
|
126
|
-
# $tester.store # This applies the store request
|
127
|
-
def store(*pins)
|
128
|
-
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
129
|
-
fail 'The store is not implemented yet on Link'
|
130
|
-
end
|
131
|
-
|
132
|
-
# Capture the next vector generated
|
133
|
-
#
|
134
|
-
# This method applies a store request to the next vector to be generated,
|
135
|
-
# note that is does not actually generate a new vector.
|
136
|
-
#
|
137
|
-
# The captured data is added to the captured_data array.
|
138
|
-
#
|
139
|
-
# This method is indended to be used by pin drivers, see the #capture method for the application
|
140
|
-
# level API.
|
141
|
-
#
|
142
|
-
# @example
|
143
|
-
# tester.store_next_cycle
|
144
|
-
# tester.cycle # This is the vector that will be captured
|
145
|
-
def store_next_cycle(*pins)
|
146
|
-
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
147
|
-
flush_vector
|
148
|
-
@store_pins = pins
|
149
|
-
end
|
150
|
-
|
151
|
-
# Capture any store data within the given block, return it and then internally clear the tester's
|
152
|
-
# capture memory.
|
153
|
-
#
|
154
|
-
# @example
|
155
|
-
#
|
156
|
-
# v = tester.capture do
|
157
|
-
# my_reg.store!
|
158
|
-
# end
|
159
|
-
# v # => Data value read from my_reg on the DUT
|
160
|
-
def capture(*args)
|
161
|
-
if block_given?
|
162
|
-
yield
|
163
|
-
synchronize
|
164
|
-
d = @captured_data
|
165
|
-
@captured_data = []
|
166
|
-
d
|
167
|
-
else
|
168
|
-
# On other testers capture is an alias of store
|
169
|
-
store(*args)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
122
|
# flush_vector
|
174
123
|
# Just as the name suggests, this method "flushes" a vector. This is necessary because
|
175
124
|
# of repeat compression (a vector isn't sent until different vector data is encountered)
|
@@ -230,6 +179,10 @@ module OrigenLink
|
|
230
179
|
# if called from finalize_pattern -> synchronize, open the output_file and store results
|
231
180
|
output_obj = nil
|
232
181
|
output_obj = File.open(output_file, 'a+') unless output_file == ''
|
182
|
+
|
183
|
+
# in case there were only comments and no vectors, place comments (if any)
|
184
|
+
microcode @comment_batch[0] if response.size == 0
|
185
|
+
|
233
186
|
response.each_index do |index|
|
234
187
|
# restore store pins state for processing
|
235
188
|
if @store_pins_batch.key?(index)
|
@@ -237,17 +190,19 @@ module OrigenLink
|
|
237
190
|
else
|
238
191
|
@store_pins = []
|
239
192
|
end
|
193
|
+
process_vector_response(response[index], output_obj)
|
240
194
|
if @comment_batch.key?(index)
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
195
|
+
if output_file == ''
|
196
|
+
microcode @comment_batch[index]
|
197
|
+
else
|
198
|
+
# get the header placed correctly, the below code doesn't work
|
199
|
+
# if index == response.length - 1
|
200
|
+
# output_obj.puts 'last comment'
|
201
|
+
# output_obj.lineno = 0
|
202
|
+
# end
|
247
203
|
output_obj.puts(@comment_batch[index])
|
248
204
|
end
|
249
205
|
end
|
250
|
-
process_vector_response(response[index], output_obj)
|
251
206
|
end
|
252
207
|
output_obj.close unless output_file == ''
|
253
208
|
else
|
@@ -265,10 +220,34 @@ module OrigenLink
|
|
265
220
|
vector_response.strip!
|
266
221
|
vector_response += msg
|
267
222
|
end
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
223
|
+
vector_cycles = vector_response.split(/\s+/)
|
224
|
+
expected_msg = ''
|
225
|
+
expected_msg = ' ' + vector_cycles.pop if vector_cycles[vector_cycles.length - 1] =~ /Expected/
|
226
|
+
pfstatus = vector_cycles[0].chr
|
227
|
+
vector_cycles[0] = vector_cycles[0].byteslice(2, vector_cycles[0].length - 2)
|
228
|
+
|
229
|
+
vector_cycles.each do |cycle|
|
230
|
+
thiscyclefail = false
|
231
|
+
if pfstatus == 'F'
|
232
|
+
# check to see if this cycle failed
|
233
|
+
0.upto(cycle.length - 1) do |index|
|
234
|
+
thiscyclefail = true if (cycle[index] == 'H') && (expected_msg[expected_msg.length - cycle.length + index] == 'L')
|
235
|
+
thiscyclefail = true if (cycle[index] == 'L') && (expected_msg[expected_msg.length - cycle.length + index] == 'X')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
if thiscyclefail
|
239
|
+
expected_msg_prnt = expected_msg
|
240
|
+
prepend = 'F:'
|
241
|
+
else
|
242
|
+
expected_msg_prnt = ''
|
243
|
+
prepend = 'P:'
|
244
|
+
end
|
245
|
+
|
246
|
+
if output_obj.nil?
|
247
|
+
microcode prepend + cycle + expected_msg_prnt
|
248
|
+
else
|
249
|
+
output_obj.puts(prepend + cycle + expected_msg_prnt)
|
250
|
+
end
|
272
251
|
end
|
273
252
|
|
274
253
|
unless vector_response.chr == 'P'
|
@@ -287,6 +266,8 @@ module OrigenLink
|
|
287
266
|
@vector_batch.delete_if { true }
|
288
267
|
@store_pins_batch.clear
|
289
268
|
@comment_batch.clear
|
269
|
+
@pattern_link_messages.delete_if { true }
|
270
|
+
@pattern_comments.clear
|
290
271
|
|
291
272
|
@total_packets = 0
|
292
273
|
@total_comm_time = 0
|
@@ -327,6 +308,15 @@ module OrigenLink
|
|
327
308
|
# Origen.log.error("FAIL - pattern execution failed (#{@fail_count} failures)")
|
328
309
|
Origen.app.stats.report_fail
|
329
310
|
end
|
311
|
+
commands_file = Origen.app.current_job.output_file.split('.')[0] + '_link_cmds.txt'
|
312
|
+
File.open(commands_file, 'w') do |file|
|
313
|
+
file.puts("pin_assign:#{@pinmap}")
|
314
|
+
file.puts("pin_patternorder:#{@pinorder}")
|
315
|
+
@pattern_link_messages.each_index do |index|
|
316
|
+
file.puts(@pattern_link_messages[index])
|
317
|
+
file.puts(@pattern_comments[index]) if @pattern_comments.key?(index)
|
318
|
+
end
|
319
|
+
end
|
330
320
|
end
|
331
321
|
|
332
322
|
# to_s
|
@@ -339,117 +329,31 @@ module OrigenLink
|
|
339
329
|
'OrigenLink::VectorBased'
|
340
330
|
end
|
341
331
|
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
#
|
346
|
-
#
|
347
|
-
# example:
|
348
|
-
# tester.pinmap = 'tclk,26,tms,19,tdi,16,tdo,23'
|
349
|
-
def pinmap=(pinmap)
|
350
|
-
@pinmap = pinmap.gsub(/\s+/, '')
|
351
|
-
response = send_cmd('pin_assign', @pinmap)
|
352
|
-
setup_cmd_response_logger('pin_assign', response)
|
353
|
-
end
|
354
|
-
|
355
|
-
# pinorder=
|
356
|
-
# This method is used to setup the pin order on the debugger device.
|
357
|
-
# The pin order will indicate the order that pin data appears in vector
|
358
|
-
# data.
|
332
|
+
# transaction
|
333
|
+
# returns true/false indicating whether the transaction passed
|
334
|
+
# true = pass
|
335
|
+
# false = fail
|
359
336
|
#
|
360
|
-
#
|
361
|
-
# scenes in the future.
|
337
|
+
# TODO: capture transaction vector data and response for use in debug
|
362
338
|
#
|
363
|
-
#
|
364
|
-
#
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
@pinformat = replace_tset_name_w_number(pinformat.gsub(/\s+/, ''))
|
379
|
-
response = send_cmd('pin_format', @pinformat)
|
380
|
-
setup_cmd_response_logger('pin_format', response)
|
381
|
-
end
|
382
|
-
|
383
|
-
# pintiming=
|
384
|
-
# This method is used to setup the pin timing on the debugger device.
|
385
|
-
# Timing is relative to the rise and fall of a clock
|
386
|
-
#
|
387
|
-
# timing value: 0 1 2
|
388
|
-
# clock waveform: ___/***\___
|
389
|
-
#
|
390
|
-
# example:
|
391
|
-
# tester.pintiming = 'func_25mhz,tms,0,tdi,0,tdo,1'
|
392
|
-
def pintiming=(pintiming)
|
393
|
-
@pintiming = replace_tset_name_w_number(pintiming.gsub(/\s+/, ''))
|
394
|
-
response = send_cmd('pin_timing', @pintiming)
|
395
|
-
setup_cmd_response_logger('pin_timing', response)
|
396
|
-
end
|
397
|
-
|
398
|
-
# replace_tset_name_w_number(csl)
|
399
|
-
# This method is used by pinformat= and pintiming=
|
400
|
-
# This method receives a comma separated list of arguments
|
401
|
-
# the first of which is a timeset name. A comma
|
402
|
-
# separated list is returned with the timeset name replaced
|
403
|
-
# by it's lookup number. If it is a new timset, a lookup
|
404
|
-
# number is associated with the name.
|
405
|
-
def replace_tset_name_w_number(csl)
|
406
|
-
args = csl.split(',')
|
407
|
-
args[0] = get_tset_number(args[0])
|
408
|
-
args.join(',')
|
409
|
-
end
|
410
|
-
|
411
|
-
# get_tset_number(name)
|
412
|
-
# This method returns the test number associated with the
|
413
|
-
# passed in tset name. If the name is unknown a new lookup
|
414
|
-
# number is returned.
|
415
|
-
def get_tset_number(name)
|
416
|
-
unless @tsets_programmed.key?(name)
|
417
|
-
@tsets_programmed[name] = @tset_count
|
418
|
-
@tset_count += 1
|
419
|
-
end
|
420
|
-
@tsets_programmed[name]
|
421
|
-
end
|
422
|
-
|
423
|
-
private
|
424
|
-
|
425
|
-
def capture_data(response)
|
426
|
-
if @store_pins.size > 1
|
427
|
-
fail 'Data capture on multiple pins is not implemented yet'
|
428
|
-
else
|
429
|
-
captured_data[0] ||= 0
|
430
|
-
captured_data[0] = (captured_data[0] << 1) | extract_value(response, @store_pins[0])
|
431
|
-
@store_pins = []
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
def extract_value(response, pin)
|
436
|
-
v = response[index_of(pin) + 2]
|
437
|
-
if v == '`'
|
438
|
-
1
|
439
|
-
elsif v == '.'
|
440
|
-
0
|
339
|
+
# if !tester.transaction {dut.reg blah blah}
|
340
|
+
# puts 'transaction failed'
|
341
|
+
# end
|
342
|
+
def transaction
|
343
|
+
if block_given?
|
344
|
+
synchronize
|
345
|
+
transaction_fail_count = @fail_count
|
346
|
+
yield
|
347
|
+
synchronize
|
348
|
+
transaction_fail_count = @fail_count - transaction_fail_count
|
349
|
+
if transaction_fail_count == 0
|
350
|
+
true
|
351
|
+
else
|
352
|
+
false
|
353
|
+
end
|
441
354
|
else
|
442
|
-
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
# Returns the vector index (position) of the given pin
|
447
|
-
def index_of(pin)
|
448
|
-
i = @pinorder.split(',').index(pin.name.to_s)
|
449
|
-
unless i
|
450
|
-
fail "Data capture of pin #{pin.name} has been requested, but it has not been included in the Link pinmap!"
|
355
|
+
true
|
451
356
|
end
|
452
|
-
i
|
453
357
|
end
|
454
358
|
end
|
455
359
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Pattern.create(options={:name => "JTAG_CaptureID"})do
|
2
|
+
$dut.jtag.reset
|
3
|
+
$dut.jtag.idle
|
4
|
+
ss "reading default ID"
|
5
|
+
$dut.reg(:testreg).bits(31..0).store
|
6
|
+
default_id = tester.capture {$dut.jtag.read_dr $dut.reg(:testreg), size: 32 }
|
7
|
+
default_id_str = default_id[0].to_s(2)
|
8
|
+
default_id_str.reverse!
|
9
|
+
default_id = default_id_str.to_i(2)
|
10
|
+
puts '**************************************************'
|
11
|
+
puts 'Captured default ID through JTAG: 0x' + default_id.to_s(16)
|
12
|
+
puts '**************************************************'
|
13
|
+
$dut.jtag.write_ir 0, size: 4
|
14
|
+
ss "reading JTAG ID"
|
15
|
+
$dut.reg(:testreg).bits(31..0).store
|
16
|
+
jtag_id = tester.capture {$dut.jtag.read_dr $dut.reg(:testreg), size: 32 }
|
17
|
+
jtag_id_str = jtag_id[0].to_s(2)
|
18
|
+
jtag_id_str.reverse!
|
19
|
+
jtag_id = jtag_id_str.to_i(2)
|
20
|
+
puts '**************************************************'
|
21
|
+
puts 'Captured JTAG ID: 0x' + jtag_id.to_s(16)
|
22
|
+
puts '**************************************************'
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Pattern.create(options={:name => "transaction_test"})do
|
2
|
+
$dut.jtag.reset
|
3
|
+
$dut.jtag.idle
|
4
|
+
ss "reading Halo debugger ID - setting correct compare value"
|
5
|
+
result = tester.transaction do
|
6
|
+
$dut.reg(:testreg).read(0x5ba00477)
|
7
|
+
$dut.jtag.read_dr $dut.reg(:testreg), size: 32
|
8
|
+
end
|
9
|
+
result_comment = "transaction result: #{result}"
|
10
|
+
ss result_comment
|
11
|
+
|
12
|
+
ss "reading Halo debugger ID - setting wrong compare value"
|
13
|
+
result = tester.transaction do
|
14
|
+
$dut.reg(:testreg).read(0x5bd00477)
|
15
|
+
$dut.jtag.read_dr $dut.reg(:testreg), size: 32
|
16
|
+
end
|
17
|
+
result_comment = "transaction result: #{result}"
|
18
|
+
ss result_comment
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen_link
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Derouen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -95,6 +95,8 @@ files:
|
|
95
95
|
- config/version.rb
|
96
96
|
- lib/origen_link.rb
|
97
97
|
- lib/origen_link/callback_handlers.rb
|
98
|
+
- lib/origen_link/capture_support.rb
|
99
|
+
- lib/origen_link/configuration_commands.rb
|
98
100
|
- lib/origen_link/server/jtag.rb
|
99
101
|
- lib/origen_link/server/pin.rb
|
100
102
|
- lib/origen_link/server/sequencer.rb
|
@@ -106,8 +108,10 @@ files:
|
|
106
108
|
- lib/tasks/origen_link.rake
|
107
109
|
- pattern/example.rb
|
108
110
|
- pattern/jtag_100_operations.rb
|
111
|
+
- pattern/jtag_capture_id.rb
|
109
112
|
- pattern/jtag_comm_fail_test.rb
|
110
113
|
- pattern/jtag_comm_test.rb
|
114
|
+
- pattern/transaction_test.rb
|
111
115
|
- templates/web/index.md.erb
|
112
116
|
- templates/web/layouts/_basic.html.erb
|
113
117
|
- templates/web/partials/_navbar.html.erb
|
@@ -131,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
135
|
version: 1.8.11
|
132
136
|
requirements: []
|
133
137
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.
|
138
|
+
rubygems_version: 2.2.2
|
135
139
|
signing_key:
|
136
140
|
specification_version: 4
|
137
141
|
summary: Origen interface to a live DUT tester
|