origen_link 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/start_link_server +116 -116
- 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 +5 -5
- 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 +236 -236
- data/lib/origen_link/listener.rb +78 -78
- data/lib/origen_link/server/jtag.rb +251 -251
- data/lib/origen_link/server/pin.rb +218 -218
- data/lib/origen_link/server/sequencer.rb +469 -469
- data/lib/origen_link/server_com.rb +154 -154
- data/lib/origen_link/test/top_level.rb +48 -48
- data/lib/origen_link/test/top_level_controller.rb +46 -46
- data/lib/origen_link/test/vector_based.rb +25 -25
- data/lib/origen_link/vector_based.rb +526 -524
- 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 +470 -451
- 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 -3
data/config/commands.rb
CHANGED
@@ -1,74 +1,74 @@
|
|
1
|
-
# This file should be used to extend the origen with application specific commands
|
2
|
-
|
3
|
-
# Map any command aliases here, for example to allow 'origen ex' to refer to a
|
4
|
-
# command called execute you would add a reference as shown below:
|
5
|
-
aliases ={
|
6
|
-
# "ex" => "execute",
|
7
|
-
}
|
8
|
-
|
9
|
-
# The requested command is passed in here as @command, this checks it against
|
10
|
-
# the above alias table and should not be removed.
|
11
|
-
@command = aliases[@command] || @command
|
12
|
-
|
13
|
-
# Now branch to the specific task code
|
14
|
-
case @command
|
15
|
-
|
16
|
-
# Here is an example of how to implement a command, the logic can go straight
|
17
|
-
# in here or you can require an external file if preferred.
|
18
|
-
when "my_command"
|
19
|
-
puts "Doing something..."
|
20
|
-
#require "commands/my_command" # Would load file lib/commands/my_command.rb
|
21
|
-
# You must always exit upon successfully capturing a command to prevent
|
22
|
-
# control flowing back to Origen
|
23
|
-
exit 0
|
24
|
-
|
25
|
-
## Example of how to make a command to run unit tests, this simply invokes RSpec on
|
26
|
-
## the spec directory
|
27
|
-
#when "specs"
|
28
|
-
# require "rspec"
|
29
|
-
# exit RSpec::Core::Runner.run(['spec'])
|
30
|
-
|
31
|
-
## Example of how to make a command to run diff-based tests
|
32
|
-
#when "examples", "test"
|
33
|
-
# Origen.load_application
|
34
|
-
# status = 0
|
35
|
-
#
|
36
|
-
# # Compiler tests
|
37
|
-
# ARGV = %w(templates/example.txt.erb -t debug -r approved)
|
38
|
-
# load "origen/commands/compile.rb"
|
39
|
-
# # Pattern generator tests
|
40
|
-
# #ARGV = %w(some_pattern -t debug -r approved)
|
41
|
-
# #load "#{Origen.top}/lib/origen/commands/generate.rb"
|
42
|
-
#
|
43
|
-
# if Origen.app.stats.changed_files == 0 &&
|
44
|
-
# Origen.app.stats.new_files == 0 &&
|
45
|
-
# Origen.app.stats.changed_patterns == 0 &&
|
46
|
-
# Origen.app.stats.new_patterns == 0
|
47
|
-
#
|
48
|
-
# Origen.app.stats.report_pass
|
49
|
-
# else
|
50
|
-
# Origen.app.stats.report_fail
|
51
|
-
# status = 1
|
52
|
-
# end
|
53
|
-
# puts
|
54
|
-
# if @command == "test"
|
55
|
-
# Origen.app.unload_target!
|
56
|
-
# require "rspec"
|
57
|
-
# result = RSpec::Core::Runner.run(['spec'])
|
58
|
-
# status = status == 1 ? 1 : result
|
59
|
-
# end
|
60
|
-
# exit status # Exit with a 1 on the event of a failure per std unix result codes
|
61
|
-
|
62
|
-
# Always leave an else clause to allow control to fall back through to the
|
63
|
-
# Origen command handler.
|
64
|
-
else
|
65
|
-
# You probably want to also add the your commands to the help shown via
|
66
|
-
# origen -h, you can do this be assigning the required text to @application_commands
|
67
|
-
# before handing control back to Origen. Un-comment the example below to get started.
|
68
|
-
# @application_commands = <<-EOT
|
69
|
-
# specs Run the specs (tests), -c will enable coverage
|
70
|
-
# examples Run the examples (tests), -c will enable coverage
|
71
|
-
# test Run both specs and examples, -c will enable coverage
|
72
|
-
# EOT
|
73
|
-
|
74
|
-
end
|
1
|
+
# This file should be used to extend the origen with application specific commands
|
2
|
+
|
3
|
+
# Map any command aliases here, for example to allow 'origen ex' to refer to a
|
4
|
+
# command called execute you would add a reference as shown below:
|
5
|
+
aliases ={
|
6
|
+
# "ex" => "execute",
|
7
|
+
}
|
8
|
+
|
9
|
+
# The requested command is passed in here as @command, this checks it against
|
10
|
+
# the above alias table and should not be removed.
|
11
|
+
@command = aliases[@command] || @command
|
12
|
+
|
13
|
+
# Now branch to the specific task code
|
14
|
+
case @command
|
15
|
+
|
16
|
+
# Here is an example of how to implement a command, the logic can go straight
|
17
|
+
# in here or you can require an external file if preferred.
|
18
|
+
when "my_command"
|
19
|
+
puts "Doing something..."
|
20
|
+
#require "commands/my_command" # Would load file lib/commands/my_command.rb
|
21
|
+
# You must always exit upon successfully capturing a command to prevent
|
22
|
+
# control flowing back to Origen
|
23
|
+
exit 0
|
24
|
+
|
25
|
+
## Example of how to make a command to run unit tests, this simply invokes RSpec on
|
26
|
+
## the spec directory
|
27
|
+
#when "specs"
|
28
|
+
# require "rspec"
|
29
|
+
# exit RSpec::Core::Runner.run(['spec'])
|
30
|
+
|
31
|
+
## Example of how to make a command to run diff-based tests
|
32
|
+
#when "examples", "test"
|
33
|
+
# Origen.load_application
|
34
|
+
# status = 0
|
35
|
+
#
|
36
|
+
# # Compiler tests
|
37
|
+
# ARGV = %w(templates/example.txt.erb -t debug -r approved)
|
38
|
+
# load "origen/commands/compile.rb"
|
39
|
+
# # Pattern generator tests
|
40
|
+
# #ARGV = %w(some_pattern -t debug -r approved)
|
41
|
+
# #load "#{Origen.top}/lib/origen/commands/generate.rb"
|
42
|
+
#
|
43
|
+
# if Origen.app.stats.changed_files == 0 &&
|
44
|
+
# Origen.app.stats.new_files == 0 &&
|
45
|
+
# Origen.app.stats.changed_patterns == 0 &&
|
46
|
+
# Origen.app.stats.new_patterns == 0
|
47
|
+
#
|
48
|
+
# Origen.app.stats.report_pass
|
49
|
+
# else
|
50
|
+
# Origen.app.stats.report_fail
|
51
|
+
# status = 1
|
52
|
+
# end
|
53
|
+
# puts
|
54
|
+
# if @command == "test"
|
55
|
+
# Origen.app.unload_target!
|
56
|
+
# require "rspec"
|
57
|
+
# result = RSpec::Core::Runner.run(['spec'])
|
58
|
+
# status = status == 1 ? 1 : result
|
59
|
+
# end
|
60
|
+
# exit status # Exit with a 1 on the event of a failure per std unix result codes
|
61
|
+
|
62
|
+
# Always leave an else clause to allow control to fall back through to the
|
63
|
+
# Origen command handler.
|
64
|
+
else
|
65
|
+
# You probably want to also add the your commands to the help shown via
|
66
|
+
# origen -h, you can do this be assigning the required text to @application_commands
|
67
|
+
# before handing control back to Origen. Un-comment the example below to get started.
|
68
|
+
# @application_commands = <<-EOT
|
69
|
+
# specs Run the specs (tests), -c will enable coverage
|
70
|
+
# examples Run the examples (tests), -c will enable coverage
|
71
|
+
# test Run both specs and examples, -c will enable coverage
|
72
|
+
# EOT
|
73
|
+
|
74
|
+
end
|
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 = 4
|
4
|
-
BUGFIX =
|
5
|
-
DEV = nil
|
6
|
-
|
7
|
-
VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
|
8
|
-
end
|
1
|
+
module OrigenLink
|
2
|
+
MAJOR = 0
|
3
|
+
MINOR = 4
|
4
|
+
BUGFIX = 3
|
5
|
+
DEV = nil
|
6
|
+
|
7
|
+
VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
|
8
|
+
end
|
data/lib/origen_link.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'origen'
|
2
|
-
require 'socket'
|
3
|
-
require 'origen_link/vector_based'
|
4
|
-
require 'origen_link/listener'
|
5
|
-
require_relative '../config/version'
|
1
|
+
require 'origen'
|
2
|
+
require 'socket'
|
3
|
+
require 'origen_link/vector_based'
|
4
|
+
require 'origen_link/listener'
|
5
|
+
require_relative '../config/version'
|
@@ -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
|