origen 0.20.3 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/fix_my_workspace +26 -4
- data/bin/origen +39 -2
- data/config/version.rb +2 -2
- data/lib/option_parser/optparse.rb +8 -1
- data/lib/origen.rb +30 -6
- data/lib/origen/application/lsf_manager.rb +13 -4
- data/lib/origen/commands.rb +19 -0
- data/lib/origen/commands_global.rb +39 -4
- data/lib/origen/core_ext/hash.rb +29 -0
- data/lib/origen/core_ext/string.rb +116 -4
- data/lib/origen/fuses.rb +31 -0
- data/lib/origen/fuses/fuse_field.rb +45 -0
- data/lib/origen/model.rb +1 -0
- data/lib/origen/site_config.rb +51 -15
- data/origen_site_config.yml +31 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 386c5e434e711ec01dd643a04282d2662f7ff312
|
4
|
+
data.tar.gz: fd0058e5748471a646a0e05fa582e7212fc50613
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d43b3346743a82f2144c9d6bc9b29f4aaab1c5af84d75e2d08fea74035680fabf7e851b1a6fb91c71cdb9dbaa32ee077c3cf3f0772f9ac408d62c1e7d979ec3
|
7
|
+
data.tar.gz: 399ad3393b90080cf5607d599e302de982edf1ce52340b8af4fb3f426eedca47ff45b82446bf7d1c6216cab797421254b4debda0690360d5cc09e41786d7b437
|
data/bin/fix_my_workspace
CHANGED
@@ -2,9 +2,17 @@
|
|
2
2
|
$VERBOSE = nil # Don't care about world writable dir warnings and the like
|
3
3
|
|
4
4
|
if $_fix_my_workspace_version_check
|
5
|
-
$_fix_my_workspace_version = '0.
|
5
|
+
$_fix_my_workspace_version = '0.7.0'
|
6
6
|
else
|
7
|
-
|
7
|
+
if File.exist?(File.expand_path('../../lib/origen.rb', __FILE__))
|
8
|
+
# If this script is being run from within an origen-core workspace, use that Origen-core,
|
9
|
+
# not the system-installed origen-core version.
|
10
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
11
|
+
require 'origen'
|
12
|
+
else
|
13
|
+
# Use system-installed Origen (the gem in system Ruby)
|
14
|
+
require 'origen'
|
15
|
+
end
|
8
16
|
|
9
17
|
if !Origen.site_config.gem_manage_bundler
|
10
18
|
puts 'Sorry but you have opted to manage Bundler yourself via your Origen site config, and this means'
|
@@ -70,9 +78,23 @@ else
|
|
70
78
|
fixed = true
|
71
79
|
end
|
72
80
|
|
73
|
-
|
81
|
+
if File.exist?(ENV['BUNDLE_BIN'])
|
82
|
+
`chmod o-w #{ENV['BUNDLE_BIN']}`
|
83
|
+
|
84
|
+
# Make .bat versions of all executables, Bundler should really be doing this when running
|
85
|
+
# on windows
|
86
|
+
if Origen.os.windows?
|
87
|
+
Dir.glob("#{ENV['BUNDLE_BIN']}/*").each do |bin|
|
88
|
+
unless bin =~ /.bat$/
|
89
|
+
bat = "#{bin}.bat"
|
90
|
+
unless File.exist?(bat)
|
91
|
+
File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
74
97
|
|
75
98
|
system 'origen -v' if fixed
|
76
|
-
|
77
99
|
end
|
78
100
|
end
|
data/bin/origen
CHANGED
@@ -56,9 +56,46 @@ if origen_root
|
|
56
56
|
exec Gem.ruby, "#{origen_root}/lbin/origen", *ARGV
|
57
57
|
exit 0
|
58
58
|
end
|
59
|
+
|
60
|
+
boot_app = true
|
61
|
+
elsif Origen.site_config.gem_manage_bundler && (Origen.site_config.user_install_enable || Origen.site_config.tool_repo_install_dir)
|
62
|
+
# Force everyone to have a consistent way of installing gems with bundler.
|
63
|
+
# In this case, we aren't running from an Origen application, so build everything at Origen.home instead
|
64
|
+
# Have two options here: if user_install_enable is tru, use user_install_dir. Otherwise, use the tool_repo_install_dir
|
65
|
+
Origen.site_config.user_install_enable ? origen_root = File.expand_path(Origen.site_config.user_install_dir) : origen_root = File.expand_path(Origen.site_config.tool_repo_install_dir)
|
66
|
+
unless Dir.exists?(origen_root)
|
67
|
+
load File.expand_path('../../lib/origen/utility/input_capture.rb', __FILE__)
|
68
|
+
include Origen::Utility::InputCapture
|
69
|
+
|
70
|
+
puts "Root directory '#{origen_root}' does not exist. Would you like to create it?"
|
71
|
+
if get_text(confirm: :return_boolean)
|
72
|
+
FileUtils.mkdir(origen_root)
|
73
|
+
else
|
74
|
+
puts "Exiting with creating Origen install"
|
75
|
+
exit!
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
gemfile = File.join(origen_root, 'Gemfile')
|
80
|
+
unless File.exists?(gemfile)
|
81
|
+
# Create a default Gemfile that can be further customized by the user.
|
82
|
+
# Initial Gemfile only requires Origen. Nothing else. Essentially a blank installation.
|
83
|
+
Dir.chdir(origen_root) do
|
84
|
+
`bundle init`
|
85
|
+
end
|
86
|
+
# The above will give a general Gemfile from Bundler. We'll just append "gem 'origen' to the end.
|
87
|
+
File.open(gemfile, 'a') do |f|
|
88
|
+
f << "gem 'origen'\n"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
92
|
+
ENV['BUNDLE_PATH'] = File.expand_path(Origen.site_config.gem_install_dir)
|
93
|
+
ENV['BUNDLE_BIN'] = File.join(origen_root, 'lbin')
|
94
|
+
|
95
|
+
boot_app = false
|
59
96
|
end
|
60
97
|
|
61
|
-
if origen_root && File.exist?(ENV['BUNDLE_GEMFILE']) && Origen.site_config.gem_manage_bundler
|
98
|
+
if origen_root && File.exist?(ENV['BUNDLE_GEMFILE']) && Origen.site_config.gem_manage_bundler && (boot_app || Origen.site_config.user_install_enable || Origen.site_config.tool_repo_install_dir)
|
62
99
|
# Overriding bundler here so that bundle install can be automated as required
|
63
100
|
require 'bundler/shared_helpers'
|
64
101
|
if Bundler::SharedHelpers.in_bundle?
|
@@ -131,7 +168,7 @@ begin
|
|
131
168
|
# If this script has been invoked from within an Origen application then open
|
132
169
|
# up all commands, if not then only allow the command to create a new Origen
|
133
170
|
# application.
|
134
|
-
if origen_root
|
171
|
+
if origen_root && boot_app
|
135
172
|
require 'origen/commands'
|
136
173
|
else
|
137
174
|
require 'origen/commands_global'
|
data/config/version.rb
CHANGED
@@ -7,6 +7,13 @@ class OptionParser
|
|
7
7
|
lsf_options = ARGV.dup
|
8
8
|
orig_parse!(*args)
|
9
9
|
lsf_options -= ARGV # Now contains all original options
|
10
|
-
|
10
|
+
|
11
|
+
# Pick whether we should be using the application's LSF instance or Origen's
|
12
|
+
# global LSF instance
|
13
|
+
if Origen.running_globally?
|
14
|
+
Origen.lsf_manager.command_options = lsf_options
|
15
|
+
else
|
16
|
+
Origen.app.lsf_manager.command_options = lsf_options
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
data/lib/origen.rb
CHANGED
@@ -55,6 +55,9 @@ unless defined? RGen::ORIGENTRANSITION
|
|
55
55
|
autoload :Netlist, 'origen/netlist'
|
56
56
|
autoload :Models, 'origen/models'
|
57
57
|
autoload :Errata, 'origen/errata'
|
58
|
+
autoload :LSF, 'origen/application/lsf'
|
59
|
+
autoload :LSFManager, 'origen/application/lsf_manager'
|
60
|
+
autoload :Fuses, 'origen/fuses'
|
58
61
|
|
59
62
|
attr_reader :switch_user
|
60
63
|
|
@@ -264,6 +267,13 @@ unless defined? RGen::ORIGENTRANSITION
|
|
264
267
|
!path.root?
|
265
268
|
end
|
266
269
|
|
270
|
+
# Shortcut method to find if Origen was invoked from within an application or from
|
271
|
+
# the global Origen install. This is just the opposite of in_app_workspace?
|
272
|
+
def running_globally?
|
273
|
+
!in_app_workspace?
|
274
|
+
end
|
275
|
+
alias_method :invoked_globally?, :running_globally?
|
276
|
+
|
267
277
|
def root(plugin = nil)
|
268
278
|
if plugin
|
269
279
|
app(plugin).root
|
@@ -277,7 +287,7 @@ unless defined? RGen::ORIGENTRANSITION
|
|
277
287
|
path = path.parent
|
278
288
|
end
|
279
289
|
if path.root?
|
280
|
-
|
290
|
+
path = top
|
281
291
|
end
|
282
292
|
path
|
283
293
|
end
|
@@ -586,10 +596,6 @@ unless defined? RGen::ORIGENTRANSITION
|
|
586
596
|
end
|
587
597
|
end
|
588
598
|
|
589
|
-
def lsf
|
590
|
-
application.lsf_manager
|
591
|
-
end
|
592
|
-
|
593
599
|
def running_on_windows?
|
594
600
|
Origen.os.windows?
|
595
601
|
end
|
@@ -691,7 +697,25 @@ unless defined? RGen::ORIGENTRANSITION
|
|
691
697
|
|
692
698
|
# Returns the home directory of Origen (i.e., the primary place that Origen operates out of)
|
693
699
|
def home
|
694
|
-
|
700
|
+
File.expand_path(Origen.site_config.home_dir)
|
701
|
+
end
|
702
|
+
|
703
|
+
def lsf_manager
|
704
|
+
@lsf_manager ||= Origen::Application::LSFManager.new
|
705
|
+
end
|
706
|
+
|
707
|
+
# Picks between either the global lsf_manager or the application's LSF manager
|
708
|
+
def lsf
|
709
|
+
if running_globally?
|
710
|
+
lsf_manager
|
711
|
+
else
|
712
|
+
application.lsf_manager
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
# Returns the Origen LSF instance, not the lsf_manager. Use Origen.lsf for that
|
717
|
+
def lsf!
|
718
|
+
@lsf ||= Origen::Application::LSF.new
|
695
719
|
end
|
696
720
|
|
697
721
|
private
|
@@ -17,6 +17,15 @@ module Origen
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
# Picks and returns either the application's LSF instance or the global LSF instance
|
21
|
+
def lsf
|
22
|
+
if Origen.running_globally?
|
23
|
+
Origen.lsf!
|
24
|
+
else
|
25
|
+
Origen.app.lsf
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
20
29
|
def remote_jobs_file
|
21
30
|
"#{Origen.root}/.lsf/remote_jobs"
|
22
31
|
end
|
@@ -359,7 +368,7 @@ module Origen
|
|
359
368
|
[log_file(job[:id]), passed_file(job[:id]), failed_file(job[:id]), started_file(job[:id])].each do |file|
|
360
369
|
FileUtils.rm_f(file) if File.exist?(file)
|
361
370
|
end
|
362
|
-
job[:lsf_id] =
|
371
|
+
job[:lsf_id] = lsf.submit(command_prefix(job[:id], job[:dependents_ids]) + job[:command] + job[:switches], dependents: job[:dependents_lsf_ids])
|
363
372
|
job[:status] = nil
|
364
373
|
job[:completed_at] = nil
|
365
374
|
job[:submitted_at] = Time.now
|
@@ -374,7 +383,7 @@ module Origen
|
|
374
383
|
id = generate_job_id
|
375
384
|
dependents_ids = extract_ids([options[:depend], options[:depends], options[:dependent], options[:dependents]].flatten.compact)
|
376
385
|
dependents_lsf_ids = dependents_ids.map { |dep_id| remote_jobs[dep_id][:lsf_id] }
|
377
|
-
lsf_id =
|
386
|
+
lsf_id = lsf.submit(command_prefix(id, dependents_ids) + command + switches, dependents: dependents_lsf_ids)
|
378
387
|
job_attrs = {
|
379
388
|
id: id,
|
380
389
|
lsf_id: lsf_id,
|
@@ -481,8 +490,8 @@ module Origen
|
|
481
490
|
|
482
491
|
def classify_jobs
|
483
492
|
clear_caches
|
484
|
-
queuing_job_ids =
|
485
|
-
running_job_ids =
|
493
|
+
queuing_job_ids = lsf.queuing_job_ids
|
494
|
+
running_job_ids = lsf.running_job_ids
|
486
495
|
remote_jobs.each do |_id, job|
|
487
496
|
# If the status has already been determined send it straight to the bucket
|
488
497
|
if job[:status]
|
data/lib/origen/commands.rb
CHANGED
@@ -24,6 +24,7 @@ ORIGEN_COMMAND_ALIASES = {
|
|
24
24
|
|
25
25
|
@command = ARGV.shift
|
26
26
|
@command = ORIGEN_COMMAND_ALIASES[@command] || @command
|
27
|
+
@global_commands = []
|
27
28
|
|
28
29
|
# Don't log to file during the save command since we need to preserve the last log,
|
29
30
|
# this is done as early in the process as possible so any deprecation warnings during
|
@@ -215,6 +216,16 @@ if shared_commands && shared_commands.size != 0
|
|
215
216
|
end
|
216
217
|
end
|
217
218
|
|
219
|
+
# Get a list of registered plugins and get the global launcher
|
220
|
+
@global_launcher = Origen._applications_lookup[:name].map do |plugin_name, plugin|
|
221
|
+
shared = plugin.config.shared || {}
|
222
|
+
if shared[:global_launcher]
|
223
|
+
file = "#{plugin.root}/#{shared[:global_launcher]}"
|
224
|
+
require file
|
225
|
+
file
|
226
|
+
end
|
227
|
+
end.compact
|
228
|
+
|
218
229
|
case @command
|
219
230
|
when 'generate', 'program', 'compile', 'merge', 'interactive', 'target', 'environment',
|
220
231
|
'save', 'lsf', 'web', 'time', 'dispatch', 'rc', 'lint', 'plugin', 'fetch', 'mode' # , 'add'
|
@@ -274,6 +285,14 @@ EOT
|
|
274
285
|
end
|
275
286
|
end
|
276
287
|
|
288
|
+
if @global_launcher && !@global_launcher.empty?
|
289
|
+
puts ''
|
290
|
+
puts 'The following global commands are provided by plugins:'
|
291
|
+
@global_commands.each do |str|
|
292
|
+
puts str
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
277
296
|
puts <<-EOT
|
278
297
|
|
279
298
|
All commands can be run with -d (or --debugger) to enable the debugger.
|
@@ -8,8 +8,32 @@ aliases = {
|
|
8
8
|
'f' => 'fetch'
|
9
9
|
}
|
10
10
|
|
11
|
-
command = ARGV.shift
|
12
|
-
command = aliases[command] || command
|
11
|
+
@command = ARGV.shift
|
12
|
+
@command = aliases[@command] || @command
|
13
|
+
|
14
|
+
@global_commands = []
|
15
|
+
@application_options = []
|
16
|
+
|
17
|
+
# Load all of the Gemfile's dependencies and grab any global commands.
|
18
|
+
# If no Gemfile is defined, don't require any extra bundler stuff though we most likely won't register any global commands
|
19
|
+
# if Origen.site_config.user_install_enable && File.exist?(File.join(File.expand_path(Origen.site_config.origen_install_dir), 'Gemfile'))
|
20
|
+
if ENV['BUNDLE_GEMFILE']
|
21
|
+
# Load the Gemfile
|
22
|
+
Bundler.require
|
23
|
+
Bundler.require(:development)
|
24
|
+
Bundler.require(:runtime)
|
25
|
+
Bundler.require(:default)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Get a list of registered plugins and get the global launcher
|
29
|
+
@global_launcher = Origen._applications_lookup[:name].map do |plugin_name, plugin|
|
30
|
+
shared = plugin.config.shared || {}
|
31
|
+
if shared[:global_launcher]
|
32
|
+
file = "#{plugin.root}/#{shared[:global_launcher]}"
|
33
|
+
require file
|
34
|
+
file
|
35
|
+
end
|
36
|
+
end.compact
|
13
37
|
|
14
38
|
require 'origen/global_methods'
|
15
39
|
include Origen::GlobalMethods
|
@@ -43,7 +67,7 @@ else
|
|
43
67
|
end
|
44
68
|
end
|
45
69
|
|
46
|
-
case command
|
70
|
+
case @command
|
47
71
|
|
48
72
|
when 'new'
|
49
73
|
require 'origen/commands/new'
|
@@ -61,7 +85,7 @@ when 'interactive'
|
|
61
85
|
IRB.start
|
62
86
|
|
63
87
|
else
|
64
|
-
puts 'Error: Command not recognized' unless ['-h', '--help'].include?(command)
|
88
|
+
puts 'Error: Command not recognized' unless ['-h', '--help'].include?(@command)
|
65
89
|
puts <<-EOT
|
66
90
|
Usage: origen COMMAND [ARGS]
|
67
91
|
|
@@ -70,6 +94,17 @@ The following commands are available:
|
|
70
94
|
new origen application workspace in "./my_app"
|
71
95
|
interactive Start an interactive Origen console (short-cut alias: "i"), this is just
|
72
96
|
IRB with the 'origen' lib loaded automatically
|
97
|
+
EOT
|
98
|
+
|
99
|
+
if @global_launcher && !@global_launcher.empty?
|
100
|
+
puts ''
|
101
|
+
puts 'The following global commands are provided by plugins:'
|
102
|
+
@global_commands.each do |str|
|
103
|
+
puts str
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
puts <<-EOT
|
73
108
|
|
74
109
|
Many commands can be run with -h (or --help) for more information.
|
75
110
|
EOT
|
data/lib/origen/core_ext/hash.rb
CHANGED
@@ -49,4 +49,33 @@ class Hash
|
|
49
49
|
def longest_value
|
50
50
|
values.map(&:to_s).max_by(&:length)
|
51
51
|
end
|
52
|
+
|
53
|
+
def recursive_find_by_key(key)
|
54
|
+
search_results = {} # Used to store results when key is a Regexp
|
55
|
+
# Create a stack of hashes to search through for the needle which
|
56
|
+
# is initially this hash
|
57
|
+
stack = [self]
|
58
|
+
# So long as there are more haystacks to search...
|
59
|
+
while (to_search = stack.pop)
|
60
|
+
# ...keep searching for this particular key...
|
61
|
+
to_search.each do |k, v|
|
62
|
+
# If this value can be recursively searched...
|
63
|
+
if v.respond_to?(:recursive_find_by_key)
|
64
|
+
# ...push that on to the list of places to search.
|
65
|
+
stack << v
|
66
|
+
elsif key.is_a? Regexp
|
67
|
+
search_results[k] = v if key.match(k.to_s)
|
68
|
+
else
|
69
|
+
return v if (k == key)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
if search_results.empty?
|
74
|
+
return nil
|
75
|
+
elsif search_results.size == 1
|
76
|
+
return search_results.values.first
|
77
|
+
else
|
78
|
+
return search_results
|
79
|
+
end
|
80
|
+
end
|
52
81
|
end
|
@@ -10,10 +10,10 @@ end
|
|
10
10
|
|
11
11
|
class String
|
12
12
|
def to_dec
|
13
|
-
if self
|
14
|
-
|
15
|
-
elsif
|
16
|
-
|
13
|
+
if self.is_verilog_number?
|
14
|
+
verilog_to_dec
|
15
|
+
elsif match(/^0[x,o,d,b]\S+/)
|
16
|
+
_to_dec(self)
|
17
17
|
else
|
18
18
|
to_i
|
19
19
|
end
|
@@ -122,4 +122,116 @@ class String
|
|
122
122
|
split(/ |\_|\-/).map(&:capitalize).join(' ')
|
123
123
|
end
|
124
124
|
end
|
125
|
+
|
126
|
+
def is_verilog_number?
|
127
|
+
case self
|
128
|
+
when /^[b,o,d,h]\S+$/, /^\d+\'[b,o,d,h]\S+$/, /^\d+\'s[b,o,d,h]\S+$/
|
129
|
+
true
|
130
|
+
else
|
131
|
+
false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
# Convert a verilog number string to an integer
|
138
|
+
def verilog_to_dec
|
139
|
+
verilog_hash = parse_verilog_number
|
140
|
+
bit_str = verilog_to_bits
|
141
|
+
msb_size_bit = bit_str.size - verilog_hash[:size]
|
142
|
+
if verilog_hash[:signed] == true
|
143
|
+
if bit_str[msb_size_bit] == '1'
|
144
|
+
_to_dec("0b#{bit_str}") * -1
|
145
|
+
else
|
146
|
+
_to_dec("0b#{bit_str}")
|
147
|
+
end
|
148
|
+
else
|
149
|
+
_to_dec("0b#{bit_str}")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Convert a verilog number string to a bit string
|
154
|
+
def verilog_to_bits
|
155
|
+
verilog_hash = parse_verilog_number
|
156
|
+
if [verilog_hash[:radix], verilog_hash[:value]].include?(nil)
|
157
|
+
Origen.log.error("The string '#{self}' does not appear to be valid Verilog number notation!")
|
158
|
+
fail
|
159
|
+
end
|
160
|
+
value_bit_string = create_bit_string_from_verilog(verilog_hash[:value], verilog_hash[:radix])
|
161
|
+
audit_verilog_value(value_bit_string, verilog_hash[:radix], verilog_hash[:size], verilog_hash[:signed])
|
162
|
+
end
|
163
|
+
|
164
|
+
def _to_dec(str)
|
165
|
+
if str =~ /^0x(.*)/i
|
166
|
+
Regexp.last_match[1].to_i(16)
|
167
|
+
elsif str =~ /0d(.*)/i
|
168
|
+
Regexp.last_match[1].to_i(10)
|
169
|
+
elsif str =~ /0o(.*)/i
|
170
|
+
Regexp.last_match[1].to_i(8)
|
171
|
+
elsif str =~ /0b(.*)/
|
172
|
+
Regexp.last_match[1].to_i(2)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def parse_verilog_number
|
177
|
+
str = nil
|
178
|
+
verilog_hash = {}.tap do |parse_hash|
|
179
|
+
[:size, :radix, :value].each do |attr|
|
180
|
+
parse_hash[attr] = nil
|
181
|
+
end
|
182
|
+
end
|
183
|
+
verilog_hash[:signed] = false
|
184
|
+
if match(/\_/)
|
185
|
+
str = delete('_')
|
186
|
+
else
|
187
|
+
str = self
|
188
|
+
end
|
189
|
+
str.downcase!
|
190
|
+
case str
|
191
|
+
when /^[0,1]+$/ # Just a value
|
192
|
+
verilog_hash[:size], verilog_hash[:radix], verilog_hash[:value] = 32, 'b', self
|
193
|
+
when /^[b,o,d,h]\S+$/ # A value and a radix
|
194
|
+
_m, verilog_hash[:radix], verilog_hash[:value] = /^([b,o,d,h])(\S+)$/.match(str).to_a
|
195
|
+
verilog_hash[:size] = calc_verilog_value_bit_size(verilog_hash[:value], verilog_hash[:radix])
|
196
|
+
when /^\d+\'[b,o,d,h]\S+$/ # A value, a radix, and a size
|
197
|
+
_m, verilog_hash[:size], verilog_hash[:radix], verilog_hash[:value] = /^(\d+)\'([b,o,d,h])(\S+)$/.match(str).to_a
|
198
|
+
when /^\d+\'s[b,o,d,h]\S+$/ # A signed value, a radix, and a size
|
199
|
+
_m, verilog_hash[:size], verilog_hash[:radix], verilog_hash[:value] = /^(\d+)\'s([b,o,d,h])(\S+)$/.match(str).to_a
|
200
|
+
verilog_hash[:signed] = true
|
201
|
+
else
|
202
|
+
Origen.log.error("The string '#{self}' does not appear to be valid Verilog number notation!")
|
203
|
+
fail
|
204
|
+
end
|
205
|
+
verilog_hash[:size] = verilog_hash[:size].to_i if verilog_hash[:size].is_a?(String)
|
206
|
+
verilog_hash
|
207
|
+
end
|
208
|
+
|
209
|
+
def calc_verilog_value_bit_size(val, radix)
|
210
|
+
create_bit_string_from_verilog(val, radix).size
|
211
|
+
end
|
212
|
+
|
213
|
+
def create_bit_string_from_verilog(val, radix)
|
214
|
+
bit_str = ''
|
215
|
+
case radix
|
216
|
+
when 'b'
|
217
|
+
return val
|
218
|
+
when 'o', 'd'
|
219
|
+
bit_str = "0#{radix}#{val}".to_dec.to_bin
|
220
|
+
when 'h'
|
221
|
+
bit_str = "0x#{val}".to_dec.to_bin
|
222
|
+
end
|
223
|
+
2.times { bit_str.slice!(0) }
|
224
|
+
bit_str
|
225
|
+
end
|
226
|
+
|
227
|
+
def audit_verilog_value(bit_str, radix, size, signed)
|
228
|
+
size_diff = bit_str.size - size
|
229
|
+
if size_diff > 0
|
230
|
+
Origen.log.warn("Truncating Verilog number '#{self}' by #{size_diff} MSBs!")
|
231
|
+
size_diff.times { bit_str.slice!(0) }
|
232
|
+
elsif size_diff < 0
|
233
|
+
bit_str = '0' * size_diff.abs + bit_str
|
234
|
+
end
|
235
|
+
bit_str
|
236
|
+
end
|
125
237
|
end
|
data/lib/origen/fuses.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'fuses/fuse_field'
|
2
|
+
module Origen
|
3
|
+
module Fuses
|
4
|
+
def fuses(expr = nil)
|
5
|
+
if expr.nil?
|
6
|
+
if @_fuses.nil?
|
7
|
+
@_fuses = {}
|
8
|
+
elsif @_fuses.is_a? Hash
|
9
|
+
if @_fuses.empty?
|
10
|
+
@_fuses
|
11
|
+
else
|
12
|
+
@_fuses.ids
|
13
|
+
end
|
14
|
+
else
|
15
|
+
@_fuses = {}
|
16
|
+
end
|
17
|
+
else
|
18
|
+
@_fuses.recursive_find_by_key(expr)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def fuse_field(name, start_addr, size, options = {})
|
23
|
+
@_fuses ||= {}
|
24
|
+
if fuses.respond_to? :name
|
25
|
+
Origen.log.error("Cannot create fuse field '#{name}', it already exists!")
|
26
|
+
fail
|
27
|
+
end
|
28
|
+
@_fuses[name] = FuseField.new(name, start_addr, size, self, options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Origen
|
2
|
+
module Fuses
|
3
|
+
# Currently just a simple data container most suited for import from Excel/CSV/XML
|
4
|
+
# by stuffing all attributes into the options hash
|
5
|
+
class FuseField
|
6
|
+
attr_accessor :name, :size, :start_addr, :owner
|
7
|
+
|
8
|
+
def initialize(name, start_addr, size, owner, options = {})
|
9
|
+
options = {
|
10
|
+
default_value: 0
|
11
|
+
}.merge(options)
|
12
|
+
@name, @start_addr, @size, @owner = name, start_addr, size, owner
|
13
|
+
# Check if the start address is in Verilog format or includes the number base in it
|
14
|
+
if @start_addr.is_a? String
|
15
|
+
if @start_addr.is_verilog_number? || @start_addr.match(/^0[x,o,d,b]\S+/)
|
16
|
+
@start_addr = @start_addr.to_dec
|
17
|
+
end
|
18
|
+
end
|
19
|
+
unless @size.is_a?(Numeric) && @start_addr.size.is_a?(Numeric)
|
20
|
+
Origen.log.error("Fuse fields must have numeric attributes for 'size' and 'start_addr'!")
|
21
|
+
fail
|
22
|
+
end
|
23
|
+
# If the fuse field is owned by Top Level DUT then keep the start address as-is
|
24
|
+
# If not, then add the fuse field start address to the base address of the IP
|
25
|
+
unless owner.is_top_level?
|
26
|
+
@start_addr += owner.base_address if owner.respond_to?(:base_address)
|
27
|
+
end
|
28
|
+
options.each do |o, val|
|
29
|
+
instance_eval("def #{o};@#{o};end") # getter
|
30
|
+
instance_eval("def #{o}=(val);@#{o}=val;end") # setter
|
31
|
+
ivar_name = "@#{o}".to_sym
|
32
|
+
instance_variable_set(ivar_name, options[o])
|
33
|
+
end
|
34
|
+
|
35
|
+
def reprogrammeable?
|
36
|
+
self.respond_to?(:reprogrammeable) ? reprogrammeable : true
|
37
|
+
end
|
38
|
+
|
39
|
+
def customer_visible?
|
40
|
+
self.respond_to?(:customer_visible) ? customer_visible : false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/origen/model.rb
CHANGED
data/lib/origen/site_config.rb
CHANGED
@@ -6,24 +6,34 @@ module Origen
|
|
6
6
|
TRUE_VALUES = ['true', 'TRUE', '1', 1]
|
7
7
|
FALSE_VALUES = ['false', 'FALSE', '0', 0]
|
8
8
|
|
9
|
+
# Define a couple of site configs variables that need a bit of processing
|
10
|
+
|
11
|
+
# Gets the gem_intall_dir. This is either site_config.home_dir/gems or the site configs gem_install_dir
|
12
|
+
def gem_install_dir
|
13
|
+
return "#{tool_repo_install_dir}/gems" if gems_use_tool_repo && tool_repo_install_dir && !user_install_enable
|
14
|
+
dir = find_val('user_gem_dir')
|
15
|
+
unless dir
|
16
|
+
dir = "#{find_val('home_dir')}/gems"
|
17
|
+
end
|
18
|
+
dir
|
19
|
+
end
|
20
|
+
|
21
|
+
# Gets the user_install_dir. Like gem_install_dir, this default to somewhere home_dir, unless overridden
|
22
|
+
def user_install_dir
|
23
|
+
dir = find_val('user_install_dir')
|
24
|
+
unless dir
|
25
|
+
dir = find_val('home_dir')
|
26
|
+
end
|
27
|
+
dir
|
28
|
+
end
|
29
|
+
|
9
30
|
def method_missing(method, *args, &block)
|
10
31
|
method = method.to_s
|
11
32
|
if method =~ /(.*)!$/
|
12
33
|
method = Regexp.last_match(1)
|
13
34
|
must_be_present = true
|
14
35
|
end
|
15
|
-
|
16
|
-
if ENV.key?(env)
|
17
|
-
val = ENV[env]
|
18
|
-
if TRUE_VALUES.include?(val)
|
19
|
-
val = true
|
20
|
-
elsif FALSE_VALUES.include?(val)
|
21
|
-
val = false
|
22
|
-
end
|
23
|
-
else
|
24
|
-
config = configs.find { |c| c.key?(method) }
|
25
|
-
val = config ? config[method] : nil
|
26
|
-
end
|
36
|
+
val = find_val(method)
|
27
37
|
if must_be_present && val.nil?
|
28
38
|
puts "No value assigned for site_config attribute '#{method}'"
|
29
39
|
puts
|
@@ -37,6 +47,22 @@ module Origen
|
|
37
47
|
|
38
48
|
private
|
39
49
|
|
50
|
+
def find_val(val, options = {})
|
51
|
+
env = "ORIGEN_#{val.upcase}"
|
52
|
+
if ENV.key?(env)
|
53
|
+
config = ENV[env]
|
54
|
+
if TRUE_VALUES.include?(val)
|
55
|
+
config = true
|
56
|
+
elsif FALSE_VALUES.include?(val)
|
57
|
+
config = false
|
58
|
+
end
|
59
|
+
config
|
60
|
+
else
|
61
|
+
config = configs.find { |c| c.key?(val) }
|
62
|
+
config ? config[val] : nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
40
66
|
def configs
|
41
67
|
@configs ||= begin
|
42
68
|
# This global is set when Origen is first required, it generally means that what is considered
|
@@ -50,21 +76,31 @@ module Origen
|
|
50
76
|
# directory area
|
51
77
|
until path.root?
|
52
78
|
file = File.join(path, 'config', 'origen_site_config.yml')
|
53
|
-
configs << YAML.load_file(file) if File.exist?(file)
|
79
|
+
configs << YAML.load_file(file) if File.exist?(file) && YAML.load_file(file)
|
54
80
|
file = File.join(path, 'origen_site_config.yml')
|
55
|
-
configs << YAML.load_file(file) if File.exist?(file)
|
81
|
+
configs << YAML.load_file(file) if File.exist?(file) && YAML.load_file(file)
|
56
82
|
path = path.parent
|
57
83
|
end
|
58
84
|
# Add and any site_configs from the directory hierarchy where Ruby is installed
|
59
85
|
path = Pathname.new($LOAD_PATH.last)
|
60
86
|
until path.root?
|
61
87
|
file = File.join(path, 'origen_site_config.yml')
|
62
|
-
configs << YAML.load_file(file) if File.exist?(file)
|
88
|
+
configs << YAML.load_file(file) if File.exist?(file) && YAML.load_file(file)
|
63
89
|
path = path.parent
|
64
90
|
end
|
65
91
|
# Add the one from the Origen core as the lowest priority, this one defines
|
66
92
|
# the default values
|
67
93
|
configs << YAML.load_file(File.expand_path('../../../origen_site_config.yml', __FILE__))
|
94
|
+
# Add the site_config from the user's home directory as highest priority, if it exists
|
95
|
+
# But, make sure we take the site installation's setup into account.
|
96
|
+
# That is, if user's home directories are somewhere else, make sure we use that directory to the find
|
97
|
+
# the user's overwrite file. The user can then override that if they want."
|
98
|
+
install_path = configs.find { |c| c.key?('home_dir') }
|
99
|
+
install_path = install_path ? install_path['home_dir'] : nil
|
100
|
+
install_path.nil? ? user_config = nil : user_config = File.join(File.expand_path(install_path), 'origen_site_config.yml')
|
101
|
+
if user_config && File.exist?(user_config)
|
102
|
+
configs.unshift(YAML.load_file(user_config)) if YAML.load_file(user_config)
|
103
|
+
end
|
68
104
|
configs
|
69
105
|
end
|
70
106
|
end
|
data/origen_site_config.yml
CHANGED
@@ -2,11 +2,39 @@
|
|
2
2
|
|
3
3
|
# If your company has an internal gem server enter it here
|
4
4
|
#gem_server: http://gems.company.net:9292
|
5
|
+
|
5
6
|
# When true Origen will configure and run Bundler in a consistent way for every
|
6
7
|
# user (recommended)
|
7
8
|
gem_manage_bundler: true
|
8
|
-
|
9
|
-
|
9
|
+
|
10
|
+
# Define where a typical user's home directory will be, with a hidden directory for Origen.
|
11
|
+
home_dir: ~/.origen
|
12
|
+
|
13
|
+
# Define where the gems should be installed
|
14
|
+
# By default, this will be at <home_dir>/gems but can be overridden here.
|
15
|
+
#gem_install_dir: ~/.origen/gems
|
16
|
+
|
17
|
+
# ORIGEN STARTUP OPTIONS
|
18
|
+
# These options define how and where Origen should boot.
|
19
|
+
# See the guides at advanced/invocations for additional details.
|
20
|
+
|
21
|
+
# By default, don't allow user install. This is more for power users to utilize for debug or those who want absolute
|
22
|
+
# control over their environment.
|
23
|
+
user_install_enable: false
|
24
|
+
|
25
|
+
# Default to the user's install dir being the .origen in their home directory but allow it to be overridden
|
26
|
+
#user_install_dir: ~/.origen
|
27
|
+
|
28
|
+
# Default 'tool_repo_install_dir' to nil, meaning no 'tool_repo_install_dir' is present. If neither this nor
|
29
|
+
# 'user_install_enable' is present, the universal install will be used.
|
30
|
+
#tool_repo_install_dir: nil
|
31
|
+
|
32
|
+
# If 'tool_repo_install_dir' is set, then, by default, Bundler will use and build the gems in the tool repo.
|
33
|
+
# Purpose of this, is to allow a power user to setup and install these gems and for individuals to just use.
|
34
|
+
# Added this parameter and set to true so that this will be the default behavior. Otherwise, gem_install_dir
|
35
|
+
# would need to be overwritten and set with the 'tool_repo_install_dir'
|
36
|
+
gems_use_tool_repo: true
|
37
|
+
|
10
38
|
# Some gems can be difficult to install reliably across individual user environments.
|
11
39
|
# Such gems can be installed to a communal system Ruby and then listed here, Origen
|
12
40
|
# will then use the system version of the given gem instead of trying to install
|
@@ -16,6 +44,7 @@ gem_use_from_system:
|
|
16
44
|
- [nokogiri, 1.6.4.1] # Only required for earlier versions of Origen
|
17
45
|
- [nokogiri, 1.6.7.2] # Only required for earlier versions of Origen
|
18
46
|
- [nokogiri, 1.7.2]
|
47
|
+
|
19
48
|
# Additionally any build switches/options that are required to build specific gems
|
20
49
|
# in your user environment can be defined here.
|
21
50
|
#gem_build_switches:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -459,6 +459,8 @@ files:
|
|
459
459
|
- lib/origen/features.rb
|
460
460
|
- lib/origen/features/feature.rb
|
461
461
|
- lib/origen/file_handler.rb
|
462
|
+
- lib/origen/fuses.rb
|
463
|
+
- lib/origen/fuses/fuse_field.rb
|
462
464
|
- lib/origen/generator.rb
|
463
465
|
- lib/origen/generator/comparator.rb
|
464
466
|
- lib/origen/generator/compiler.rb
|