origen 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|