origen 0.2.6 → 0.3.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/bin/origen +3 -1
- data/config/boot.rb +1 -7
- data/config/commands.rb +0 -1
- data/config/version.rb +2 -2
- data/lib/c99/{j750_interface.rb → ate_interface.rb} +3 -11
- data/lib/c99/doc_interface.rb +1 -1
- data/lib/origen.rb +9 -30
- data/lib/origen/application.rb +10 -8
- data/lib/origen/application/configuration.rb +13 -26
- data/lib/origen/application/plugins.rb +122 -0
- data/lib/origen/application/plugins_manager.rb +16 -254
- data/lib/origen/application/release.rb +2 -2
- data/lib/origen/application/runner.rb +2 -4
- data/lib/origen/chips.rb +0 -0
- data/lib/origen/chips/chip.rb +0 -0
- data/lib/origen/chips/design_entry.rb +0 -0
- data/lib/origen/chips/doc_entry.rb +0 -0
- data/lib/origen/chips/note.rb +0 -0
- data/lib/origen/commands.rb +4 -44
- data/lib/origen/commands/compile.rb +1 -2
- data/lib/origen/commands/generate.rb +1 -1
- data/lib/origen/commands/interactive.rb +1 -2
- data/lib/origen/commands/plugin.rb +49 -56
- data/lib/origen/commands/program.rb +1 -1
- data/lib/origen/commands/rc.rb +2 -2
- data/lib/origen/commands/version.rb +2 -17
- data/lib/origen/commands_global.rb +3 -0
- data/lib/origen/file_handler.rb +10 -10
- data/lib/origen/generator.rb +1 -1
- data/lib/origen/generator/job.rb +1 -1
- data/lib/origen/generator/pattern.rb +2 -2
- data/lib/origen/generator/pattern_finder.rb +10 -9
- data/lib/origen/pins/pin.rb +0 -0
- data/lib/origen/regression_manager.rb +0 -0
- data/lib/origen/remote_manager.rb +2 -8
- data/lib/origen/revision_control/design_sync.rb +0 -0
- data/lib/origen/revision_control/git.rb +0 -0
- data/lib/origen/specs.rb +0 -0
- data/lib/origen/specs/checkers.rb +0 -0
- data/lib/origen/specs/creation_info.rb +0 -0
- data/lib/origen/specs/exhibit.rb +0 -0
- data/lib/origen/specs/spec.rb +0 -0
- data/lib/origen/utility.rb +0 -1
- data/lib/origen/utility/diff.rb +0 -0
- metadata +42 -119
- data/lib/origen/import_manager.rb +0 -596
- data/lib/origen/nvm.rb +0 -6
- data/lib/origen/nvm/block_array.rb +0 -72
- data/lib/origen/tester.rb +0 -56
- data/lib/origen/tester/api.rb +0 -277
- data/lib/origen/tester/bdm/bdm.rb +0 -25
- data/lib/origen/tester/doc/doc.rb +0 -226
- data/lib/origen/tester/doc/generator.rb +0 -126
- data/lib/origen/tester/doc/generator/flow.rb +0 -71
- data/lib/origen/tester/doc/generator/flow_line.rb +0 -203
- data/lib/origen/tester/doc/generator/test.rb +0 -68
- data/lib/origen/tester/doc/generator/test_group.rb +0 -66
- data/lib/origen/tester/doc/generator/tests.rb +0 -47
- data/lib/origen/tester/doc/model.rb +0 -162
- data/lib/origen/tester/generator.rb +0 -271
- data/lib/origen/tester/generator/flow_control_api.rb +0 -606
- data/lib/origen/tester/generator/identity_map.rb +0 -25
- data/lib/origen/tester/generator/placeholder.rb +0 -13
- data/lib/origen/tester/generator/test_numberer.rb +0 -25
- data/lib/origen/tester/interface.rb +0 -154
- data/lib/origen/tester/j750/files.rb +0 -45
- data/lib/origen/tester/j750/generator.rb +0 -203
- data/lib/origen/tester/j750/generator/flow.rb +0 -123
- data/lib/origen/tester/j750/generator/flow_line.rb +0 -288
- data/lib/origen/tester/j750/generator/patgroup.rb +0 -111
- data/lib/origen/tester/j750/generator/patgroups.rb +0 -41
- data/lib/origen/tester/j750/generator/patset.rb +0 -111
- data/lib/origen/tester/j750/generator/patsets.rb +0 -41
- data/lib/origen/tester/j750/generator/templates/flow.txt.erb +0 -9
- data/lib/origen/tester/j750/generator/templates/instances.txt.erb +0 -16
- data/lib/origen/tester/j750/generator/templates/patgroups.txt.erb +0 -8
- data/lib/origen/tester/j750/generator/templates/patsets.txt.erb +0 -10
- data/lib/origen/tester/j750/generator/test_instance.rb +0 -846
- data/lib/origen/tester/j750/generator/test_instance_group.rb +0 -60
- data/lib/origen/tester/j750/generator/test_instances.rb +0 -182
- data/lib/origen/tester/j750/j750.rb +0 -845
- data/lib/origen/tester/j750/j750_hpt.rb +0 -35
- data/lib/origen/tester/j750/parser.rb +0 -104
- data/lib/origen/tester/j750/parser/ac_spec.rb +0 -11
- data/lib/origen/tester/j750/parser/ac_specs.rb +0 -0
- data/lib/origen/tester/j750/parser/dc_spec.rb +0 -36
- data/lib/origen/tester/j750/parser/dc_specs.rb +0 -50
- data/lib/origen/tester/j750/parser/descriptions.rb +0 -340
- data/lib/origen/tester/j750/parser/flow.rb +0 -111
- data/lib/origen/tester/j750/parser/flow_line.rb +0 -207
- data/lib/origen/tester/j750/parser/flows.rb +0 -23
- data/lib/origen/tester/j750/parser/pattern_set.rb +0 -94
- data/lib/origen/tester/j750/parser/pattern_sets.rb +0 -33
- data/lib/origen/tester/j750/parser/test_instance.rb +0 -322
- data/lib/origen/tester/j750/parser/test_instances.rb +0 -26
- data/lib/origen/tester/j750/parser/timeset.rb +0 -15
- data/lib/origen/tester/j750/parser/timesets.rb +0 -0
- data/lib/origen/tester/jlink/jlink.rb +0 -33
- data/lib/origen/tester/parser.rb +0 -24
- data/lib/origen/tester/parser/description_lookup.rb +0 -64
- data/lib/origen/tester/parser/searchable_array.rb +0 -32
- data/lib/origen/tester/parser/searchable_hash.rb +0 -32
- data/lib/origen/tester/time.rb +0 -338
- data/lib/origen/tester/timing.rb +0 -253
- data/lib/origen/tester/ultraflex/files.rb +0 -45
- data/lib/origen/tester/ultraflex/generator.rb +0 -200
- data/lib/origen/tester/ultraflex/generator/flow.rb +0 -119
- data/lib/origen/tester/ultraflex/generator/flow_line.rb +0 -269
- data/lib/origen/tester/ultraflex/generator/patgroup.rb +0 -111
- data/lib/origen/tester/ultraflex/generator/patgroups.rb +0 -41
- data/lib/origen/tester/ultraflex/generator/patset.rb +0 -111
- data/lib/origen/tester/ultraflex/generator/patsets.rb +0 -41
- data/lib/origen/tester/ultraflex/generator/templates/flow.txt.erb +0 -9
- data/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb +0 -16
- data/lib/origen/tester/ultraflex/generator/templates/patgroups.txt.erb +0 -8
- data/lib/origen/tester/ultraflex/generator/templates/patsets.txt.erb +0 -10
- data/lib/origen/tester/ultraflex/generator/test_instance.rb +0 -622
- data/lib/origen/tester/ultraflex/generator/test_instance_group.rb +0 -60
- data/lib/origen/tester/ultraflex/generator/test_instances.rb +0 -174
- data/lib/origen/tester/ultraflex/parser.rb +0 -104
- data/lib/origen/tester/ultraflex/parser/ac_spec.rb +0 -11
- data/lib/origen/tester/ultraflex/parser/ac_specs.rb +0 -0
- data/lib/origen/tester/ultraflex/parser/dc_spec.rb +0 -36
- data/lib/origen/tester/ultraflex/parser/dc_specs.rb +0 -50
- data/lib/origen/tester/ultraflex/parser/descriptions.rb +0 -342
- data/lib/origen/tester/ultraflex/parser/flow.rb +0 -111
- data/lib/origen/tester/ultraflex/parser/flow_line.rb +0 -207
- data/lib/origen/tester/ultraflex/parser/flows.rb +0 -23
- data/lib/origen/tester/ultraflex/parser/pattern_set.rb +0 -94
- data/lib/origen/tester/ultraflex/parser/pattern_sets.rb +0 -33
- data/lib/origen/tester/ultraflex/parser/test_instance.rb +0 -262
- data/lib/origen/tester/ultraflex/parser/test_instances.rb +0 -26
- data/lib/origen/tester/ultraflex/parser/timeset.rb +0 -15
- data/lib/origen/tester/ultraflex/parser/timesets.rb +0 -0
- data/lib/origen/tester/ultraflex/ultraflex.rb +0 -759
- data/lib/origen/tester/v93k/generator.rb +0 -80
- data/lib/origen/tester/v93k/generator/flow.rb +0 -63
- data/lib/origen/tester/v93k/generator/flow_node.rb +0 -17
- data/lib/origen/tester/v93k/generator/flow_node/print.rb +0 -10
- data/lib/origen/tester/v93k/generator/pattern.rb +0 -16
- data/lib/origen/tester/v93k/generator/pattern_master.rb +0 -54
- data/lib/origen/tester/v93k/generator/templates/_test_method.txt.erb +0 -6
- data/lib/origen/tester/v93k/generator/templates/_test_suite.txt.erb +0 -11
- data/lib/origen/tester/v93k/generator/templates/template.flow.erb +0 -121
- data/lib/origen/tester/v93k/generator/templates/template.pmfl.erb +0 -9
- data/lib/origen/tester/v93k/generator/test_function.rb +0 -103
- data/lib/origen/tester/v93k/generator/test_functions.rb +0 -79
- data/lib/origen/tester/v93k/generator/test_method.rb +0 -46
- data/lib/origen/tester/v93k/generator/test_methods.rb +0 -75
- data/lib/origen/tester/v93k/generator/test_suite.rb +0 -54
- data/lib/origen/tester/v93k/generator/test_suites.rb +0 -65
- data/lib/origen/tester/v93k/v93k.rb +0 -420
- data/lib/origen/tester/vector.rb +0 -86
- data/lib/origen/tester/vector_generator.rb +0 -637
- data/lib/origen/tester/vector_pipeline.rb +0 -150
- data/lib/origen/utility/design_sync.rb +0 -494
- data/lib/origen/version_checker.rb +0 -117
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Origen
|
|
2
|
-
module Tester
|
|
3
|
-
module Parser
|
|
4
|
-
class SearchableArray < ::Array
|
|
5
|
-
def where(conditions)
|
|
6
|
-
exact = conditions.delete(:exact)
|
|
7
|
-
results = SearchableArray.new
|
|
8
|
-
each do |item|
|
|
9
|
-
if conditions.all? do |attr, val|
|
|
10
|
-
if val.is_a?(Array)
|
|
11
|
-
if exact
|
|
12
|
-
val.any? { |v| item.send(attr).to_s == v.to_s }
|
|
13
|
-
else
|
|
14
|
-
val.any? { |v| item.send(attr).to_s =~ /#{v.to_s}/ }
|
|
15
|
-
end
|
|
16
|
-
else
|
|
17
|
-
if exact
|
|
18
|
-
item.send(attr).to_s == val.to_s
|
|
19
|
-
else
|
|
20
|
-
item.send(attr).to_s =~ /#{val.to_s}/
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
results << item
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
results
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Origen
|
|
2
|
-
module Tester
|
|
3
|
-
module Parser
|
|
4
|
-
class SearchableHash < ::Hash
|
|
5
|
-
def where(conditions)
|
|
6
|
-
exact = conditions.delete(:exact)
|
|
7
|
-
results = SearchableArray.new
|
|
8
|
-
each do |_key, item|
|
|
9
|
-
if conditions.all? do |attr, val|
|
|
10
|
-
if val.is_a?(Array)
|
|
11
|
-
if exact
|
|
12
|
-
val.any? { |v| item.send(attr).to_s == v.to_s }
|
|
13
|
-
else
|
|
14
|
-
val.any? { |v| item.send(attr).to_s =~ /#{v.to_s}/ }
|
|
15
|
-
end
|
|
16
|
-
else
|
|
17
|
-
if exact
|
|
18
|
-
item.send(attr).to_s == val.to_s
|
|
19
|
-
else
|
|
20
|
-
item.send(attr).to_s =~ /#{val.to_s}/
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
results << item
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
results
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
data/lib/origen/tester/time.rb
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
module Origen
|
|
2
|
-
module Tester
|
|
3
|
-
# Class for handling test time analysis - implements the functionality
|
|
4
|
-
# exposed via the 'origen time' command
|
|
5
|
-
class Time
|
|
6
|
-
require 'yaml'
|
|
7
|
-
|
|
8
|
-
TT_LIB_DIR = "#{Origen.root}/config/test_time/lib"
|
|
9
|
-
TT_FLOW_DIR = "#{Origen.root}/config/test_time/flow"
|
|
10
|
-
DEFAULT_LIBRARY = "#{TT_LIB_DIR}/default.yaml"
|
|
11
|
-
DEFAULT_FLOW = "#{TT_FLOW_DIR}/default.yaml"
|
|
12
|
-
|
|
13
|
-
# If any new embedded hashes are added to this a default of {} must also be added
|
|
14
|
-
# to the sanitize method
|
|
15
|
-
TEST_META_DATA = { 'rule' => nil,
|
|
16
|
-
'reference' => { 'rule_result' => nil,
|
|
17
|
-
'time' => nil,
|
|
18
|
-
'target' => nil
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
def stats
|
|
23
|
-
@stats ||= { imported: 0, rules_assigned: 0, reference_rules_evaluated: 0 }
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def clear_stats
|
|
27
|
-
@stats = nil
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Import a flow, this can be from either a datalog or an execution time
|
|
31
|
-
def import_test_flow(file, options = {})
|
|
32
|
-
clear_stats
|
|
33
|
-
@options = options
|
|
34
|
-
if Origen.tester.respond_to?('read_test_times')
|
|
35
|
-
tests = Origen.tester.read_test_times(file, options)
|
|
36
|
-
flow = []
|
|
37
|
-
merge_indexed_tests(tests) do |name, _attrs|
|
|
38
|
-
if import?(name)
|
|
39
|
-
Origen.log.info "imported... #{name}"
|
|
40
|
-
flow << name
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
puts ''
|
|
44
|
-
puts 'Import complete!'
|
|
45
|
-
puts ''
|
|
46
|
-
export_flow(flow, options)
|
|
47
|
-
else
|
|
48
|
-
error 'Sorry, no test time import method is defined for the current tester'
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def import_test_time(file, options = {})
|
|
53
|
-
clear_stats
|
|
54
|
-
@options = options
|
|
55
|
-
if Origen.tester.respond_to?('read_test_times')
|
|
56
|
-
tests = Origen.tester.read_test_times(file, options)
|
|
57
|
-
total = extract_total_time(tests)
|
|
58
|
-
flow = []
|
|
59
|
-
library = {}
|
|
60
|
-
imported = 0.0
|
|
61
|
-
merge_indexed_tests(tests) do |name, attrs|
|
|
62
|
-
attrs = sanitize(attrs)
|
|
63
|
-
|
|
64
|
-
if import?(name)
|
|
65
|
-
Origen.log.info "importing... #{name}"
|
|
66
|
-
flow << name
|
|
67
|
-
if library[name]
|
|
68
|
-
library[name] = merge(library[name], attrs)
|
|
69
|
-
else
|
|
70
|
-
library[name] = populate(name, attrs)
|
|
71
|
-
stats[:imported] += 1
|
|
72
|
-
end
|
|
73
|
-
imported += attrs['reference']['time']
|
|
74
|
-
# puts name
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
puts ''
|
|
78
|
-
puts 'Import complete!'
|
|
79
|
-
puts ''
|
|
80
|
-
puts 'Some stats...'
|
|
81
|
-
puts ''
|
|
82
|
-
puts "Tests imported: #{stats[:imported]}"
|
|
83
|
-
puts "Rules assigned: #{stats[:rules_assigned]}"
|
|
84
|
-
puts "Ref rules calculated: #{stats[:reference_rules_evaluated]}"
|
|
85
|
-
puts ''
|
|
86
|
-
puts 'Total time: ' + total.round(6).to_s + 's'
|
|
87
|
-
puts 'Total filtered time: ' + imported.round(6).to_s + 's'
|
|
88
|
-
if stats[:imported] == stats[:rules_assigned]
|
|
89
|
-
puts 'Forecasted: ' + calculate_time(flow, library, options.merge(silent: true)).to_s + 's'
|
|
90
|
-
else
|
|
91
|
-
puts 'Forecasted: SOME TESTS HAVE NO RULES ASSIGNED!'
|
|
92
|
-
end
|
|
93
|
-
puts ''
|
|
94
|
-
export_library(library, options)
|
|
95
|
-
else
|
|
96
|
-
error 'Sorry, no test time import method is defined for the current tester'
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def forecast_test_time(options = {})
|
|
101
|
-
clear_stats
|
|
102
|
-
@options = options
|
|
103
|
-
time = 0.0
|
|
104
|
-
flow = import_flow(input_flow_file(options))
|
|
105
|
-
library = import_library(input_library_file(options))['tests']
|
|
106
|
-
calculate_time(flow, library, options)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def output_library_file(options = {})
|
|
110
|
-
if options[:ref_name]
|
|
111
|
-
"#{TT_LIB_DIR}/#{options[:ref_name]}.yaml"
|
|
112
|
-
else
|
|
113
|
-
DEFAULT_LIBRARY
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def input_library_file(options = {})
|
|
118
|
-
output_library_file(options)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def output_flow_file(options = {})
|
|
122
|
-
if options[:ref_name]
|
|
123
|
-
"#{TT_FLOW_DIR}/#{options[:ref_name]}.yaml"
|
|
124
|
-
else
|
|
125
|
-
DEFAULT_FLOW
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def input_flow_file(options = {})
|
|
130
|
-
output_flow_file(options)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# Force the imported test data from the tester into a YAML compliant form
|
|
134
|
-
def sanitize(attrs)
|
|
135
|
-
# Force all keys to strings...
|
|
136
|
-
attrs.keys.each do |key|
|
|
137
|
-
begin
|
|
138
|
-
attrs[key.to_s] = attrs.delete(key)
|
|
139
|
-
rescue
|
|
140
|
-
# No problem
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
attrs['reference'] ||= {}
|
|
144
|
-
# attrs["opportunity"] ||= {}
|
|
145
|
-
if attrs['time']
|
|
146
|
-
attrs['reference']['time'] = attrs.delete('time')
|
|
147
|
-
end
|
|
148
|
-
deep_merge(TEST_META_DATA, attrs)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# Populate the attributes based on user specified rules
|
|
152
|
-
def populate(name, attrs, options = {})
|
|
153
|
-
if rules
|
|
154
|
-
r = rules.assign(name, attrs, options)
|
|
155
|
-
if r
|
|
156
|
-
stats[:rules_assigned] += 1
|
|
157
|
-
attrs['rule'] = r
|
|
158
|
-
else
|
|
159
|
-
warn "No rule assigned to: #{name}"
|
|
160
|
-
attrs.delete('rule')
|
|
161
|
-
end
|
|
162
|
-
r = rules.evaluate(name, attrs, options)
|
|
163
|
-
if r
|
|
164
|
-
stats[:reference_rules_evaluated] += 1
|
|
165
|
-
attrs['reference']['rule_result'] = r
|
|
166
|
-
else
|
|
167
|
-
warn "No reference rule result assigned to: #{name}"
|
|
168
|
-
attrs['reference'].delete('rule_result')
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
attrs['reference']['target'] = Origen.target.name
|
|
172
|
-
attrs
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def export_library(lib, options = {})
|
|
176
|
-
tests = {}
|
|
177
|
-
lib.each do |name, attrs|
|
|
178
|
-
tests[name] = attrs
|
|
179
|
-
end
|
|
180
|
-
Origen.file_handler.open_for_write(output_library_file(options)) do |f|
|
|
181
|
-
f.puts YAML.dump('tests' => tests)
|
|
182
|
-
end
|
|
183
|
-
puts "Test library exported to: #{Origen.file_handler.relative_path_to(output_library_file(options))}"
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def import_library(lib, _options = {})
|
|
187
|
-
YAML.load(File.open(lib))
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def export_flow(flow, options = {})
|
|
191
|
-
Origen.file_handler.open_for_write(output_flow_file(options)) do |f|
|
|
192
|
-
f.puts YAML.dump(flow)
|
|
193
|
-
end
|
|
194
|
-
puts "Test flow exported to: #{Origen.file_handler.relative_path_to(output_flow_file(options))}"
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def import_flow(flow, _options = {})
|
|
198
|
-
YAML.load(File.open(flow))
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
# Deep merge two hashes, the first one should be the defaults, the second one will override any
|
|
202
|
-
# items from the defaults
|
|
203
|
-
def deep_merge(hash1, hash2)
|
|
204
|
-
hash1.merge(hash2) do |_key, oldval, newval|
|
|
205
|
-
oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
|
|
206
|
-
newval = newval.to_hash if newval.respond_to?(:to_hash)
|
|
207
|
-
oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? deep_merge(oldval, newval) : newval
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
# Merge two sets of attributes for the same test, generally this means that the time will
|
|
212
|
-
# be averaged and all other attributes will remain the same
|
|
213
|
-
def merge(t1, t2)
|
|
214
|
-
t1['reference']['time'] = (t1['reference']['time'] + t2['reference']['time']) / 2
|
|
215
|
-
t1
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Calculate the time for the given flow, using times from the given library
|
|
219
|
-
def calculate_time(flow, library, options = {})
|
|
220
|
-
options = {
|
|
221
|
-
silent: false,
|
|
222
|
-
summary: false
|
|
223
|
-
}.merge(options)
|
|
224
|
-
unless options[:silent] || options[:summary]
|
|
225
|
-
Origen.log.info 'Test'.ljust(60) + 'Rule'.ljust(40) +
|
|
226
|
-
library.first[1]['reference']['target'].ljust(30) + Origen.target.name
|
|
227
|
-
orig = 0
|
|
228
|
-
end
|
|
229
|
-
forecasted = flow.reduce(0.0) do |sum, test|
|
|
230
|
-
if library[test]['include'] == false || library[test]['exclude'] == true
|
|
231
|
-
sum
|
|
232
|
-
else
|
|
233
|
-
orig += library[test]['reference']['time'] unless options[:silent] || options[:summary]
|
|
234
|
-
forecast = rules.forecast(test, library[test], options)
|
|
235
|
-
unless options[:silent] || options[:summary]
|
|
236
|
-
Origen.log.info test.ljust(60) + library[test]['rule'].to_s.ljust(40) +
|
|
237
|
-
"#{library[test]['reference']['time'].round(6)}".ljust(30) +
|
|
238
|
-
"#{forecast.round(6)}"
|
|
239
|
-
end
|
|
240
|
-
sum + forecast
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
if options[:silent]
|
|
244
|
-
forecasted.round(6)
|
|
245
|
-
elsif options[:summary]
|
|
246
|
-
Origen.log.info Origen.target.name.ljust(50) + "#{forecasted.round(6)}"
|
|
247
|
-
else
|
|
248
|
-
Origen.log.info ''
|
|
249
|
-
Origen.log.info ''.ljust(100) + '---------------'.ljust(30) + '---------------'
|
|
250
|
-
Origen.log.info ''.ljust(100) + "#{orig.round(6)}".ljust(30) + "#{forecasted.round(6)}"
|
|
251
|
-
Origen.log.info ''.ljust(100) + '---------------'.ljust(30) + '==============='
|
|
252
|
-
Origen.log.info ''
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
def extract_total_time(tests)
|
|
257
|
-
tests.reduce(0.0) { |sum, test| sum + test[:time] }
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
# This combines the test time from indexed tests and removes the :index and :group keys from all tests.
|
|
261
|
-
#
|
|
262
|
-
# If it is an indexed test then a single hash will be returned containing the total time and the key:
|
|
263
|
-
# {:indexed => true}.
|
|
264
|
-
def merge_indexed_tests(tests)
|
|
265
|
-
ix_counter = false
|
|
266
|
-
ix_group = false
|
|
267
|
-
ix_test = false
|
|
268
|
-
ix_total = false
|
|
269
|
-
|
|
270
|
-
tests.each do |t|
|
|
271
|
-
i = t.delete(:index)
|
|
272
|
-
g = t.delete(:group)
|
|
273
|
-
process = true
|
|
274
|
-
if ix_counter
|
|
275
|
-
if ix_test == t[:name]
|
|
276
|
-
process = false
|
|
277
|
-
warning "Incomplete index data from test: #{ix_test}" if i != ix_counter + 1
|
|
278
|
-
ix_counter = i
|
|
279
|
-
ix_total += t[:time]
|
|
280
|
-
# If the last test in the index
|
|
281
|
-
if i == ix_group
|
|
282
|
-
yield(ix_test, { time: ix_total, indexed: true })
|
|
283
|
-
ix_counter = false
|
|
284
|
-
end
|
|
285
|
-
else
|
|
286
|
-
warning "Incomplete index data from test: #{ix_test}"
|
|
287
|
-
yield(ix_test, { time: ix_total, indexed: true })
|
|
288
|
-
ix_counter = false
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
# Don't combine this with the above via an else, it is required to be separate to generate the
|
|
292
|
-
# next entry in the case where an index group was incomplete
|
|
293
|
-
if process
|
|
294
|
-
if i
|
|
295
|
-
# Ignore tests with an invalid index and a very short time, these occur from tests which
|
|
296
|
-
# are in the flow, but have not been executed in this run
|
|
297
|
-
unless i != 1 && t[:time] < 0.0001
|
|
298
|
-
ix_counter = i
|
|
299
|
-
ix_group = g
|
|
300
|
-
ix_test = t[:name]
|
|
301
|
-
ix_total = t[:time]
|
|
302
|
-
warning "Incomplete index data from test: #{t[:name]}" if ix_counter != 1
|
|
303
|
-
end
|
|
304
|
-
else
|
|
305
|
-
yield t.delete(:name), t
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
def import?(test)
|
|
312
|
-
if filter
|
|
313
|
-
filter.import?(test)
|
|
314
|
-
else
|
|
315
|
-
true
|
|
316
|
-
end
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
def filter
|
|
320
|
-
return @filter if defined?(@filter)
|
|
321
|
-
if defined?(TestTimeFilter)
|
|
322
|
-
@filter = TestTimeFilter.new
|
|
323
|
-
else
|
|
324
|
-
@filter = false
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
def rules
|
|
329
|
-
return @rules if defined?(@rules)
|
|
330
|
-
if defined?(TestTimeRules)
|
|
331
|
-
@rules = TestTimeRules.new
|
|
332
|
-
else
|
|
333
|
-
@rules = false
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
end
|
|
337
|
-
end
|
|
338
|
-
end
|
data/lib/origen/tester/timing.rb
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
module Origen
|
|
2
|
-
module Tester
|
|
3
|
-
module Timing
|
|
4
|
-
class Timeset
|
|
5
|
-
attr_accessor :name, :period_in_ns
|
|
6
|
-
|
|
7
|
-
def initialize(attrs = {})
|
|
8
|
-
attrs.each do |name, value|
|
|
9
|
-
send("#{name}=", value)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Set the timeset for the next vectors, this will remain in place until the next
|
|
15
|
-
# time this is called.
|
|
16
|
-
#
|
|
17
|
-
# $tester.set_timeset("bist_25mhz", 40)
|
|
18
|
-
#
|
|
19
|
-
# This method also accepts a block in which case the contained vectors will generate
|
|
20
|
-
# with the supplied timeset and subsequent vectors will return to the previous timeset
|
|
21
|
-
# automatically.
|
|
22
|
-
#
|
|
23
|
-
# $tester.set_timeset("bist_25mhz", 40) do
|
|
24
|
-
# $tester.cycle
|
|
25
|
-
# end
|
|
26
|
-
#
|
|
27
|
-
# The arguments can also be supplied as a single array, or not at all. In the latter case
|
|
28
|
-
# the existing timeset will simply be preserved. This is useful if you have timesets that
|
|
29
|
-
# can be conditionally set based on the target.
|
|
30
|
-
#
|
|
31
|
-
# # Target 1
|
|
32
|
-
# $soc.readout_timeset = ["readout", 120]
|
|
33
|
-
# # Target 2
|
|
34
|
-
# $soc.readout_timeset = false
|
|
35
|
-
#
|
|
36
|
-
# # This code is compatible with both targets, in the first case the timeset will switch
|
|
37
|
-
# # over, in the second case the existing timeset will be preserved.
|
|
38
|
-
# $tester.set_timeset($soc.readout_timeset) do
|
|
39
|
-
# $tester.cycle
|
|
40
|
-
# end
|
|
41
|
-
def set_timeset(timeset, period_in_ns = nil)
|
|
42
|
-
if timeset.is_a?(Array)
|
|
43
|
-
timeset, period_in_ns = timeset[0], timeset[1]
|
|
44
|
-
end
|
|
45
|
-
timeset ||= @timeset
|
|
46
|
-
unless timeset.is_a?(Timeset)
|
|
47
|
-
fail 'You must supply a period_in_ns argument to set_timeset' unless period_in_ns
|
|
48
|
-
timeset = Timeset.new(name: timeset.to_s.chomp, period_in_ns: period_in_ns)
|
|
49
|
-
end
|
|
50
|
-
called_timesets << timeset unless called_timesets.map(&:name).include?(timeset.name)
|
|
51
|
-
if block_given?
|
|
52
|
-
original = @timeset
|
|
53
|
-
timeset_changed(timeset)
|
|
54
|
-
@timeset = timeset
|
|
55
|
-
yield
|
|
56
|
-
timeset_changed(original)
|
|
57
|
-
@timeset = original
|
|
58
|
-
else
|
|
59
|
-
timeset_changed(timeset)
|
|
60
|
-
@timeset = timeset
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def timeset_changed(timeset)
|
|
65
|
-
if last_vector && last_vector.timeset != timeset
|
|
66
|
-
change = { old: last_vector.timeset, new: timeset }
|
|
67
|
-
# Suppress any duplicate calls
|
|
68
|
-
if !@_last_timeset_change ||
|
|
69
|
-
(@_last_timeset_change[:new] != change[:new] &&
|
|
70
|
-
@_last_timeset_change[:old] != change[:old])
|
|
71
|
-
before_timeset_change(change)
|
|
72
|
-
end
|
|
73
|
-
@_last_timeset_change = change
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def before_timeset_change(_options = {})
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Cause the pattern to wait.
|
|
81
|
-
# The following options are available to help you specify the time to wait:
|
|
82
|
-
# * :cycles - delays specified in raw cycles, the test model is responsible for translating this into a sequence of valid repeat statements
|
|
83
|
-
# * :time_in_ns - time specified in nano-seconds
|
|
84
|
-
# * :time_in_us - time specified in micro-seconds
|
|
85
|
-
# * :time_in_ms - time specified in milli-seconds
|
|
86
|
-
# * :time_in_s - time specified in seconds
|
|
87
|
-
# If more than one option is supplied they will get added together to give a final
|
|
88
|
-
# delay time expressed in cycles.
|
|
89
|
-
# ==== Examples
|
|
90
|
-
# $tester.wait(:cycles => 100, :time_in_ns => 200) # Wait for 100 cycles + 200ns
|
|
91
|
-
# This method can also be used to trigger a match loop in which case the supplied time
|
|
92
|
-
# becomes the time out for the match. See the J750#match method for full details of the
|
|
93
|
-
# available options.
|
|
94
|
-
# $tester.wait(:match => true, :state => :high, :pin => $top.pin(:done), :time_in_ms => 500)
|
|
95
|
-
def wait(options = {})
|
|
96
|
-
options = {
|
|
97
|
-
cycles: 0,
|
|
98
|
-
time_in_cycles: 0,
|
|
99
|
-
time_in_us: 0,
|
|
100
|
-
time_in_ns: 0,
|
|
101
|
-
time_in_ms: 0,
|
|
102
|
-
time_in_s: 0,
|
|
103
|
-
match: false, # Set to true to invoke a match loop where the supplied delay
|
|
104
|
-
# will become the timeout duration
|
|
105
|
-
}.merge(options)
|
|
106
|
-
|
|
107
|
-
cycles = 0
|
|
108
|
-
cycles += options[:cycles] + options[:time_in_cycles]
|
|
109
|
-
cycles += s_to_cycles(options[:time_in_s])
|
|
110
|
-
cycles += ms_to_cycles(options[:time_in_ms])
|
|
111
|
-
cycles += us_to_cycles(options[:time_in_us])
|
|
112
|
-
cycles += ns_to_cycles(options[:time_in_ns])
|
|
113
|
-
|
|
114
|
-
time = cycles * current_period_in_ns # Total delay in ns
|
|
115
|
-
case
|
|
116
|
-
when time < 1000 # When less than 1us
|
|
117
|
-
cc "Wait for #{'a maximum of ' if options[:match]}#{time}ns"
|
|
118
|
-
when time < 1_000_000 # When less than 1ms
|
|
119
|
-
cc "Wait for #{'a maximum of ' if options[:match]}#{(time.to_f / 1000).round(1)}us" # Display delay in us
|
|
120
|
-
when time < 1_000_000_000 # When less than 1s
|
|
121
|
-
cc "Wait for #{'a maximum of ' if options[:match]}#{(time.to_f / 1_000_000).round(1)}ms"
|
|
122
|
-
else
|
|
123
|
-
cc "Wait for #{'a maximum of ' if options[:match]}%.2fs" % (time.to_f / 1_000_000_000)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
if cycles > 0 # Allow this function to be called with 0 in which case it will just return
|
|
127
|
-
if options[:match]
|
|
128
|
-
if block_given?
|
|
129
|
-
match_block(cycles, options) { yield }
|
|
130
|
-
else
|
|
131
|
-
match(options[:pin], options[:state], cycles, options)
|
|
132
|
-
end
|
|
133
|
-
else
|
|
134
|
-
delay(cycles)
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# @api private
|
|
140
|
-
# This should not be called directly, call via tester#wait
|
|
141
|
-
def delay(cycles, options = {})
|
|
142
|
-
(cycles / max_repeat_loop).times do
|
|
143
|
-
if block_given?
|
|
144
|
-
yield options.merge(repeat: max_repeat_loop)
|
|
145
|
-
else
|
|
146
|
-
cycle(options.merge(repeat: max_repeat_loop))
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
if block_given?
|
|
150
|
-
yield options.merge(repeat: (cycles % max_repeat_loop))
|
|
151
|
-
else
|
|
152
|
-
cycle(options.merge(repeat: (cycles % max_repeat_loop)))
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def max_repeat_loop
|
|
157
|
-
@max_repeat_loop || 65_535
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def s_to_cycles(time) # :nodoc:
|
|
161
|
-
((time.to_f) * 1000 * 1000 * 1000 / current_period_in_ns).to_int
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def ms_to_cycles(time) # :nodoc:
|
|
165
|
-
((time.to_f) * 1000 * 1000 / current_period_in_ns).to_int
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def us_to_cycles(time) # :nodoc:
|
|
169
|
-
((time.to_f * 1000) / current_period_in_ns).to_int
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def ns_to_cycles(time) # :nodoc:
|
|
173
|
-
(time.to_f / current_period_in_ns).to_int
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def cycles_to_us(cycles) # :nodoc:
|
|
177
|
-
((cycles.to_f * current_period_in_ns) / (1000)).ceil
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def cycles_to_ms(cycles) # :nodoc:
|
|
181
|
-
((cycles.to_f * current_period_in_ns) / (1000 * 1000)).ceil
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# Cycles to tenths of a second
|
|
185
|
-
def cycles_to_ts(cycles) # :nodoc:
|
|
186
|
-
((cycles.to_f * current_period_in_ns) / (1000 * 1000 * 100)).ceil
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
def called_timesets
|
|
190
|
-
@called_timesets ||= []
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def current_period_in_ns
|
|
194
|
-
if @timeset
|
|
195
|
-
@timeset.period_in_ns
|
|
196
|
-
else
|
|
197
|
-
fail 'No timeset has been specified yet!'
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
alias_method :current_period, :current_period_in_ns
|
|
201
|
-
alias_method :period, :current_period_in_ns
|
|
202
|
-
|
|
203
|
-
def current_timeset
|
|
204
|
-
@timeset
|
|
205
|
-
end
|
|
206
|
-
alias_method :timeset, :current_timeset
|
|
207
|
-
|
|
208
|
-
# Convert the supplied number of cycles to a time, based on the SoC defined cycle period
|
|
209
|
-
def cycles_to_time(cycles) # :nodoc:
|
|
210
|
-
(cycles * current_period_in_ns).to_f / 1_000_000_000
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# This function can be used to generate a clock or some other repeating function
|
|
214
|
-
# that spans accross a range of vectors.
|
|
215
|
-
# The period of each cycle and the duration of the sequence are supplied via the following
|
|
216
|
-
# options:
|
|
217
|
-
# * :period_in_cycles
|
|
218
|
-
# * :period_in_ns
|
|
219
|
-
# * :period_in_us
|
|
220
|
-
# * :period_in_ms
|
|
221
|
-
# * :duration_in_cycles
|
|
222
|
-
# * :duration_in_ns
|
|
223
|
-
# * :duration_in_us
|
|
224
|
-
# * :duration_in_ms
|
|
225
|
-
# If multiple definitions for either option are supplied then they will be added
|
|
226
|
-
# together.
|
|
227
|
-
# ==== Example
|
|
228
|
-
# # Supply a clock pulse on :pinA for 100ms
|
|
229
|
-
# $tester.count(:period_in_cycles => 10, :duration_in_ms => 100) do
|
|
230
|
-
# $top.pin(:pinA).drive!(1)
|
|
231
|
-
# $top.pin(:pinA).drive!(0)
|
|
232
|
-
# end
|
|
233
|
-
def count(options = {})
|
|
234
|
-
options = { period_in_cycles: 0, period_in_ms: 0, period_in_us: 0, period_in_ns: 0,
|
|
235
|
-
duration_in_cycles: 0, duration_in_ms: 0, duration_in_us: 0, duration_in_ns: 0
|
|
236
|
-
}.merge(options)
|
|
237
|
-
|
|
238
|
-
period_cycles = options[:period_in_cycles] + ms_to_cycles(options[:period_in_ms]) +
|
|
239
|
-
us_to_cycles(options[:period_in_us]) + ns_to_cycles(options[:period_in_ns])
|
|
240
|
-
|
|
241
|
-
duration_cycles = options[:duration_in_cycles] + ms_to_cycles(options[:duration_in_ms]) +
|
|
242
|
-
us_to_cycles(options[:duration_in_us]) + ns_to_cycles(options[:duration_in_ns])
|
|
243
|
-
|
|
244
|
-
total = 0
|
|
245
|
-
while total < duration_cycles
|
|
246
|
-
wait(time_in_cycles: period_cycles)
|
|
247
|
-
yield # Return control back to caller
|
|
248
|
-
total += period_cycles
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
end
|