origen 0.34.3 → 0.52.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/origen +1 -231
- data/config/application.rb +12 -3
- data/config/boot.rb +2 -7
- data/config/commands.rb +3 -74
- data/config/rubocop/easy_disabled.yml +4 -0
- data/config/rubocop/easy_enabled.yml +0 -4
- data/config/rubocop/strict_disabled.yml +4 -0
- data/config/rubocop/strict_enabled.yml +0 -4
- data/config/version.rb +2 -3
- data/lib/origen.rb +27 -14
- data/lib/origen/application.rb +88 -2
- data/lib/origen/application/deployer.rb +3 -1
- data/lib/origen/application/release.rb +2 -2
- data/lib/origen/application/runner.rb +35 -20
- data/lib/origen/boot.rb +302 -0
- data/lib/origen/boot/api.rb +13 -0
- data/lib/origen/boot/app.rb +284 -0
- data/lib/origen/code_generators.rb +30 -10
- data/lib/origen/code_generators/actions.rb +244 -34
- data/lib/origen/code_generators/base.rb +9 -2
- data/lib/origen/code_generators/block.rb +203 -0
- data/lib/origen/code_generators/block_common.rb +100 -0
- data/lib/origen/code_generators/dut.rb +62 -0
- data/lib/origen/code_generators/feature.rb +50 -0
- data/lib/origen/code_generators/klass.rb +41 -0
- data/lib/origen/code_generators/model.rb +60 -0
- data/lib/origen/code_generators/module.rb +92 -0
- data/lib/origen/commands.rb +30 -13
- data/lib/origen/commands/archive.rb +175 -0
- data/lib/origen/commands/extract.rb +43 -0
- data/lib/origen/commands/generate.rb +1 -0
- data/lib/origen/commands/lint.rb +6 -1
- data/lib/origen/commands/new.rb +48 -24
- data/lib/origen/commands/new_resource.rb +41 -0
- data/lib/origen/commands/site.rb +52 -0
- data/lib/origen/commands/web.rb +11 -6
- data/lib/origen/commands_global.rb +9 -7
- data/lib/origen/core_ext/numeric.rb +20 -0
- data/lib/{option_parser → origen/core_ext/option_parser}/optparse.rb +0 -0
- data/lib/origen/dependencies.rb +0 -0
- data/lib/origen/file_handler.rb +18 -6
- data/lib/origen/generator.rb +19 -10
- data/lib/origen/generator/comparator.rb +2 -1
- data/lib/origen/generator/flow.rb +3 -1
- data/lib/origen/generator/job.rb +60 -16
- data/lib/origen/generator/pattern.rb +132 -72
- data/lib/origen/generator/pattern_finder.rb +3 -3
- data/lib/origen/generator/pattern_sequence.rb +201 -0
- data/lib/origen/generator/pattern_sequencer.rb +99 -0
- data/lib/origen/generator/pattern_thread.rb +175 -0
- data/lib/origen/loader.rb +381 -0
- data/lib/origen/log.rb +250 -108
- data/lib/origen/model.rb +22 -1
- data/lib/origen/model/exporter.rb +50 -10
- data/lib/origen/model_initializer.rb +5 -1
- data/lib/origen/operating_systems.rb +4 -0
- data/lib/origen/parameters.rb +96 -4
- data/lib/origen/parameters/set.rb +4 -3
- data/lib/origen/pins.rb +10 -8
- data/lib/origen/pins/pin.rb +61 -46
- data/lib/origen/ports/port.rb +5 -0
- data/lib/origen/registers.rb +5 -0
- data/lib/origen/registers/bit.rb +57 -53
- data/lib/origen/registers/bit_collection.rb +100 -43
- data/lib/origen/registers/msb0_delegator.rb +47 -0
- data/lib/origen/registers/reg.rb +114 -99
- data/lib/origen/revision_control.rb +1 -1
- data/lib/origen/revision_control/git.rb +23 -3
- data/lib/origen/site_config.rb +251 -60
- data/lib/origen/site_config/config.rb +217 -0
- data/lib/origen/sub_blocks.rb +106 -31
- data/lib/origen/top_level.rb +11 -0
- data/lib/origen/users/user.rb +3 -2
- data/lib/origen/utility/mailer.rb +42 -9
- data/lib/origen/value/bin_str_val.rb +1 -1
- data/lib/origen/value/hex_str_val.rb +1 -1
- data/lib/origen/version_string.rb +6 -1
- data/lib/tasks/gem.rake +6 -1
- data/origen_app_generators/Gemfile +19 -0
- data/origen_app_generators/Gemfile.lock +152 -0
- data/origen_app_generators/LICENSE +21 -0
- data/origen_app_generators/README.md +368 -0
- data/{templates/code_generators/rakefile.rb → origen_app_generators/Rakefile} +0 -0
- data/origen_app_generators/bin/boot.rb +39 -0
- data/origen_app_generators/config/application.rb +153 -0
- data/origen_app_generators/config/boot.rb +1 -0
- data/origen_app_generators/config/commands.rb +63 -0
- data/origen_app_generators/config/shared_commands.rb +177 -0
- data/origen_app_generators/config/version.rb +8 -0
- data/origen_app_generators/doc/history +223 -0
- data/origen_app_generators/lbin/bundle +105 -0
- data/origen_app_generators/lbin/byebug +29 -0
- data/origen_app_generators/lbin/coderay +29 -0
- data/origen_app_generators/lbin/htmldiff +29 -0
- data/origen_app_generators/lbin/httparty +29 -0
- data/origen_app_generators/lbin/httpclient +29 -0
- data/origen_app_generators/lbin/kramdown +29 -0
- data/origen_app_generators/lbin/ldiff +29 -0
- data/origen_app_generators/lbin/nanoc +29 -0
- data/origen_app_generators/lbin/nokogiri +29 -0
- data/origen_app_generators/lbin/origen +62 -0
- data/origen_app_generators/lbin/pry +29 -0
- data/origen_app_generators/lbin/rackup +29 -0
- data/origen_app_generators/lbin/rake +29 -0
- data/origen_app_generators/lbin/rspec +29 -0
- data/origen_app_generators/lbin/rubocop +29 -0
- data/origen_app_generators/lbin/ruby-parse +29 -0
- data/origen_app_generators/lbin/ruby-rewrite +29 -0
- data/origen_app_generators/lbin/thor +29 -0
- data/origen_app_generators/lbin/tilt +29 -0
- data/origen_app_generators/lbin/yard +29 -0
- data/origen_app_generators/lbin/yardoc +29 -0
- data/origen_app_generators/lbin/yri +29 -0
- data/origen_app_generators/lib/origen_app_generators.rb +125 -0
- data/origen_app_generators/lib/origen_app_generators/application.rb +62 -0
- data/origen_app_generators/lib/origen_app_generators/base.rb +257 -0
- data/origen_app_generators/lib/origen_app_generators/empty_application.rb +15 -0
- data/origen_app_generators/lib/origen_app_generators/empty_plugin.rb +15 -0
- data/origen_app_generators/lib/origen_app_generators/new.rb +170 -0
- data/origen_app_generators/lib/origen_app_generators/new_app_tests.rb +4 -0
- data/origen_app_generators/lib/origen_app_generators/origen_infrastructure/app_generator_plugin.rb +107 -0
- data/origen_app_generators/lib/origen_app_generators/plugin.rb +55 -0
- data/origen_app_generators/lib/origen_app_generators/test_engineering/common.rb +29 -0
- data/origen_app_generators/lib/origen_app_generators/test_engineering/stand_alone_application.rb +64 -0
- data/origen_app_generators/lib/origen_app_generators/test_engineering/test_block.rb +61 -0
- data/origen_app_generators/origen_app_generators.gemspec +33 -0
- data/{templates/code_generators → origen_app_generators/spec}/spec_helper.rb +0 -0
- data/origen_app_generators/target/debug.rb +8 -0
- data/origen_app_generators/target/default.rb +8 -0
- data/origen_app_generators/target/production.rb +0 -0
- data/origen_app_generators/templates/app_generators/application/.gitignore +37 -0
- data/origen_app_generators/templates/app_generators/application/.irbrc +9 -0
- data/origen_app_generators/templates/app_generators/application/.rspec +1 -0
- data/origen_app_generators/templates/app_generators/application/.travis.yml +11 -0
- data/origen_app_generators/templates/app_generators/application/Gemfile +34 -0
- data/origen_app_generators/templates/app_generators/application/Rakefile +7 -0
- data/origen_app_generators/templates/app_generators/application/app/blocks/top_level.rb +12 -0
- data/origen_app_generators/templates/app_generators/application/app/lib/module.rb +6 -0
- data/origen_app_generators/templates/app_generators/application/app/templates/web/index.md.erb +19 -0
- data/origen_app_generators/templates/app_generators/application/app/templates/web/layouts/_basic.html.erb +13 -0
- data/origen_app_generators/templates/app_generators/application/app/templates/web/partials/_navbar.html.erb +20 -0
- data/origen_app_generators/templates/app_generators/application/app/templates/web/release_notes.md.erb +5 -0
- data/origen_app_generators/templates/app_generators/application/config/application.rb +121 -0
- data/origen_app_generators/templates/app_generators/application/config/boot.rb +4 -0
- data/origen_app_generators/templates/app_generators/application/config/commands.rb +79 -0
- data/origen_app_generators/templates/app_generators/application/config/maillist_dev.txt +4 -0
- data/origen_app_generators/templates/app_generators/application/config/maillist_prod.txt +3 -0
- data/origen_app_generators/templates/app_generators/application/config/version.rb +8 -0
- data/origen_app_generators/templates/app_generators/application/doc/history +0 -0
- data/origen_app_generators/templates/app_generators/application/dot_keep +0 -0
- data/origen_app_generators/templates/app_generators/application/origen_core_session +2 -0
- data/origen_app_generators/templates/app_generators/application/spec/spec_helper.rb +44 -0
- data/origen_app_generators/templates/app_generators/application/target/debug.rb +8 -0
- data/origen_app_generators/templates/app_generators/application/target/default.rb +1 -0
- data/origen_app_generators/templates/app_generators/application/target/production.rb +4 -0
- data/origen_app_generators/templates/app_generators/new/generator.rb +102 -0
- data/origen_app_generators/templates/app_generators/new/info.md.erb +9 -0
- data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/application.rb +54 -0
- data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/base.rb +55 -0
- data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/module.rb +28 -0
- data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/plugin.rb +64 -0
- data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/config/load_generators.rb +6 -0
- data/origen_app_generators/templates/app_generators/plugin/Gemfile +32 -0
- data/origen_app_generators/templates/app_generators/plugin/Rakefile +10 -0
- data/origen_app_generators/templates/app_generators/plugin/app/templates/web/index.md.erb +37 -0
- data/origen_app_generators/templates/app_generators/plugin/app/templates/web/partials/_navbar_external.html.erb +20 -0
- data/origen_app_generators/templates/app_generators/plugin/app/templates/web/partials/_navbar_internal.html.erb +20 -0
- data/origen_app_generators/templates/app_generators/plugin/config/boot.rb +24 -0
- data/origen_app_generators/templates/app_generators/plugin/gemspec.rb +43 -0
- data/origen_app_generators/templates/app_generators/test_engineering/environment/j750.rb +1 -0
- data/origen_app_generators/templates/app_generators/test_engineering/environment/uflex.rb +1 -0
- data/origen_app_generators/templates/app_generators/test_engineering/environment/v93k.rb +1 -0
- data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/.keep +0 -0
- data/origen_app_generators/templates/app_generators/test_engineering/test_block/.keep +0 -0
- data/origen_site_config.yml +55 -5
- data/templates/code_generators/attributes.rb +20 -0
- data/templates/code_generators/class.rb +9 -0
- data/templates/code_generators/controller.rb +87 -0
- data/templates/code_generators/model.rb +21 -0
- data/templates/code_generators/module.rb +4 -0
- data/templates/code_generators/parameters.rb +19 -0
- data/templates/code_generators/pins.rb +28 -0
- data/templates/code_generators/registers.rb +20 -0
- data/templates/code_generators/sub_blocks.rb +24 -0
- data/templates/code_generators/timesets.rb +24 -0
- data/templates/code_generators/version.rb +0 -1
- data/templates/git/gitignore.erb +0 -1
- data/vendor/lib/models/origen/export1.rb +77 -0
- data/vendor/lib/models/origen/export1/block1.rb +13 -0
- data/vendor/lib/models/origen/export1/block1/x.rb +36 -0
- data/vendor/lib/models/origen/non_origen_meta_data.md +1 -0
- metadata +149 -68
- data/bin/fix_my_workspace +0 -100
- data/lib/c99/ate_interface.rb +0 -77
- data/lib/c99/nvm.rb +0 -110
- data/lib/c99/target/mock2.rb +0 -1
- data/lib/c99/target/subdir/mock3.rb +0 -1
- data/lib/origen/code_generators/bundler.rb +0 -17
- data/lib/origen/code_generators/gem_setup.rb +0 -49
- data/lib/origen/code_generators/rake.rb +0 -13
- data/lib/origen/code_generators/rspec.rb +0 -12
- data/lib/origen/commands/add.rb +0 -12
- data/lib/tasks/private/build.rake +0 -8
- data/templates/code_generators/gemfile_app.rb +0 -4
- data/templates/code_generators/gemfile_plugin.rb +0 -6
- data/templates/code_generators/gemspec.rb +0 -33
@@ -51,7 +51,8 @@ module Origen
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def relative_path_to(file)
|
54
|
-
|
54
|
+
file = Pathname.new(file) unless file.is_a?(Pathname)
|
55
|
+
p = file.expand_path.relative_path_from(Pathname.pwd).to_s
|
55
56
|
p.gsub!('/', '\\') if Origen.running_on_windows?
|
56
57
|
p
|
57
58
|
end
|
@@ -31,7 +31,9 @@ module Origen
|
|
31
31
|
end
|
32
32
|
interface.close(flow: true, sub_flow: true)
|
33
33
|
else
|
34
|
-
|
34
|
+
unless tester.try(:sim?)
|
35
|
+
Origen.log.info "Generating... #{Origen.file_handler.current_file.basename}"
|
36
|
+
end
|
35
37
|
interface = Origen.reset_interface(options)
|
36
38
|
Origen.interface.set_top_level_flow
|
37
39
|
Origen.interface.flow_generator.set_flow_description(Origen.interface.consume_comments)
|
data/lib/origen/generator/job.rb
CHANGED
@@ -121,18 +121,34 @@ module Origen
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
+
def strip_dir_and_ext(name)
|
125
|
+
Pathname.new(name).basename('.*').basename('.*').to_s
|
126
|
+
end
|
127
|
+
|
124
128
|
def run
|
125
129
|
Origen.app.current_jobs << self
|
126
130
|
begin
|
127
131
|
if @options[:compile]
|
132
|
+
Origen.log.start_job(strip_dir_and_ext(@requested_pattern), :compiler)
|
128
133
|
Origen.generator.compiler.compile(@requested_pattern, @options)
|
129
134
|
elsif @options[:job_type] == :merge
|
135
|
+
Origen.log.start_job(strip_dir_and_ext(@requested_pattern), :merger)
|
130
136
|
Origen.generator.compiler.merge(@requested_pattern)
|
131
137
|
elsif @options[:action] == :program
|
138
|
+
if Origen.running_simulation?
|
139
|
+
Origen.log.start_job(strip_dir_and_ext(@requested_pattern), :simulator)
|
140
|
+
else
|
141
|
+
Origen.log.start_job(strip_dir_and_ext(@requested_pattern), :program_generator)
|
142
|
+
end
|
132
143
|
Origen.flow.reset
|
133
144
|
Origen.resources.reset
|
134
145
|
OrigenTesters::Generator.execute_source(@pattern)
|
135
146
|
else
|
147
|
+
if Origen.running_simulation?
|
148
|
+
Origen.log.start_job(strip_dir_and_ext(@requested_pattern), :simulator)
|
149
|
+
else
|
150
|
+
Origen.log.start_job(strip_dir_and_ext(@requested_pattern), :pattern_generator)
|
151
|
+
end
|
136
152
|
Origen.generator.pattern.reset # Resets the pattern controller ready for a new pattern
|
137
153
|
# Give the app a chance to handle pattern dispatch
|
138
154
|
skip = false
|
@@ -140,30 +156,58 @@ module Origen
|
|
140
156
|
skip ||= !listener.before_pattern_lookup(@requested_pattern)
|
141
157
|
end
|
142
158
|
unless skip
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
159
|
+
if @options[:sequence]
|
160
|
+
@pattern = @requested_pattern
|
161
|
+
Origen.pattern.sequence do |seq|
|
162
|
+
# This splits the pattern name by "_" then removes all values that are common to all patterns
|
163
|
+
# and then rejoins what is left.
|
164
|
+
# The goal is to keep the thread ID concise for the log and rather than using the whole pattern
|
165
|
+
# name only focussing on what is different.
|
166
|
+
# e.g. if you combined patterns flash_read_ckbd_ip1_max.rb and flash_read_ckbd_ip2_max.rb into
|
167
|
+
# a concurrent sequence then the two threads would be called 'ip1' and 'ip2'.
|
168
|
+
ids = @options[:patterns].map do |pat|
|
169
|
+
Pathname.new(pat).basename('.*').to_s.split('_')
|
170
|
+
end
|
171
|
+
ids = ids.map { |id| id.reject { |i| ids.all? { |id| id.include?(i) } }.join('_') }
|
172
|
+
|
173
|
+
@options[:patterns].each_with_index do |pat, i|
|
174
|
+
id = ids[i]
|
175
|
+
id = i.to_s if id.empty?
|
176
|
+
seq.in_parallel id do
|
177
|
+
seq.run pat
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
else
|
182
|
+
@pattern = Origen.generator.pattern_finder.find(@requested_pattern, @options)
|
183
|
+
if @pattern.is_a?(Hash)
|
184
|
+
@output_file_body = @pattern[:output]
|
185
|
+
@pattern = @pattern[:pattern]
|
186
|
+
end
|
187
|
+
load @pattern unless @pattern == :skip # Run the pattern
|
147
188
|
end
|
148
|
-
load @pattern unless @pattern == :skip # Run the pattern
|
149
189
|
end
|
150
190
|
end
|
151
191
|
rescue Exception => e
|
152
|
-
|
153
|
-
|
154
|
-
Origen.
|
155
|
-
|
156
|
-
Origen.log.error
|
157
|
-
|
158
|
-
|
159
|
-
|
192
|
+
# Whoever has aborted the job is responsible for cleaning it up
|
193
|
+
unless e.is_a?(Origen::Generator::AbortError)
|
194
|
+
if @options[:continue] || Origen.running_remotely?
|
195
|
+
Origen.log.error "FAILED - #{@requested_pattern} (for target #{Origen.target.name})"
|
196
|
+
Origen.log.error e.message
|
197
|
+
e.backtrace.each do |l|
|
198
|
+
Origen.log.error l
|
199
|
+
end
|
200
|
+
if @options[:compile]
|
201
|
+
Origen.app.stats.failed_files += 1
|
202
|
+
else
|
203
|
+
Origen.app.stats.failed_patterns += 1
|
204
|
+
end
|
160
205
|
else
|
161
|
-
|
206
|
+
raise
|
162
207
|
end
|
163
|
-
else
|
164
|
-
raise
|
165
208
|
end
|
166
209
|
end
|
210
|
+
Origen.log.stop_job
|
167
211
|
Origen.app.current_jobs.pop
|
168
212
|
end
|
169
213
|
end
|
@@ -59,87 +59,144 @@ module Origen
|
|
59
59
|
pattern_close(options)
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
62
|
+
def sequence(options = {}, &block)
|
63
63
|
@create_options = options
|
64
64
|
unless Origen.tester
|
65
65
|
puts 'The current target has not instantiated a tester and pattern generation cannot run.'
|
66
|
-
puts 'Add something like this to
|
67
|
-
puts
|
68
|
-
puts '
|
69
|
-
puts
|
66
|
+
puts 'Add something like this to an environment file:'
|
67
|
+
puts
|
68
|
+
puts ' Origen::Tester::J750.new'
|
69
|
+
puts
|
70
|
+
puts
|
71
|
+
puts 'Then select it by running: origen e <environment name>'
|
70
72
|
exit 1
|
71
73
|
end
|
72
74
|
Origen.tester.generating = :pattern
|
73
75
|
|
74
76
|
job.output_file_body = options.delete(:name).to_s if options[:name]
|
75
77
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
Origen.app.pattern_iterators.find { |iterator| iterator.key == key }
|
80
|
-
end.compact
|
81
|
-
iterators << DummyIterator.new while iterators.size < 10
|
82
|
-
|
83
|
-
args = []
|
84
|
-
|
85
|
-
# Couldn't get this to work fully dynamically, so hard-coded for 10 custom
|
86
|
-
# iterators for now, should be plenty for any application in the meantime.
|
87
|
-
# Should revisit this when time allows and remove this limitation by changing
|
88
|
-
# this to a recursive structure.
|
89
|
-
iterators[0].invoke(options) do |arg0|
|
90
|
-
args[0] = arg0
|
91
|
-
iterators[1].invoke(options) do |arg1|
|
92
|
-
args[1] = arg1
|
93
|
-
iterators[2].invoke(options) do |arg2|
|
94
|
-
args[2] = arg2
|
95
|
-
iterators[3].invoke(options) do |arg3|
|
96
|
-
args[3] = arg3
|
97
|
-
iterators[4].invoke(options) do |arg4|
|
98
|
-
args[4] = arg4
|
99
|
-
iterators[5].invoke(options) do |arg5|
|
100
|
-
args[5] = arg5
|
101
|
-
iterators[6].invoke(options) do |arg6|
|
102
|
-
args[6] = arg6
|
103
|
-
iterators[7].invoke(options) do |arg7|
|
104
|
-
args[7] = arg7
|
105
|
-
iterators[8].invoke(options) do |arg8|
|
106
|
-
args[8] = arg8
|
107
|
-
iterators[9].invoke(options) do |arg9|
|
108
|
-
args[9] = arg9
|
109
|
-
# Refresh the target to start all settings from scratch each time
|
110
|
-
# This is an easy way to reset all registered values
|
111
|
-
Origen.app.reload_target!(skip_first_time: true)
|
112
|
-
|
113
|
-
# Final call back to the project to allow it to make any pattern name specific
|
114
|
-
# configuration changes
|
115
|
-
Origen.app.listeners_for(:before_pattern).each do |listener|
|
116
|
-
listener.before_pattern(job.output_pattern_filename)
|
117
|
-
end
|
78
|
+
# Refresh the target to start all settings from scratch each time
|
79
|
+
# This is an easy way to reset all registered values
|
80
|
+
Origen.app.reload_target!(skip_first_time: true)
|
118
81
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
iterator.pattern_name.call(job.output_pattern_filename, args[i])
|
125
|
-
end
|
126
|
-
end
|
82
|
+
# Final call back to the project to allow it to make any pattern name specific
|
83
|
+
# configuration changes
|
84
|
+
Origen.app.listeners_for(:before_pattern).each do |listener|
|
85
|
+
listener.before_pattern(job.output_pattern_filename)
|
86
|
+
end
|
127
87
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
88
|
+
## Allow custom pattern postfix
|
89
|
+
# unless options[:pat_postfix].to_s.empty?
|
90
|
+
# job.output_pattern_filename = job.output_pattern_filename.sub(job.output_postfix + job.output_extension, "_#{options[:pat_postfix]}" + job.output_postfix + job.output_extension)
|
91
|
+
# end
|
92
|
+
|
93
|
+
@pattern_sequence = true
|
94
|
+
pattern_wrapper([], [], options) do
|
95
|
+
PatternSequencer.send(:active=, true)
|
96
|
+
@pattern_sequence = PatternSequence.new(job.output_pattern_filename, block)
|
97
|
+
@pattern_sequence.send(:execute)
|
98
|
+
PatternSequencer.send(:active=, false)
|
99
|
+
end
|
100
|
+
@pattern_sequence = false
|
101
|
+
@create_options = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def create(options = {})
|
105
|
+
if @pattern_sequence
|
106
|
+
yield
|
107
|
+
else
|
108
|
+
@create_options = options
|
109
|
+
unless Origen.tester
|
110
|
+
puts 'The current target has not instantiated a tester and pattern generation cannot run.'
|
111
|
+
puts 'Add something like this to an environment file:'
|
112
|
+
puts
|
113
|
+
puts ' Origen::Tester::J750.new'
|
114
|
+
puts
|
115
|
+
puts
|
116
|
+
puts 'Then select it by running: origen e <environment name>'
|
117
|
+
exit 1
|
118
|
+
end
|
119
|
+
Origen.tester.generating = :pattern
|
120
|
+
|
121
|
+
job.output_file_body = options.delete(:name).to_s if options[:name]
|
122
|
+
|
123
|
+
# Order the iterators by the order that their enable keys appear in the options, pad
|
124
|
+
# any missing iterators with a dummy function...
|
125
|
+
iterators = options.map do |key, _val|
|
126
|
+
Origen.app.pattern_iterators.find { |iterator| iterator.key == key }
|
127
|
+
end.compact
|
128
|
+
iterators << DummyIterator.new while iterators.size < 10
|
129
|
+
|
130
|
+
args = []
|
131
|
+
|
132
|
+
# Couldn't get this to work fully dynamically, so hard-coded for 10 custom
|
133
|
+
# iterators for now, should be plenty for any application in the meantime.
|
134
|
+
# Should revisit this when time allows and remove this limitation by changing
|
135
|
+
# this to a recursive structure.
|
136
|
+
iterators[0].invoke(options) do |arg0|
|
137
|
+
args[0] = arg0
|
138
|
+
iterators[1].invoke(options) do |arg1|
|
139
|
+
args[1] = arg1
|
140
|
+
iterators[2].invoke(options) do |arg2|
|
141
|
+
args[2] = arg2
|
142
|
+
iterators[3].invoke(options) do |arg3|
|
143
|
+
args[3] = arg3
|
144
|
+
iterators[4].invoke(options) do |arg4|
|
145
|
+
args[4] = arg4
|
146
|
+
iterators[5].invoke(options) do |arg5|
|
147
|
+
args[5] = arg5
|
148
|
+
iterators[6].invoke(options) do |arg6|
|
149
|
+
args[6] = arg6
|
150
|
+
iterators[7].invoke(options) do |arg7|
|
151
|
+
args[7] = arg7
|
152
|
+
iterators[8].invoke(options) do |arg8|
|
153
|
+
args[8] = arg8
|
154
|
+
iterators[9].invoke(options) do |arg9|
|
155
|
+
args[9] = arg9
|
156
|
+
# Refresh the target to start all settings from scratch each time
|
157
|
+
# This is an easy way to reset all registered values
|
158
|
+
Origen.app.reload_target!(skip_first_time: true)
|
159
|
+
|
160
|
+
# Final call back to the project to allow it to make any pattern name specific
|
161
|
+
# configuration changes
|
162
|
+
Origen.app.listeners_for(:before_pattern).each do |listener|
|
163
|
+
listener.before_pattern(job.output_pattern_filename)
|
164
|
+
end
|
132
165
|
|
133
|
-
|
134
|
-
|
135
|
-
yield_items = []
|
166
|
+
# Work out the final pattern name based on the current iteration
|
167
|
+
job.reset_output_pattern_filename
|
136
168
|
iterators.each_with_index do |iterator, i|
|
137
169
|
if iterator.enabled?(options)
|
138
|
-
|
170
|
+
job.output_pattern_filename =
|
171
|
+
iterator.pattern_name.call(job.output_pattern_filename, args[i])
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Allow custom pattern prefix
|
176
|
+
unless options[:pat_prefix].to_s.empty?
|
177
|
+
if job.output_prefix.empty?
|
178
|
+
job.output_pattern_filename = "#{options[:pat_prefix]}_" + job.output_pattern_filename
|
179
|
+
else
|
180
|
+
job.output_pattern_filename = job.output_pattern_filename.sub(job.output_prefix, job.output_prefix + "#{options[:pat_prefix]}_")
|
139
181
|
end
|
140
182
|
end
|
141
183
|
|
142
|
-
|
184
|
+
# Allow custom pattern postfix
|
185
|
+
unless options[:pat_postfix].to_s.empty?
|
186
|
+
job.output_pattern_filename = job.output_pattern_filename.sub(job.output_postfix + job.output_extension, "_#{options[:pat_postfix]}" + job.output_postfix + job.output_extension)
|
187
|
+
end
|
188
|
+
|
189
|
+
pattern_wrapper(iterators, args, options) do
|
190
|
+
# Call iterator setups, whatever these return are passed to the pattern
|
191
|
+
yield_items = []
|
192
|
+
iterators.each_with_index do |iterator, i|
|
193
|
+
if iterator.enabled?(options)
|
194
|
+
yield_items << iterator.setup.call(args[i])
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
yield(*yield_items)
|
199
|
+
end
|
143
200
|
end
|
144
201
|
end
|
145
202
|
end
|
@@ -363,9 +420,7 @@ module Origen
|
|
363
420
|
unless job.test?
|
364
421
|
File.delete(job.output_pattern) if File.exist?(job.output_pattern)
|
365
422
|
|
366
|
-
|
367
|
-
log.info "Generating... #{job.output_pattern_directory}/#{job.output_pattern_filename}".ljust(50)
|
368
|
-
else
|
423
|
+
unless tester.try(:sim?)
|
369
424
|
log.info "Generating... #{job.output_pattern_directory}/#{job.output_pattern_filename}".ljust(50)
|
370
425
|
end
|
371
426
|
end
|
@@ -459,11 +514,16 @@ module Origen
|
|
459
514
|
end
|
460
515
|
end
|
461
516
|
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
517
|
+
unless tester.try(:sim?)
|
518
|
+
log.info ' '
|
519
|
+
log.info "Pattern vectors: #{stats.number_of_vectors_for(job.output_pattern).to_s.ljust(10)}"
|
520
|
+
log.info 'Execution time'.ljust(15) + ': %.6f' % stats.execution_time_for(job.output_pattern)
|
521
|
+
log.info '----------------------------------------------------------------------'
|
522
|
+
check_for_changes(job.output_pattern, job.reference_pattern) unless tester.try(:disable_pattern_diffs)
|
523
|
+
end
|
524
|
+
if @pattern_sequence
|
525
|
+
@pattern_sequence.send(:log_execution_profile)
|
526
|
+
end
|
467
527
|
stats.record_pattern_completion(job.output_pattern)
|
468
528
|
end
|
469
529
|
|
@@ -95,10 +95,10 @@ module Origen
|
|
95
95
|
matches = Dir.glob("#{current_plugin_pattern_path}/**/#{name}.rb").sort
|
96
96
|
# If the current plugin does not include the pattern then look into the current app
|
97
97
|
if matches.size == 0
|
98
|
-
matches = Dir.glob("#{pattern_directory}/**/#{name}.rb").sort # <= this does not include symlinks
|
98
|
+
matches = Dir.glob(["#{pattern_directory}/**/#{name}.rb", "#{Origen.root}/app/patterns/**/#{name}.rb"]).sort # <= this does not include symlinks
|
99
99
|
end
|
100
100
|
else
|
101
|
-
matches = Dir.glob("#{pattern_directory}/**/#{name}.rb").sort # <= this does not include symlinks
|
101
|
+
matches = Dir.glob(["#{pattern_directory}/**/#{name}.rb", "#{Origen.root}/app/patterns/**/#{name}.rb"]).sort # <= this does not include symlinks
|
102
102
|
end
|
103
103
|
|
104
104
|
matches
|
@@ -114,7 +114,7 @@ module Origen
|
|
114
114
|
|
115
115
|
def all_matches(name)
|
116
116
|
name = name.gsub(/\..*$/, '')
|
117
|
-
matches = Dir.glob("#{pattern_directory}/**{,/*/**}/#{name}.rb").sort # Takes symlinks into consideration
|
117
|
+
matches = Dir.glob(["#{pattern_directory}/**{,/*/**}/#{name}.rb", "#{Origen.root}/app/patterns/**{,/*/**}/#{name}.rb"]).sort # Takes symlinks into consideration
|
118
118
|
matches.flatten.uniq
|
119
119
|
end
|
120
120
|
|
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'io/console'
|
2
|
+
|
3
|
+
module Origen
|
4
|
+
class Generator
|
5
|
+
# Manages a single pattern sequence, i.e. an instance of PatternSequence is
|
6
|
+
# created for every Pattern.sequence do ... end block
|
7
|
+
class PatternSequence
|
8
|
+
def initialize(name, block)
|
9
|
+
@number_of_threads = 1
|
10
|
+
@name = name
|
11
|
+
@running_thread_ids = { main: true }
|
12
|
+
# The contents of the main Pattern.sequence block will be executed as a thread and treated
|
13
|
+
# like any other parallel block
|
14
|
+
thread = PatternThread.new(:main, self, block, true)
|
15
|
+
threads << thread
|
16
|
+
active_threads << thread
|
17
|
+
end
|
18
|
+
|
19
|
+
# Execute the given pattern
|
20
|
+
def run(pattern_name)
|
21
|
+
pattern = Origen.generator.pattern_finder.find(pattern_name.to_s, {})
|
22
|
+
pattern = pattern[:pattern] if pattern.is_a?(Hash)
|
23
|
+
load pattern
|
24
|
+
end
|
25
|
+
alias_method :call, :run
|
26
|
+
|
27
|
+
# Execute the given block in a new concurrent thread
|
28
|
+
def thread(id = nil, &block)
|
29
|
+
@number_of_threads += 1
|
30
|
+
id ||= "thread#{@number_of_threads}".to_sym
|
31
|
+
# Just stage the request for now, it will be started at the end of the current execute loop
|
32
|
+
@parallel_blocks_waiting_to_start ||= []
|
33
|
+
@parallel_blocks_waiting_to_start << [id, block]
|
34
|
+
@running_thread_ids[id] = true
|
35
|
+
end
|
36
|
+
alias_method :in_parallel, :thread
|
37
|
+
|
38
|
+
def wait_for_threads(*ids)
|
39
|
+
completed = false
|
40
|
+
blocked = false
|
41
|
+
ids = ids.map(&:to_sym)
|
42
|
+
all = ids.empty? || ids.include?(:all)
|
43
|
+
until completed
|
44
|
+
if all
|
45
|
+
limit = current_thread.id == :main ? 1 : 2
|
46
|
+
if @running_thread_ids.size > limit
|
47
|
+
current_thread.waiting_for_thread(blocked)
|
48
|
+
blocked = true
|
49
|
+
else
|
50
|
+
current_thread.record_active if blocked
|
51
|
+
completed = true
|
52
|
+
end
|
53
|
+
else
|
54
|
+
if ids.any? { |id| @running_thread_ids[id] }
|
55
|
+
current_thread.waiting_for_thread(blocked)
|
56
|
+
blocked = true
|
57
|
+
else
|
58
|
+
current_thread.record_active if blocked
|
59
|
+
completed = true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias_method :wait_for_thread, :wait_for_threads
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def thread_running?(id)
|
69
|
+
@running_thread_ids[id]
|
70
|
+
end
|
71
|
+
|
72
|
+
def current_thread
|
73
|
+
PatSeq.thread
|
74
|
+
end
|
75
|
+
|
76
|
+
def log_execution_profile
|
77
|
+
if threads.size > 1
|
78
|
+
thread_id_size = threads.map { |t| t.id.to_s.size }.max
|
79
|
+
line_size = IO.console.winsize[1] - 35 - thread_id_size
|
80
|
+
line_size -= 16 if tester.try(:sim?)
|
81
|
+
cycles_per_tick = (@cycle_count_stop / (line_size * 1.0)).ceil
|
82
|
+
if tester.try(:sim?)
|
83
|
+
execution_time = tester.execution_time_in_ns / 1_000_000_000.0
|
84
|
+
else
|
85
|
+
execution_time = Origen.app.stats.execution_time_for(Origen.app.current_job.output_pattern)
|
86
|
+
end
|
87
|
+
Origen.log.info ''
|
88
|
+
tick_time = execution_time / line_size
|
89
|
+
|
90
|
+
Origen.log.info "Concurrent execution profile (#{pretty_time(tick_time)}/increment):"
|
91
|
+
Origen.log.info
|
92
|
+
|
93
|
+
number_of_ticks = @cycle_count_stop / cycles_per_tick
|
94
|
+
|
95
|
+
ticks_per_step = 0
|
96
|
+
step_size = 0.1.us
|
97
|
+
|
98
|
+
while ticks_per_step < 10
|
99
|
+
step_size = step_size * 10
|
100
|
+
ticks_per_step = step_size / tick_time
|
101
|
+
end
|
102
|
+
|
103
|
+
ticks_per_step = ticks_per_step.ceil
|
104
|
+
step_size = tick_time * ticks_per_step
|
105
|
+
|
106
|
+
if tester.try(:sim?)
|
107
|
+
padding = '.' + (' ' * (thread_id_size + 1))
|
108
|
+
else
|
109
|
+
padding = ' ' * (thread_id_size + 2)
|
110
|
+
end
|
111
|
+
scale_step = '|' + ('-' * (ticks_per_step - 1))
|
112
|
+
number_of_steps = (number_of_ticks / ticks_per_step) + 1
|
113
|
+
scale = scale_step * number_of_steps
|
114
|
+
scale = scale[0, number_of_ticks]
|
115
|
+
Origen.log.info padding + scale
|
116
|
+
|
117
|
+
scale = ''
|
118
|
+
number_of_steps.times do |i|
|
119
|
+
scale += pretty_time(i * step_size, 1).ljust(ticks_per_step)
|
120
|
+
end
|
121
|
+
scale = scale[0, number_of_ticks]
|
122
|
+
Origen.log.info padding + scale
|
123
|
+
|
124
|
+
threads.each do |thread|
|
125
|
+
line = thread.execution_profile(0, @cycle_count_stop, cycles_per_tick)
|
126
|
+
Origen.log.info ''
|
127
|
+
Origen.log.info "#{thread.id}: ".ljust(thread_id_size + 2) + line
|
128
|
+
end
|
129
|
+
Origen.log.info ''
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def pretty_time(time, number_decimal_places = 0)
|
134
|
+
return '0' if time == 0
|
135
|
+
if time < 1.us
|
136
|
+
"%.#{number_decimal_places}fns" % (time * 1_000_000_000)
|
137
|
+
elsif time < 1.ms
|
138
|
+
"%.#{number_decimal_places}fus" % (time * 1_000_000)
|
139
|
+
elsif time < 1.s
|
140
|
+
"%.#{number_decimal_places}fms" % (time * 1_000)
|
141
|
+
else
|
142
|
+
"%.#{number_decimal_places}fs" % tick_time
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def thread_completed(thread)
|
147
|
+
@running_thread_ids.delete(thread.id)
|
148
|
+
active_threads.delete(thread)
|
149
|
+
end
|
150
|
+
|
151
|
+
def threads
|
152
|
+
@threads ||= []
|
153
|
+
end
|
154
|
+
|
155
|
+
def active_threads
|
156
|
+
@active_threads ||= []
|
157
|
+
end
|
158
|
+
|
159
|
+
def threads_waiting_to_start?
|
160
|
+
@parallel_blocks_waiting_to_start
|
161
|
+
end
|
162
|
+
|
163
|
+
def execute
|
164
|
+
active_threads.first.start
|
165
|
+
until active_threads.empty?
|
166
|
+
# Advance all threads to their next cycle point in sequential order. Keeping tight control of
|
167
|
+
# when threads are running in this way ensures that the output is deterministic no matter what
|
168
|
+
# computer it is running on, and ensures that the application code does not have to worry about
|
169
|
+
# race conditions.
|
170
|
+
cycs = active_threads.map do |t|
|
171
|
+
t.advance
|
172
|
+
t.pending_cycles
|
173
|
+
end.compact.min
|
174
|
+
|
175
|
+
if cycs
|
176
|
+
# Now generate the required number of cycles which is defined by the thread that has the least
|
177
|
+
# amount of cycles ready to go.
|
178
|
+
# Since tester.cycle is being called by the master process here it will generate as normal (as
|
179
|
+
# opposed to when called from a thread in which case it causes the thread to wait).
|
180
|
+
cycs.cycles
|
181
|
+
|
182
|
+
# Now let each thread know how many cycles we just generated, so they can decide whether they
|
183
|
+
# need to wait for more cycles or if they can start preparing the next one
|
184
|
+
active_threads.each { |t| t.executed_cycles(cycs) }
|
185
|
+
end
|
186
|
+
|
187
|
+
if @parallel_blocks_waiting_to_start
|
188
|
+
@parallel_blocks_waiting_to_start.each do |id, block|
|
189
|
+
thread = PatternThread.new(id, self, block)
|
190
|
+
threads << thread
|
191
|
+
active_threads << thread
|
192
|
+
thread.start
|
193
|
+
end
|
194
|
+
@parallel_blocks_waiting_to_start = nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
@cycle_count_stop = threads.first.current_cycle_count
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|