origen_link 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/start_link_server +51 -4
- data/config/version.rb +2 -2
- data/lib/origen_link/server/jtag.rb +96 -40
- data/lib/origen_link/vector_based.rb +49 -4
- data/templates/web/index.md.erb +54 -21
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d23f0665303afa13e7e60c42dae8931fa93abe3
|
4
|
+
data.tar.gz: 53e0c64c2a14c273fac39b100208e0bccfa7b21d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18d29362fa1d0c1ba23996f7a296342d712e89cfaf0aa321b0cf71f271bf0f8f33c6fa5e936576b8c0070d8bc6e36e152128abb1c0e23ba0686bf20941343356
|
7
|
+
data.tar.gz: 96f5d51aef745dff7c49202d0df7bbd2760a32ba78a4fef99b3ee9ffb47c61d8dcafd50cd193fab19d8e3aa65d88d82d1ca6273999252b8e208579d91094cd1a
|
data/bin/start_link_server
CHANGED
@@ -3,17 +3,55 @@ $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'li
|
|
3
3
|
$LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'config'))
|
4
4
|
require 'socket'
|
5
5
|
require 'origen_link/server/sequencer'
|
6
|
+
require 'origen_link/server/jtag'
|
6
7
|
require 'version'
|
7
8
|
|
9
|
+
# method to handle the processing of a jtag message
|
10
|
+
def processjtagmessage(message)
|
11
|
+
reply = 'Error'
|
12
|
+
if message =~ /jtag_configure:/
|
13
|
+
# Allow the default io numbers to be overridden
|
14
|
+
newios = message.gsub(/\s+/, '').split(':')[1].split(',')
|
15
|
+
if newios.size = 4
|
16
|
+
$tdiio = newios[0]
|
17
|
+
$tdoio = newios[1]
|
18
|
+
$tmsio = newios[2]
|
19
|
+
$tckio = newios[3]
|
20
|
+
reply = "jtag_configure: tdi = #{$tdiio}, tdo = #{$tdoio}, tms = #{$tmsio}, tck = #{$tckio}"
|
21
|
+
else
|
22
|
+
reply = 'jtag_configure failed, need 4 io numbers, tdi, tdo, tms, tck - in that order'
|
23
|
+
end
|
24
|
+
elsif message =~ /jtag_reinit/
|
25
|
+
$jtag_interpreter.destroy unless $jtag_interpreter.nil?
|
26
|
+
$jtag_interpreter = OrigenLink::Server::Jtag.new($tdiio, $tdoio, $tmsio, $tckio)
|
27
|
+
reply = 'done'
|
28
|
+
else
|
29
|
+
$jtag_interpreter = OrigenLink::Server::Jtag.new($tdiio, $tdoio, $tmsio, $tckio) if $jtag_interpreter.nil?
|
30
|
+
reply = $jtag_interpreter.processmessage(message)
|
31
|
+
end
|
32
|
+
reply
|
33
|
+
end
|
34
|
+
|
35
|
+
# General initialization
|
8
36
|
server = TCPServer.open('', 12_777)
|
9
|
-
pinsequencer = OrigenLink::Server::Sequencer.new
|
10
|
-
pinsequencer.version = OrigenLink::VERSION
|
11
37
|
remoteuser = ''
|
12
38
|
remotehost = ''
|
13
39
|
sessionactivity = Time.now
|
14
40
|
sessionactive = false
|
41
|
+
|
42
|
+
# Initialize the pin sequencer object
|
43
|
+
pinsequencer = OrigenLink::Server::Sequencer.new
|
44
|
+
pinsequencer.version = OrigenLink::VERSION
|
15
45
|
puts "server version #{pinsequencer.version} started"
|
16
46
|
|
47
|
+
# Set default values for the Jtag object
|
48
|
+
$tdiio = 116
|
49
|
+
$tdoio = 124
|
50
|
+
$tmsio = 6
|
51
|
+
$tckio = 119
|
52
|
+
$jtag_interpreter = nil
|
53
|
+
|
54
|
+
# Wait for connection requests in an infinite loop
|
17
55
|
loop do
|
18
56
|
client = server.accept
|
19
57
|
thisuser = client.gets.chomp
|
@@ -41,25 +79,34 @@ loop do
|
|
41
79
|
response = "\n"
|
42
80
|
end
|
43
81
|
|
82
|
+
# Now we're ready to process the actual message
|
44
83
|
# if this connection is from the active user\host machine, then process the information
|
45
84
|
if (remoteuser.eql? thisuser) && (remotehost.eql? thisremotehost)
|
46
85
|
while (message = client.gets) != "\n"
|
47
86
|
# process the message
|
48
|
-
|
49
|
-
if message =~ /session_end/
|
87
|
+
if message =~ /session_end/ || message =~ /session_kill/
|
50
88
|
sessionactive = false
|
51
89
|
response = response + "session_end:session_end\n"
|
90
|
+
elsif message[0,5] == 'jtag_'
|
91
|
+
# jtag messages get routed to the jtag message handler
|
92
|
+
sessionactive = true
|
93
|
+
response = response + processjtagmessage(message.chomp) + "\n"
|
52
94
|
else
|
95
|
+
# default is pin sequencer message handling
|
53
96
|
sessionactive = true
|
54
97
|
response = response + pinsequencer.processmessage(message.chomp) + "\n"
|
55
98
|
end
|
56
99
|
end
|
57
100
|
sessionactivity = Time.now
|
58
101
|
else
|
102
|
+
# The connection didn't come from the active user. Only session_kill is allowed.
|
59
103
|
checkmessage = client.gets.chomp
|
60
104
|
if checkmessage =~ /session_kill/
|
61
105
|
sessionactive = false
|
62
106
|
response = response + "Terminated: session from #{remoteuser} at IP address #{remotehost} inactive for #{Time.now - sessionactivity} seconds has been killed\n"
|
107
|
+
change_in_user = true unless (remoteuser.eql? thisuser) && (remotehost.eql? thisremotehost)
|
108
|
+
remoteuser = thisuser
|
109
|
+
remotehost = thisremotehost
|
63
110
|
else
|
64
111
|
response = response + "Busy: server is in use by #{remoteuser} from IP address #{remotehost}\n"
|
65
112
|
end
|
data/config/version.rb
CHANGED
@@ -2,35 +2,23 @@ require 'origen_link/server/pin'
|
|
2
2
|
|
3
3
|
module OrigenLink
|
4
4
|
module Server
|
5
|
-
# The Jtag class is not part of the OrigenLink plug-in/server ecosystem.
|
6
|
-
# It implements standard jtag protocol. It can be used to implement a
|
7
|
-
# Jtag protocol server (not included in this repository presently).
|
8
5
|
class Jtag
|
9
|
-
# The value read from TDO during the shift
|
10
6
|
attr_reader :tdoval
|
11
|
-
# Enable extra output
|
12
7
|
attr_accessor :verbose_enable
|
13
8
|
attr_accessor :anytdofail
|
14
9
|
|
15
|
-
|
16
|
-
def initialize(tdiio = 16, tdoio = 23, tmsio = 19, tckio = 26, tck_period = 0.000001)
|
10
|
+
def initialize(tdiio = 116, tdoio = 124, tmsio = 6, tckio = 119)
|
17
11
|
@tdipin = Pin.new(tdiio, :out)
|
18
12
|
@tdopin = Pin.new(tdoio, :in)
|
19
13
|
@tmspin = Pin.new(tmsio, :out)
|
20
14
|
@tckpin = Pin.new(tckio, :out)
|
21
|
-
@tck_half_period = tck_period / 2
|
22
15
|
@tdoval = 0
|
23
16
|
@tdostr = ''
|
24
17
|
@verbose_enable = true
|
25
18
|
@anytdofail = false
|
19
|
+
@pins = {}
|
26
20
|
end
|
27
21
|
|
28
|
-
# not needed, no need for wait states between operations
|
29
|
-
def tck_period=(value)
|
30
|
-
@tck_half_period = value / 2
|
31
|
-
end
|
32
|
-
|
33
|
-
# close out file IO objects for the pins
|
34
22
|
def destroy
|
35
23
|
@tdipin.destroy
|
36
24
|
@tdopin.destroy
|
@@ -40,15 +28,14 @@ module OrigenLink
|
|
40
28
|
@tdopin = nil
|
41
29
|
@tmspin = nil
|
42
30
|
@tckpin = nil
|
31
|
+
@pins.each_value(&:destroy)
|
43
32
|
end
|
44
33
|
|
45
|
-
# perform 1 jtag cycle
|
46
34
|
def do_cycle(tdival, tmsval, capturetdo = false)
|
47
35
|
@tdipin.out(tdival)
|
48
36
|
@tmspin.out(tmsval)
|
49
|
-
|
37
|
+
|
50
38
|
@tckpin.out(1)
|
51
|
-
sleep @tck_half_period
|
52
39
|
|
53
40
|
if capturetdo
|
54
41
|
@tdostr = @tdopin.in + @tdostr
|
@@ -56,13 +43,11 @@ module OrigenLink
|
|
56
43
|
@tckpin.out(0)
|
57
44
|
end
|
58
45
|
|
59
|
-
# advance state machine to test logic reset, then return to run/test idle
|
60
46
|
def do_tlr
|
61
47
|
8.times { do_cycle(0, 1) }
|
62
48
|
do_cycle(0, 0)
|
63
49
|
end
|
64
50
|
|
65
|
-
# shift a value in on tdi, optionall capture tdo
|
66
51
|
def do_shift(numbits, value, capturetdo = false, suppresscomments = false, tdocompare = '')
|
67
52
|
@tdoval = 0
|
68
53
|
@tdostr = ''
|
@@ -96,20 +81,9 @@ module OrigenLink
|
|
96
81
|
|
97
82
|
tdovalstr = @tdoval.to_s(2)
|
98
83
|
tdovalstr = '0' * (numbits - tdovalstr.length) + tdovalstr
|
99
|
-
|
100
|
-
if thiscomparefail
|
101
|
-
puts '****************************>>>>>>>>>>>>>>>>> TDO failure <<<<<<<<<<<<<<<<<<****************************'
|
102
|
-
puts 'expected: ' + tdocompare
|
103
|
-
puts 'received: ' + tdovalstr
|
104
|
-
else
|
105
|
-
puts 'TDO compare pass'
|
106
|
-
puts 'expected: ' + tdocompare
|
107
|
-
puts 'received: ' + tdovalstr
|
108
|
-
end
|
109
84
|
end
|
110
85
|
end
|
111
86
|
|
112
|
-
# perform an ir-update
|
113
87
|
def do_ir(numbits, value, options = {})
|
114
88
|
defaults = {
|
115
89
|
capturetdo: false,
|
@@ -118,10 +92,6 @@ module OrigenLink
|
|
118
92
|
}
|
119
93
|
options = defaults.merge(options)
|
120
94
|
|
121
|
-
if !(options[:suppresscomments]) && @verbose_enable
|
122
|
-
puts " shift IR, #{numbits} bits, value = 0x" + value.to_s(16)
|
123
|
-
end
|
124
|
-
|
125
95
|
if options[:tdocompare] != ''
|
126
96
|
capturetdo = true
|
127
97
|
else
|
@@ -142,7 +112,6 @@ module OrigenLink
|
|
142
112
|
do_cycle(0, 0)
|
143
113
|
end
|
144
114
|
|
145
|
-
# perform a dr update
|
146
115
|
def do_dr(numbits, value, options = {})
|
147
116
|
defaults = {
|
148
117
|
capturetdo: true,
|
@@ -150,9 +119,6 @@ module OrigenLink
|
|
150
119
|
tdocompare: ''
|
151
120
|
}
|
152
121
|
options = defaults.merge(options)
|
153
|
-
if !(options[:suppresscomments]) && @verbose_enable
|
154
|
-
puts " shift DR, #{numbits} bits, value = 0x" + value.to_s(16)
|
155
|
-
end
|
156
122
|
|
157
123
|
if options[:tdocompare] != ''
|
158
124
|
capturetdo = true
|
@@ -173,7 +139,6 @@ module OrigenLink
|
|
173
139
|
do_cycle(0, 0)
|
174
140
|
end
|
175
141
|
|
176
|
-
# traverse the pause dr state
|
177
142
|
def pause_dr
|
178
143
|
do_cycle(0, 1)
|
179
144
|
do_cycle(0, 0)
|
@@ -185,11 +150,102 @@ module OrigenLink
|
|
185
150
|
do_cycle(0, 0)
|
186
151
|
end
|
187
152
|
|
188
|
-
# traverse the pause ir state
|
189
153
|
def pause_ir
|
190
154
|
do_cycle(0, 1)
|
191
155
|
pause_dr
|
192
156
|
end
|
157
|
+
|
158
|
+
def read_adc(csl)
|
159
|
+
channel_list = csl.split(',')
|
160
|
+
response = ''
|
161
|
+
channel_list.each do |channel|
|
162
|
+
file_name = '/sys/bus/iio/devices/'
|
163
|
+
case channel
|
164
|
+
when 'A0'
|
165
|
+
file_name = file_name + 'iio:device0/in_voltage0_raw'
|
166
|
+
when 'A1'
|
167
|
+
file_name = file_name + 'iio:device0/in_voltage1_raw'
|
168
|
+
when 'A2'
|
169
|
+
file_name = file_name + 'iio:device0/in_voltage2_raw'
|
170
|
+
when 'A3'
|
171
|
+
file_name = file_name + 'iio:device0/in_voltage3_raw'
|
172
|
+
when 'A4'
|
173
|
+
file_name = file_name + 'iio:device1/in_voltage0_raw'
|
174
|
+
when 'A5'
|
175
|
+
file_name = file_name + 'iio:device1/in_voltage1_raw'
|
176
|
+
end
|
177
|
+
response = response + ',' unless response.size == 0
|
178
|
+
if File.exist?(file_name)
|
179
|
+
File.open(file_name, 'r') do |file|
|
180
|
+
reading = file.gets
|
181
|
+
response = response + reading.strip
|
182
|
+
end
|
183
|
+
else
|
184
|
+
response = response + '-1'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
response
|
188
|
+
end
|
189
|
+
|
190
|
+
def processmessage(message)
|
191
|
+
message.strip!
|
192
|
+
split_message = message.split(':')
|
193
|
+
response = ''
|
194
|
+
case split_message[0]
|
195
|
+
when 'jtag_ir'
|
196
|
+
args = split_message[1].split(',')
|
197
|
+
do_ir(args[2].to_i, string_to_val(args[0], args[1]), capturetdo: true, suppresscomments: true)
|
198
|
+
response = @tdoval.to_s(16)
|
199
|
+
when 'jtag_dr'
|
200
|
+
args = split_message[1].split(',')
|
201
|
+
do_dr(args[2].to_i, string_to_val(args[0], args[1]), capturetdo: true, suppresscomments: true)
|
202
|
+
response = @tdoval.to_s(16)
|
203
|
+
when 'jtag_pause_dr'
|
204
|
+
pause_dr
|
205
|
+
response = 'done'
|
206
|
+
when 'jtag_pause_ir'
|
207
|
+
pause_ir
|
208
|
+
response = 'done'
|
209
|
+
when 'jtag_reset'
|
210
|
+
do_tlr
|
211
|
+
response = 'done'
|
212
|
+
when 'jtag_pin_set'
|
213
|
+
pinlist = split_message[1].split(',')
|
214
|
+
pinlist.each do |pin|
|
215
|
+
@pins[pin] = Pin.new(pin, :out) unless @pins.key?(pin)
|
216
|
+
@pins[pin].out(1)
|
217
|
+
end
|
218
|
+
response = 'done'
|
219
|
+
when 'jtag_pin_clear'
|
220
|
+
pinlist = split_message[1].split(',')
|
221
|
+
pinlist.each do |pin|
|
222
|
+
@pins[pin] = Pin.new(pin, :out) unless @pins.key?(pin)
|
223
|
+
@pins[pin].out(0)
|
224
|
+
end
|
225
|
+
response = 'done'
|
226
|
+
when 'jtag_pin_read'
|
227
|
+
pinlist = split_message[1].split(',')
|
228
|
+
pinlist.each do |pin|
|
229
|
+
@pins[pin] = Pin.new(pin, :in) unless @pins.key?(pin)
|
230
|
+
response = response + @pins[pin].in
|
231
|
+
end
|
232
|
+
response
|
233
|
+
when 'jtag_adc_read'
|
234
|
+
response = read_adc(split_message[1])
|
235
|
+
response
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def string_to_val(base_indicator, numstr)
|
240
|
+
case base_indicator
|
241
|
+
when 'h'
|
242
|
+
numstr.to_i(16)
|
243
|
+
when 'd'
|
244
|
+
numstr.to_i(10)
|
245
|
+
when 'b'
|
246
|
+
numstr.to_i(2)
|
247
|
+
end
|
248
|
+
end
|
193
249
|
end
|
194
250
|
end
|
195
251
|
end
|
@@ -202,16 +202,17 @@ module OrigenLink
|
|
202
202
|
exit 1
|
203
203
|
end
|
204
204
|
tset = options[:timeset].name
|
205
|
+
local_repeat = options[:repeat].nil? ? 1 : options[:repeat]
|
205
206
|
if @vector_count > 0
|
206
207
|
# compressing repeats as we go
|
207
208
|
if (programmed_data == @previous_vectordata) && (@previous_tset == tset) && @store_pins.empty?
|
208
|
-
@vector_repeatcount +=
|
209
|
+
@vector_repeatcount += local_repeat
|
209
210
|
else
|
210
211
|
# all repeats of the previous vector have been counted
|
211
212
|
# time to flush. Don't panic though! @previous_vectordata
|
212
213
|
# is what gets flushed. programmed_data is passed as an
|
213
214
|
# arg to be set as the new @previous_vectordata
|
214
|
-
flush_vector(programmed_data, tset)
|
215
|
+
flush_vector(programmed_data, tset, local_repeat)
|
215
216
|
end
|
216
217
|
else
|
217
218
|
# if this is the first vector of the pattern, insure variables are initialized
|
@@ -225,7 +226,7 @@ module OrigenLink
|
|
225
226
|
# flush_vector
|
226
227
|
# Just as the name suggests, this method "flushes" a vector. This is necessary because
|
227
228
|
# of repeat compression (a vector isn't sent until different vector data is encountered)
|
228
|
-
def flush_vector(programmed_data = '', tset = '')
|
229
|
+
def flush_vector(programmed_data = '', tset = '', local_repeat = 1)
|
229
230
|
# prevent server crash when vector_flush is used during debug
|
230
231
|
unless @previous_vectordata == ''
|
231
232
|
if @vector_repeatcount > 1
|
@@ -261,7 +262,7 @@ module OrigenLink
|
|
261
262
|
@store_pins = []
|
262
263
|
end
|
263
264
|
|
264
|
-
@vector_repeatcount =
|
265
|
+
@vector_repeatcount = local_repeat
|
265
266
|
@previous_vectordata = programmed_data
|
266
267
|
@previous_tset = tset
|
267
268
|
end
|
@@ -470,5 +471,49 @@ module OrigenLink
|
|
470
471
|
true
|
471
472
|
end
|
472
473
|
end
|
474
|
+
|
475
|
+
# wait a fixed amount of time
|
476
|
+
# This method will run the Sleep method to wait rather than generating cycles.
|
477
|
+
# Cycle execution time is not predictable with OrigenLink.
|
478
|
+
#
|
479
|
+
# If you want cycles to be generated by this method include apply_cycles: true
|
480
|
+
# in the options hash
|
481
|
+
#
|
482
|
+
# This method currently doesn't handle match blocks.
|
483
|
+
def wait(options = {})
|
484
|
+
options = {
|
485
|
+
cycles: 0,
|
486
|
+
time_in_cycles: 0,
|
487
|
+
time_in_us: 0,
|
488
|
+
time_in_ns: 0,
|
489
|
+
time_in_ms: 0,
|
490
|
+
time_in_s: 0,
|
491
|
+
match: false, # Set to true to invoke a match loop where the supplied delay
|
492
|
+
apply_cycles: false
|
493
|
+
# will become the timeout duration
|
494
|
+
}.merge(options)
|
495
|
+
|
496
|
+
fail 'wait(match: true) is not yet implemented on Link' if options[:match]
|
497
|
+
|
498
|
+
time_delay = 0
|
499
|
+
time_delay += (options[:time_in_s])
|
500
|
+
time_delay += (options[:time_in_ms]) * 0.001
|
501
|
+
time_delay += (options[:time_in_us]) * 0.000001
|
502
|
+
time_delay += (options[:time_in_ns]) * 0.000000001
|
503
|
+
time_delay += (options[:cycles] + options[:time_in_cycles]) * current_period_in_ns * 0.000000001
|
504
|
+
|
505
|
+
if options[:apply_cycles]
|
506
|
+
cycles = time_delay / 0.00003 # cycle execution time is unpredictable, but ~= 30us
|
507
|
+
if options[:cycles] > 0 || options[:time_in_cycles] > 0
|
508
|
+
options[:repeat] = options[:cycles] + options[:time_in_cycles]
|
509
|
+
else
|
510
|
+
options[:repeat] = (cycles > 0) ? cycles : 1
|
511
|
+
end
|
512
|
+
cycle(options)
|
513
|
+
else
|
514
|
+
synchronize # ensure all generated cycles are executed before delay is run
|
515
|
+
sleep time_delay
|
516
|
+
end
|
517
|
+
end
|
473
518
|
end
|
474
519
|
end
|
data/templates/web/index.md.erb
CHANGED
@@ -14,14 +14,14 @@ Instructions for integrating and using the plug-in with your app.
|
|
14
14
|
|
15
15
|
## How To Import
|
16
16
|
|
17
|
-
|
17
|
+
##### Add the following line to your application's GEMFILE:
|
18
18
|
|
19
19
|
~~~ruby
|
20
20
|
gem 'origen_link'
|
21
21
|
~~~
|
22
22
|
|
23
23
|
|
24
|
-
|
24
|
+
##### Add a link environment (./environment/link.rb). See server setup section for more information:
|
25
25
|
|
26
26
|
~~~ruby
|
27
27
|
# Note that the field for providing the computer name or IP address is a string
|
@@ -29,7 +29,7 @@ OrigenLink::VectorBased.new('<ServerComputerName -- or IP_Address>', 12777)
|
|
29
29
|
~~~
|
30
30
|
|
31
31
|
|
32
|
-
|
32
|
+
##### Select link as your environment to run a pattern over the link connection when the origen generate command is run:
|
33
33
|
|
34
34
|
~~~
|
35
35
|
origen e environment/link.rb
|
@@ -159,7 +159,7 @@ There are pin methods available to aid debug of an OrigenLink setup.
|
|
159
159
|
|
160
160
|
For efficiency vectors that are generated by your app are compressed and stored until the pattern generation is completed. This means that when execution reaches a 'debugger' statement the previously generated vectors may not have been sent to the server yet. There are a handful of ways to make this happen.
|
161
161
|
|
162
|
-
|
162
|
+
##### Use the tester.synchronize command from the debugger interface:
|
163
163
|
|
164
164
|
~~~
|
165
165
|
# one time synchronize
|
@@ -170,7 +170,9 @@ For efficiency vectors that are generated by your app are compressed and stored
|
|
170
170
|
(debugger prompt): disp tester.synchronize
|
171
171
|
~~~
|
172
172
|
|
173
|
-
|
173
|
+
##### Use tester.transaction
|
174
|
+
|
175
|
+
It makes the most sense to have this in your app's reg read/write methods). Before the transaction method executes the code block provided it will perform a synchronization. Then, the code in the block is executed (which generates new vectors) and a second synchronization is performed. The transaction method returns a boolean indicating whether the vectors generated by the code block passed or failed.
|
174
176
|
|
175
177
|
~~~ruby
|
176
178
|
result = tester.transaction { dut.jtag.shift_xx (yy) }
|
@@ -183,7 +185,7 @@ For efficiency vectors that are generated by your app are compressed and stored
|
|
183
185
|
|
184
186
|
There are a few methods for observing the actual state of the DUT.
|
185
187
|
|
186
|
-
|
188
|
+
##### Capture using tester.capture
|
187
189
|
|
188
190
|
~~~ruby
|
189
191
|
# example of capturing and programatically using information read from the DUT
|
@@ -198,7 +200,7 @@ There are a few methods for observing the actual state of the DUT.
|
|
198
200
|
puts '**************************************************'
|
199
201
|
~~~
|
200
202
|
|
201
|
-
|
203
|
+
##### Capture using mem api
|
202
204
|
|
203
205
|
This command will read the contents of memory from the DUT and display it.
|
204
206
|
|
@@ -216,28 +218,57 @@ This command will read the contents of memory from the DUT and display it.
|
|
216
218
|
20000008: 1C000898
|
217
219
|
~~~
|
218
220
|
|
219
|
-
|
221
|
+
##### reg.sync!
|
220
222
|
|
221
223
|
This command will read the contents of the register from the DUT and display it by bit field.
|
222
224
|
|
223
225
|
~~~
|
224
|
-
(debugger prompt): dut.reg(:
|
226
|
+
(debugger prompt): dut.reg(:My_Reg).sync!
|
227
|
+
|
228
|
+
0x3B4 - :My_Reg
|
229
|
+
===============================================================================================================
|
230
|
+
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 |
|
231
|
+
| unused[16:9] |
|
232
|
+
| 0x0 |
|
233
|
+
---------------------------------------------------------------------------------------------------------------
|
234
|
+
| 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
|
235
|
+
| unused[8:1] |
|
236
|
+
| 0x0 |
|
237
|
+
---------------------------------------------------------------------------------------------------------------
|
238
|
+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
|
239
|
+
| unused[0:0] | result[14:8] |
|
240
|
+
| 0x0 | 0x1C |
|
241
|
+
---------------------------------------------------------------------------------------------------------------
|
242
|
+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
243
|
+
| result[7:0] |
|
244
|
+
| 0x98 |
|
245
|
+
---------------------------------------------------------------------------------------------------------------
|
225
246
|
~~~
|
226
247
|
|
227
|
-
|
248
|
+
##### When A Shared Server Session Isn't Properly Ended
|
249
|
+
|
250
|
+
The server is able to handle multiple users. Once a user connects to the server, it will only allow access from that same IP address and user name until the session has ended. The session end command is transmitted when pattern generation is completed. If a user fails to properly end their session (happens when you exit debug mode by typing 'q' instead of 'c'), the server application will continue to lock out access until the time out has expired (20 minutes). Before terminating a running session, check with the user who started the session to make sure they aren't in the middle of debug (the user id and IP address will be displayed when you try to connect).
|
251
|
+
|
252
|
+
~~~
|
253
|
+
...origen/work 224$ origen g pattern/sar_debug.rb
|
254
|
+
[ERROR] 0.011[0.011] || Busy: server is in use by joshua from IP address 10.84.152.212
|
255
|
+
retry in 1 second
|
256
|
+
[ERROR] 1.039[1.028] || Busy: server is in use by joshua from IP address 10.84.152.212
|
257
|
+
retry in 1 second
|
258
|
+
[ERROR] 2.203[1.164] || Busy: server is in use by joshua from IP address 10.84.152.212
|
259
|
+
retry in 1 second
|
260
|
+
~~~
|
228
261
|
|
229
|
-
|
262
|
+
If the previous session needs to be manually terminated, this is how you do it (this should be a rare exception to the rule - it's bad manners to forcefully kill another user's session):
|
230
263
|
|
231
264
|
~~~ruby
|
232
|
-
# run this code to forcefully terminate a session
|
233
265
|
require 'socket'
|
266
|
+
require 'etc'
|
267
|
+
|
268
|
+
user_name = Etc.getlogin
|
234
269
|
|
235
270
|
TCPSocket.open('udooneo-computer-name', 12777) do |link|
|
236
|
-
link.puts("
|
237
|
-
while received = link.gets
|
238
|
-
puts received
|
239
|
-
end
|
240
|
-
link.puts("session_kill\n\n")
|
271
|
+
link.puts("#{user_name}\nsession_kill\n\n")
|
241
272
|
while received = link.gets
|
242
273
|
puts received
|
243
274
|
end
|
@@ -255,7 +286,9 @@ This section describes how to setup a new IOT device to serve the OrigenLink pin
|
|
255
286
|
|
256
287
|
Here are the steps to take to setup a new UDOO-Neo to run the OrigenLink server application. These instructions are not intended to be exhaustive, but should be good enough to get you up and running.
|
257
288
|
|
258
|
-
|
289
|
+
##### Change the name of the computer to something unique (like udooneo-myname).
|
290
|
+
|
291
|
+
This name is the string that you will enter in your environment ruby file for your app. Your computer running origen g pattern/my_pattern.rb and the UDOO should be attached to the same network (either through USB or ethernet)
|
259
292
|
|
260
293
|
~~~
|
261
294
|
prompt$> sudo nano /etc/hostname
|
@@ -266,13 +299,13 @@ prompt$> sudo nano /etc/hostname
|
|
266
299
|
OrigenLink::VectorBased.new('<ServerComputerName -- or IP_Address>', 12777)
|
267
300
|
~~~
|
268
301
|
|
269
|
-
|
302
|
+
##### Disable the M4 core (allows access to all IO's from unix)
|
270
303
|
|
271
304
|
~~~
|
272
305
|
menu -> preferences -> Udoo web configuration -> Advanced settings
|
273
306
|
~~~
|
274
307
|
|
275
|
-
|
308
|
+
##### Install ruby. This is a decision point. If you want to install the OrigenLink gem, the steps are a bit more complicated.
|
276
309
|
|
277
310
|
** Option 1 (I want the gem): You need to install ruby 2.2.
|
278
311
|
|
@@ -288,7 +321,7 @@ prompt$> sudo apt-get ruby22
|
|
288
321
|
prompt$> sudo apt-get ruby
|
289
322
|
~~~
|
290
323
|
|
291
|
-
|
324
|
+
##### Install the OrigenLink server.
|
292
325
|
|
293
326
|
** Option 1 (if you installed ruby22 you can do this). Install origen and origen_link gems.
|
294
327
|
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Derouen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|