origen_link 0.2.0.pre0 → 0.2.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 +66 -66
- data/config/application.rb +109 -109
- data/config/commands.rb +74 -74
- data/config/shared_commands.rb +40 -40
- data/config/version.rb +8 -8
- data/lib/origen_link.rb +4 -4
- data/lib/origen_link/callback_handlers.rb +13 -13
- data/lib/origen_link/capture_support.rb +94 -94
- data/lib/origen_link/configuration_commands.rb +84 -84
- data/lib/origen_link/listener.rb +78 -78
- data/lib/origen_link/server/jtag.rb +180 -180
- data/lib/origen_link/server/pin.rb +121 -121
- data/lib/origen_link/server/sequencer.rb +361 -361
- data/lib/origen_link/server_com.rb +150 -150
- data/lib/origen_link/test/top_level.rb +48 -48
- data/lib/origen_link/test/top_level_controller.rb +44 -44
- data/lib/origen_link/test/vector_based.rb +25 -25
- data/lib/origen_link/vector_based.rb +366 -365
- data/lib/tasks/origen_link.rake +6 -6
- data/pattern/example.rb +4 -4
- data/pattern/jtag_capture_id.rb +22 -22
- data/pattern/transaction_test.rb +18 -18
- data/templates/web/index.md.erb +25 -25
- data/templates/web/layouts/_basic.html.erb +13 -13
- data/templates/web/partials/_navbar.html.erb +20 -20
- data/templates/web/release_notes.md.erb +5 -5
- metadata +3 -4
data/config/shared_commands.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
1
|
-
# The requested command is passed in here as @command
|
2
|
-
case @command
|
3
|
-
|
4
|
-
when "link:listen"
|
5
|
-
t = Thread.new do
|
6
|
-
OrigenLink::Listener.run!
|
7
|
-
end
|
8
|
-
Thread.new do
|
9
|
-
# Get the current host
|
10
|
-
host = `hostname`.strip.downcase
|
11
|
-
if Origen.os.windows?
|
12
|
-
domain = '' # Not sure what to do in this case...
|
13
|
-
else
|
14
|
-
domain = `dnsdomainname`.strip
|
15
|
-
end
|
16
|
-
port = 20020
|
17
|
-
puts ''
|
18
|
-
sleep 0.5
|
19
|
-
puts
|
20
|
-
puts
|
21
|
-
puts "*************************************************************"
|
22
|
-
puts "Point your OrigenLink app to: http://#{host}#{domain.empty? ? '' : '.' + domain}:#{port}"
|
23
|
-
puts "*************************************************************"
|
24
|
-
puts
|
25
|
-
puts
|
26
|
-
end
|
27
|
-
|
28
|
-
# Fall through to the Origen interactive command to open up a console
|
29
|
-
@command = "interactive"
|
30
|
-
|
31
|
-
# Always leave an else clause to allow control to fall back through to the Origen command handler.
|
32
|
-
# You probably want to also add the command details to the help shown via 'origen -h',
|
33
|
-
# you can do this bb adding the required text to @plugin_commands before handing control back to
|
34
|
-
# Origen.
|
35
|
-
else
|
36
|
-
@plugin_commands << <<-EOT
|
37
|
-
link:listen Open a console and listen for OrigenLink requests over http (i.e. from a GUI)
|
38
|
-
EOT
|
39
|
-
|
40
|
-
end
|
1
|
+
# The requested command is passed in here as @command
|
2
|
+
case @command
|
3
|
+
|
4
|
+
when "link:listen"
|
5
|
+
t = Thread.new do
|
6
|
+
OrigenLink::Listener.run!
|
7
|
+
end
|
8
|
+
Thread.new do
|
9
|
+
# Get the current host
|
10
|
+
host = `hostname`.strip.downcase
|
11
|
+
if Origen.os.windows?
|
12
|
+
domain = '' # Not sure what to do in this case...
|
13
|
+
else
|
14
|
+
domain = `dnsdomainname`.strip
|
15
|
+
end
|
16
|
+
port = 20020
|
17
|
+
puts ''
|
18
|
+
sleep 0.5
|
19
|
+
puts
|
20
|
+
puts
|
21
|
+
puts "*************************************************************"
|
22
|
+
puts "Point your OrigenLink app to: http://#{host}#{domain.empty? ? '' : '.' + domain}:#{port}"
|
23
|
+
puts "*************************************************************"
|
24
|
+
puts
|
25
|
+
puts
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fall through to the Origen interactive command to open up a console
|
29
|
+
@command = "interactive"
|
30
|
+
|
31
|
+
# Always leave an else clause to allow control to fall back through to the Origen command handler.
|
32
|
+
# You probably want to also add the command details to the help shown via 'origen -h',
|
33
|
+
# you can do this bb adding the required text to @plugin_commands before handing control back to
|
34
|
+
# Origen.
|
35
|
+
else
|
36
|
+
@plugin_commands << <<-EOT
|
37
|
+
link:listen Open a console and listen for OrigenLink requests over http (i.e. from a GUI)
|
38
|
+
EOT
|
39
|
+
|
40
|
+
end
|
data/config/version.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
module OrigenLink
|
2
|
-
MAJOR = 0
|
3
|
-
MINOR = 2
|
4
|
-
BUGFIX = 0
|
5
|
-
DEV =
|
6
|
-
|
7
|
-
VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
|
8
|
-
end
|
1
|
+
module OrigenLink
|
2
|
+
MAJOR = 0
|
3
|
+
MINOR = 2
|
4
|
+
BUGFIX = 0
|
5
|
+
DEV = nil
|
6
|
+
|
7
|
+
VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
|
8
|
+
end
|
data/lib/origen_link.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'origen'
|
2
|
-
require 'socket'
|
3
|
-
require 'origen_link/vector_based'
|
4
|
-
require 'origen_link/listener'
|
1
|
+
require 'origen'
|
2
|
+
require 'socket'
|
3
|
+
require 'origen_link/vector_based'
|
4
|
+
require 'origen_link/listener'
|
@@ -1,13 +1,13 @@
|
|
1
|
-
module OrigenLink
|
2
|
-
class CallbackHandlers
|
3
|
-
include Origen::Callbacks
|
4
|
-
|
5
|
-
def pattern_generated(output_file)
|
6
|
-
tester.finalize_pattern(output_file)
|
7
|
-
end
|
8
|
-
|
9
|
-
def before_pattern(pattern_name)
|
10
|
-
tester.initialize_pattern
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
1
|
+
module OrigenLink
|
2
|
+
class CallbackHandlers
|
3
|
+
include Origen::Callbacks
|
4
|
+
|
5
|
+
def pattern_generated(output_file)
|
6
|
+
tester.finalize_pattern(output_file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def before_pattern(pattern_name)
|
10
|
+
tester.initialize_pattern
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,94 +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
|
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
|
@@ -1,84 +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
|
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
|