origen 0.40.2 → 0.41.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 641fd0140d976febea8c6cad4cd9c3ad853e0e37d502ed10b98c7a54a1269bb0
4
- data.tar.gz: 80da77dd07ca579ac6231bcd4ba2693d3ae0398fc059a3559989a9d9d96f0e22
3
+ metadata.gz: 7b5ba8eda5e72800d451d575b48242c7483bc07260b41b2a6325e87296c512ac
4
+ data.tar.gz: 873f0bbcb08ccd34c50b549f30d9932c800cc5b432584e618be5589673f7ad0e
5
5
  SHA512:
6
- metadata.gz: 71cdc7dbf0257e82ed78b1871b47ca2980d9e83a904dff92f12dab35334e54ed9188e8977561a9242cded10b44458bc6268597e8a7b954f8fc9b1ca8ad9cc82d
7
- data.tar.gz: 940f2d51b2137ef1eb639fe00a25fa2e8bb11e32a761722971adce69cf734c2a80071e2a8465bdf58067a795326e319c0754e636d3eda99b3259d58317ec243e
6
+ metadata.gz: 1cea1d1879bacccf077275bf1c04aba477d39fba1188b2806166baedbf5436e1a0bda85212c4572838b1a4dae22f92bbf7199a91a3c36056a867bf67bc46f0c0
7
+ data.tar.gz: 1fba58ea8bd16b85c81b154fc4ede78257b355327cf540b802bfd2caf3fd11c98d5f40c6142b3ce3a205b57889c1fb05561b020f0d4e3bdac0b38fd25e6b6876
data/bin/origen~ ADDED
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env ruby
2
+ $VERBOSE = nil # Don't care about world writable dir warnings and the like
3
+
4
+ require 'pathname'
5
+ require 'fileutils'
6
+ #require 'byebug' # Un-comment to debug this file
7
+
8
+ class OrigenBootError < StandardError
9
+ end
10
+
11
+ # Keep a note of the pwd at the time when Origen was first loaded, this is initially used
12
+ # by the site_config lookup.
13
+ $_origen_invocation_pwd ||= Pathname.pwd
14
+
15
+ load File.expand_path('../../lib/origen/operating_systems.rb', __FILE__)
16
+ load File.expand_path('../../lib/origen/site_config.rb', __FILE__)
17
+
18
+ # This will be referenced later in ruby_version_check, the origen used to launch
19
+ # the process is different than the one that actually runs under bundler
20
+ $origen_launch_root = Pathname.new(File.dirname(__FILE__)).parent
21
+
22
+ # Override any influence from $LANG in the users environment
23
+ Encoding.default_external = Encoding::UTF_8
24
+ Encoding.default_internal = Encoding::UTF_8
25
+ ENV['LC_ALL'] = nil
26
+ ENV['LANG'] = nil
27
+ ENV['LANG'] = 'en_US.UTF-8'
28
+
29
+ # Work out what Origen.root is if we are running inside an Origen application, this will be
30
+ # later used to execute from that app's bundle even if the origen executable lives somewhere
31
+ # else (e.g. in the tools repository)
32
+ app_config = File.join('config', 'application.rb')
33
+ if File.exist?(app_config)
34
+ origen_root = Dir.pwd
35
+ else
36
+ path = Pathname.new(Dir.pwd)
37
+ until path.root? || origen_root
38
+ if File.exist?(File.join(path, app_config))
39
+ origen_root = path.to_s
40
+ else
41
+ path = path.parent
42
+ end
43
+ end
44
+ end
45
+
46
+ # If running inside an application workspace
47
+ if origen_root
48
+ # Force everyone to have a consistent way of installing gems with bundler
49
+ ENV['BUNDLE_GEMFILE'] = File.join(origen_root, 'Gemfile')
50
+ ENV['BUNDLE_PATH'] = File.expand_path(Origen.site_config.gem_install_dir)
51
+ ENV['BUNDLE_BIN'] = File.join(origen_root, 'lbin')
52
+
53
+ # If it looks like a bundled binstub of origen exists, and we have not been invoked through that,
54
+ # then run that instead.
55
+ if Origen.site_config.gem_manage_bundler && File.exist?("#{origen_root}/lbin/origen") && !ENV['BUNDLE_BIN_PATH'] &&
56
+ File.exist?(File.expand_path(Origen.site_config.gem_install_dir))
57
+ exec Gem.ruby, "#{origen_root}/lbin/origen", *ARGV
58
+ exit 0
59
+ end
60
+
61
+ boot_app = true
62
+
63
+ # If running outside an application and a user or central tool Origen bundle is to be used
64
+ elsif Origen.site_config.gem_manage_bundler && (Origen.site_config.user_install_enable || Origen.site_config.tool_repo_install_dir)
65
+ # Force everyone to have a consistent way of installing gems with bundler.
66
+ # In this case, we aren't running from an Origen application, so build everything at Origen.home instead
67
+ # Have two options here: if user_install_enable is true, use user_install_dir. Otherwise, use the tool_repo_install_dir
68
+ 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)
69
+ unless Dir.exists?(origen_root)
70
+ load File.expand_path('../../lib/origen/utility/input_capture.rb', __FILE__)
71
+ include Origen::Utility::InputCapture
72
+
73
+ puts "Root directory '#{origen_root}' does not exist. Would you like to create it?"
74
+ if get_text(confirm: :return_boolean)
75
+ FileUtils.mkdir(origen_root)
76
+ else
77
+ puts "Exiting with creating Origen install"
78
+ exit!
79
+ end
80
+ end
81
+
82
+ gemfile = File.join(origen_root, 'Gemfile')
83
+ unless File.exists?(gemfile)
84
+ # Create a default Gemfile that can be further customized by the user.
85
+ # Initial Gemfile only requires Origen. Nothing else. Essentially a blank installation.
86
+ Dir.chdir(origen_root) do
87
+ `bundle init`
88
+ end
89
+ # The above will give a general Gemfile from Bundler. We'll just append "gem 'origen' to the end.
90
+ File.open(gemfile, 'a') do |f|
91
+ f << "gem 'origen'\n"
92
+ end
93
+ end
94
+ ENV['BUNDLE_GEMFILE'] = gemfile
95
+ ENV['BUNDLE_PATH'] = File.expand_path(Origen.site_config.gem_install_dir)
96
+ ENV['BUNDLE_BIN'] = File.join(origen_root, 'lbin')
97
+
98
+ origen_exec = File.join(ENV['BUNDLE_BIN'], 'origen')
99
+
100
+ # If the user/tool bundle already exists but we have not been invoked through that, abort this thread
101
+ # and re-launch under the required bundler environment
102
+ if File.exist?(origen_exec) && !ENV['BUNDLE_BIN_PATH'] && File.exist?(ENV['BUNDLE_PATH'])
103
+ exec Gem.ruby, origen_exec, *ARGV
104
+ exit 0
105
+ else
106
+ boot_app = false
107
+ end
108
+ end
109
+
110
+ 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)
111
+ # Overriding bundler here so that bundle install can be automated as required
112
+ require 'bundler/shared_helpers'
113
+ if Bundler::SharedHelpers.in_bundle?
114
+ require 'bundler'
115
+ if STDOUT.tty?
116
+ begin
117
+ fail OrigenBootError unless File.exist?(ENV['BUNDLE_BIN'])
118
+ Bundler.setup
119
+ fail OrigenBootError unless File.exist?(ENV['BUNDLE_BIN'])
120
+ rescue Gem::LoadError, Bundler::BundlerError, OrigenBootError => e
121
+ cmd = "bundle install --gemfile #{ENV['BUNDLE_GEMFILE']} --binstubs #{ENV['BUNDLE_BIN']} --path #{ENV['BUNDLE_PATH']}"
122
+ # puts cmd
123
+ puts 'Installing required gems...'
124
+ puts
125
+ `chmod o-w #{origen_root}` # Stops some annoying world writable warnings during install
126
+ `chmod o-w #{origen_root}/bin` if File.exist?("#{origen_root}/bin")
127
+ `chmod o-w #{origen_root}/.bin` if File.exist?("#{origen_root}/.bin")
128
+ result = false
129
+
130
+ Bundler.with_clean_env do
131
+ if Origen.os.unix?
132
+ if Origen.site_config.gem_build_switches
133
+ Origen.site_config.gem_build_switches.each do |switches|
134
+ `bundle config build.#{switches}`
135
+ end
136
+ end
137
+ end
138
+ result = system(cmd)
139
+ end
140
+ `chmod o-w #{ENV['BUNDLE_BIN']}`
141
+ # Make .bat versions of all executables, Bundler should really be doing this when running
142
+ # on windows
143
+ if Origen.os.windows?
144
+ bat_present = File.exist? "#{origen_root}/lbin/origen.bat"
145
+ Dir.glob("#{origen_root}/lbin/*").each do |bin|
146
+ unless bin =~ /.bat$/
147
+ bat = "#{bin}.bat"
148
+ unless File.exist?(bat)
149
+ File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') }
150
+ end
151
+ end
152
+ end
153
+ if !bat_present && !result
154
+ puts 'Some Windows specific updates to your workspace were required, please re-run the last command'
155
+ exit 0
156
+ end
157
+ end
158
+ if result
159
+ exec "origen #{ARGV.join(' ')}"
160
+ exit 0
161
+ else
162
+ puts
163
+ puts "If you have just updated a gem version and are now getting an error that Bundler cannot find compatible versions for it then first try running 'bundle update <gemname>'."
164
+ puts "For example if you have just changed the version of origen_core run 'bundle update origen_core'."
165
+ exit 1
166
+ end
167
+ end
168
+ else
169
+ Bundler.setup
170
+ end
171
+ end
172
+ require 'bundler/setup'
173
+ if Origen.site_config.use_bootsnap && !Origen.os.windows?
174
+ puts 'Gettin bootsnappy up in here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
175
+ ENV["BOOTSNAP_CACHE_DIR"] ||= "#{origen_root}/tmp/cache"
176
+ require 'bootsnap/setup'
177
+ else
178
+ puts 'NOT SO SNAPPY'
179
+ end
180
+ require 'origen'
181
+ else
182
+ $LOAD_PATH.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
183
+ require 'origen'
184
+ end
185
+
186
+ begin
187
+ # If this script has been invoked from within an Origen application then open
188
+ # up all commands, if not then only allow the command to create a new Origen
189
+ # application.
190
+ if origen_root && boot_app
191
+ require 'origen/commands'
192
+ else
193
+ require 'origen/commands_global'
194
+ end
195
+ rescue Exception => e
196
+ # A formatted stack dump will not be printed if the application ends via 'exit 0' or 'exit 1'. In that
197
+ # case the application code is responsible for printing a helpful error message.
198
+ # This will intercept all other exits, e.g. via 'fail "Something has done wrong"', and split the stack
199
+ # dump to separate all in-application references from Origen core/plugin references.
200
+ if e.is_a?(SystemExit)
201
+ exit e.status
202
+ else
203
+ puts
204
+ if Origen.app_loaded?
205
+ puts 'COMPLETE CALL STACK'
206
+ puts '-------------------'
207
+ puts e.message unless e.is_a?(SystemExit)
208
+ puts e.backtrace
209
+
210
+ puts
211
+ puts 'APPLICATION CALL STACK'
212
+ puts '----------------------'
213
+ puts e.message unless e.is_a?(SystemExit)
214
+ # Only print out the application stack trace by default, if verbose logging is
215
+ # enabled then output the full thing
216
+ e.backtrace.each do |line|
217
+ path = Pathname.new(line)
218
+ if path.absolute?
219
+ if line =~ /^#{Origen.root}/ && line !~ /^#{Origen.root}\/lbin/
220
+ puts line
221
+ end
222
+ else
223
+ puts line unless line =~ /^.\/lbin/
224
+ end
225
+ end
226
+ else
227
+ puts 'COMPLETE CALL STACK'
228
+ puts '-------------------'
229
+ puts e.message unless e.is_a?(SystemExit)
230
+ puts e.backtrace
231
+ end
232
+ exit 1
233
+ end
234
+ ensure
235
+ if Origen.app_loaded?
236
+ Origen.app.listeners_for(:on_origen_shutdown).each(&:on_origen_shutdown)
237
+ Origen.app.runner.shutdown
238
+ end
239
+ end
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Origen
2
2
  MAJOR = 0
3
- MINOR = 40
4
- BUGFIX = 2
3
+ MINOR = 41
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -247,16 +247,21 @@ module Origen
247
247
  unless reg.description.empty?
248
248
  reg.description.each { |l| lines << indent + "# #{l}" }
249
249
  end
250
- lines << indent + "model.add_reg :#{id}, #{reg.offset.to_hex}, size: #{reg.size} do |reg|"
250
+ lines << indent + "model.add_reg :#{id}, #{reg.offset.to_hex}, size: #{reg.size} #{reg.bit_order == :msb0 ? ', bit_order: :msb0' : ''} do |reg|"
251
251
  indent = ' ' * ((options[:indent] || 0) + 2)
252
252
  reg.named_bits.each do |name, bits|
253
253
  unless bits.description.empty?
254
254
  bits.description.each { |l| lines << indent + "# #{l}" }
255
255
  end
256
+ position = reg.bit_order == :msb0 ? (reg.size - bits.position - 1) : bits.position
256
257
  if bits.size == 1
257
- line = indent + "reg.bit #{bits.position}, :#{name}"
258
+ line = indent + "reg.bit #{position}, :#{name}"
258
259
  else
259
- line = indent + "reg.bit #{bits.position + bits.size - 1}..#{bits.position}, :#{name}"
260
+ if reg.bit_order == :msb0
261
+ line = indent + "reg.bit #{position - bits.size + 1}..#{position}, :#{name}"
262
+ else
263
+ line = indent + "reg.bit #{position + bits.size - 1}..#{position}, :#{name}"
264
+ end
260
265
  end
261
266
  unless bits.access == :rw
262
267
  line << ", access: :#{bits.access}"
@@ -68,6 +68,11 @@ module Origen
68
68
  end
69
69
  end
70
70
 
71
+ # Prevent infinite loop if a child bit collection checks bit_order
72
+ def bit_order
73
+ parent.bit_order
74
+ end
75
+
71
76
  def drive(value = nil, options = {})
72
77
  value, options = nil, value if value.is_a?(Hash)
73
78
  if options[:index]
@@ -19,12 +19,13 @@ module Origen
19
19
  attr_accessor :name
20
20
  alias_method :id, :name
21
21
 
22
- def initialize(reg, name, data = []) # :nodoc:
22
+ def initialize(reg, name, data = [], options = {}) # :nodoc:
23
23
  if reg.respond_to?(:has_bits_enabled_by_feature?) && reg.has_parameter_bound_bits?
24
24
  reg.update_bound_bits unless reg.updating_bound_bits?
25
25
  end
26
26
  @reg = reg
27
27
  @name = name
28
+ @with_bit_order = options[:with_bit_order] || :lsb0
28
29
  [data].flatten.each { |item| self << item }
29
30
  end
30
31
 
@@ -33,6 +34,31 @@ module Origen
33
34
  parent.bit_order
34
35
  end
35
36
 
37
+ # Returns the bit numbering order to use when interpreting indeces
38
+ def with_bit_order
39
+ @with_bit_order
40
+ end
41
+
42
+ # Allow bit number interpreting to be explicitly set to msb0
43
+ def with_msb0
44
+ @with_bit_order = :msb0
45
+ self
46
+ end
47
+
48
+ # Allow bit number interpreting to be explicitly set to lsb0
49
+ def with_lsb0
50
+ if block_given?
51
+ # run just the code block with lsb0 numbering (for internal methods)
52
+ saved_wbo = @with_bit_order
53
+ @with_bit_order = :lsb0
54
+ yield
55
+ @with_bit_order = saved_wbo
56
+ else
57
+ @with_bit_order = :lsb0
58
+ self
59
+ end
60
+ end
61
+
36
62
  def terminal?
37
63
  true
38
64
  end
@@ -41,6 +67,24 @@ module Origen
41
67
  parent.bind(name, live_parameter)
42
68
  end
43
69
 
70
+ # Access bits by index
71
+ #
72
+ # **Note** This method behaves differently depending on the setting of @with_bit_order
73
+ #
74
+ # If @with_bit_order == :lsb0 (default) index 0 refers to the lsb of the bit collection
75
+ # If @with_bit_order == :msb0 index 0 refers to the msb of the bit collection
76
+ #
77
+ # ==== Example
78
+ # dut.reg(:some_reg).bits(:some_field).with_msb0[0..1] # returns 2 most significant bits
79
+ # dut.reg(:some_reg).bits(:some_field)[0..1] # returns 2 least significant bits
80
+ #
81
+ # **Note** Internal methods should call this method using a with_lsb0 block around the code
82
+ # or alternatively use the shift_out methods
83
+ # ==== Example
84
+ # with_lsb0 do
85
+ # saved_bit = [index]
86
+ # [index] = some_new_bit_or_operation
87
+ # end
44
88
  def [](*indexes)
45
89
  return self if indexes.empty?
46
90
  b = BitCollection.new(parent, name)
@@ -52,7 +96,8 @@ module Origen
52
96
  if b.size == 1
53
97
  b.first
54
98
  else
55
- b
99
+ # maintain downstream bit numbering setting
100
+ @with_bit_order == :msb0 ? b.with_msb0 : b
56
101
  end
57
102
  end
58
103
  alias_method :bits, :[]
@@ -174,16 +219,18 @@ module Origen
174
219
  puts
175
220
  fail 'Mismatched size for bit collection copy'
176
221
  end
177
- size.times do |i|
178
- source_bit = reg.bit[i]
179
- if source_bit
180
- self[i].overlay(source_bit.overlay_str) if source_bit.has_overlay?
181
- self[i].write(source_bit.data)
182
-
183
- self[i].read if source_bit.is_to_be_read?
184
- self[i].store if source_bit.is_to_be_stored?
222
+ # safely handle collections with differing with_bit_order settings
223
+ with_lsb0 do
224
+ reg.shift_out_with_index do |source_bit, i|
225
+ if source_bit
226
+ self[i].overlay(source_bit.overlay_str) if source_bit.has_overlay?
227
+ self[i].write(source_bit.data)
228
+
229
+ self[i].read if source_bit.is_to_be_read?
230
+ self[i].store if source_bit.is_to_be_stored?
231
+ end
185
232
  end
186
- end
233
+ end # of with_lsb0
187
234
  else
188
235
  write(reg)
189
236
  clear_flags
@@ -331,8 +378,10 @@ module Origen
331
378
  end
332
379
  value = value.data if value.respond_to?('data')
333
380
 
334
- size.times do |i|
335
- self[i].write(value[i], options)
381
+ with_lsb0 do
382
+ size.times do |i|
383
+ self[i].write(value[i], options)
384
+ end
336
385
  end
337
386
  self
338
387
  end
@@ -402,38 +451,26 @@ module Origen
402
451
  # bist_shift(bit)
403
452
  # end
404
453
  def shift_out_left
405
- if bit_order == :msb0
406
- each { |bit| yield bit }
407
- else
408
- reverse_each { |bit| yield bit }
409
- end
454
+ # This is functionally equivalent to reverse_shift_out
455
+ reverse_each { |bit| yield bit }
410
456
  end
411
457
 
412
458
  # Same as Reg#shift_out_left but includes the index counter
413
459
  def shift_out_left_with_index
414
- if bit_order == :msb0
415
- each.with_index { |bit, i| yield bit, i }
416
- else
417
- reverse_each.with_index { |bit, i| yield bit, i }
418
- end
460
+ # This is functionally equivalent to reverse_shift_out_with_index
461
+ reverse_each.with_index { |bit, i| yield bit, i }
419
462
  end
420
463
 
421
- # Same as Reg#shift_out_left but starts from the MSB
464
+ # Same as Reg#shift_out_left but starts from the LSB
422
465
  def shift_out_right
423
- if bit_order == :msb0
424
- reverse_each { |bit| yield bit }
425
- else
426
- each { |bit| yield bit }
427
- end
466
+ # This is functionally equivalent to shift_out, actually sends LSB first
467
+ each { |bit| yield bit }
428
468
  end
429
469
 
430
470
  # Same as Reg#shift_out_right but includes the index counter
431
471
  def shift_out_right_with_index
432
- if bit_order == :msb0
433
- reverse_each.with_index { |bit, i| yield bit, i }
434
- else
435
- each_with_index { |bit, i| yield bit, i }
436
- end
472
+ # This is functionally equivalent to shift_out_with_index
473
+ each_with_index { |bit, i| yield bit, i }
437
474
  end
438
475
 
439
476
  # Yields each bit in the register, LSB first.
@@ -985,7 +1022,13 @@ module Origen
985
1022
  ixs << index
986
1023
  end
987
1024
  end
988
- ixs.flatten.sort
1025
+ ixs.flatten!
1026
+ # ixs.sort!
1027
+ # convert msb0 numbering (if provided) to lsb0 numbering to get the correct bits
1028
+ if @with_bit_order == :msb0
1029
+ ixs.each_index { |i| ixs[i] = size - ixs[i] - 1 }
1030
+ end
1031
+ ixs.sort
989
1032
  end
990
1033
  end
991
1034
  end
@@ -0,0 +1,47 @@
1
+ module Origen
2
+ module Registers
3
+ require 'delegate'
4
+
5
+ # Thin wrapper around register objects to modify bit number interpretation
6
+ #
7
+ # This is provided as a convenience to make user code more readable
8
+ class Msb0Delegator < ::Delegator
9
+ def initialize(reg_object, bits)
10
+ @reg_object = reg_object
11
+ @bits = bits
12
+ end
13
+
14
+ def __getobj__
15
+ @reg_object
16
+ end
17
+
18
+ def __object__
19
+ @reg_object
20
+ end
21
+
22
+ def __setobj__(obj)
23
+ @reg_object = obj
24
+ end
25
+
26
+ def inspect(options = {})
27
+ options[:with_bit_order] = :msb0
28
+ @reg_object.inspect(options)
29
+ end
30
+
31
+ def method_missing(method, *args, &block)
32
+ if args.last.is_a?(Hash)
33
+ args.last[:with_bit_order] = :msb0
34
+ else
35
+ args << { with_bit_order: :msb0 }
36
+ end
37
+ @reg_object.method_missing(method, *args, &block)
38
+ end
39
+
40
+ def bit(*args)
41
+ @reg_object.bit(args, with_bit_order: :msb0)
42
+ end
43
+ alias_method :bits, :bit
44
+ alias_method :[], :bit
45
+ end
46
+ end
47
+ end
@@ -1,4 +1,5 @@
1
1
  require 'json'
2
+ require 'origen/registers/msb0_delegator'
2
3
  module Origen
3
4
  module Registers
4
5
  # The register class can be used to represent not only h/ware resgisters,
@@ -91,7 +92,20 @@ module Origen
91
92
  @bits << Bit.new(self, n, writable: @init_as_writable, undefined: true)
92
93
  end
93
94
 
95
+ # Internally re-map msb0 register descriptions as lsb0
96
+ options.each_value { |bit_desc| bit_desc[:pos] = @size - bit_desc[:pos] - bit_desc[:bits] } if bit_order == :msb0
97
+
94
98
  add_bits_from_options(options)
99
+
100
+ @msb0_delegator = Msb0Delegator.new(self, @bits)
101
+ end
102
+
103
+ def with_msb0
104
+ @msb0_delegator
105
+ end
106
+
107
+ def with_lsb0
108
+ self
95
109
  end
96
110
 
97
111
  # Returns the bit order attribute of the register (either :msb0 or :lsb0). If
@@ -134,6 +148,18 @@ module Origen
134
148
  end
135
149
 
136
150
  def inspect(options = {})
151
+ wbo = options[:with_bit_order] || :lsb0
152
+ domsb0 = wbo == :msb0
153
+ dolsb0 = !domsb0
154
+ if wbo != bit_order
155
+ Origen.log.warn "Register displayed with #{wbo} numbering, but defined with #{bit_order} numbering"
156
+ Origen.log.warn 'Access (and display) this register with explicit numbering like this:'
157
+ Origen.log.warn ''
158
+ Origen.log.warn " reg(:#{name}).with_msb0 # bit numbering scheme is msb0"
159
+ Origen.log.warn " reg(:#{name}).with_lsb0 # bit numbering scheme is lsb0 (default)"
160
+ Origen.log.warn " reg(:#{name}) # bit numbering scheme is lsb0 (default)"
161
+ end
162
+
137
163
  # This fancy_output option is passed in via option hash
138
164
  # Even better, the output could auto-detect 7-bit vs 8-bit terminal output and adjust the parameter, but that's for another day
139
165
  fancy_output = options[:fancy_output].nil? ? true : options[:fancy_output]
@@ -173,14 +199,10 @@ module Origen
173
199
  bit_width = 13
174
200
  desc = ["\n0x%X - :#{name}" % address]
175
201
  r = size % 8
176
- if r == 0 || (size > 8 && bit_order == :msb0)
202
+ if r == 0 # || (size > 8 && domsb0)
177
203
  desc << (' ' + corner_double_up_left + ((horiz_double_line * bit_width + horiz_double_tee_down) * 8)).chop + corner_double_up_right
178
204
  else
179
- if bit_order == :lsb0
180
- desc << (' ' + (' ' * (bit_width + 1) * (8 - r)) + corner_double_up_left + ((horiz_double_line * bit_width + horiz_double_tee_down) * r)).chop + corner_double_up_right
181
- else
182
- desc << (' ' + corner_double_up_left + ((horiz_double_line * bit_width + horiz_double_tee_down) * r)).chop + corner_double_up_right
183
- end
205
+ desc << (' ' + (' ' * (bit_width + 1) * (8 - r)) + corner_double_up_left + ((horiz_double_line * bit_width + horiz_double_tee_down) * r)).chop + corner_double_up_right
184
206
  end
185
207
 
186
208
  # "<#{self.class}: #{self.name}>"
@@ -188,32 +210,22 @@ module Origen
188
210
  num_bytes.times do |byte_index|
189
211
  # Need to add support for little endian regs here?
190
212
  byte_number = num_bytes - byte_index
191
- if bit_order == :lsb0
192
- max_bit = (byte_number * 8) - 1
193
- min_bit = max_bit - 8 + 1
194
- else
195
- min_bit = (byte_index * 8)
196
- max_bit = min_bit + 7
197
- end
213
+ max_bit = (byte_number * 8) - 1
214
+ min_bit = max_bit - 8 + 1
198
215
 
199
216
  # BIT INDEX ROW
200
217
  line = ' '
201
218
  line_complete = false
202
219
  8.times do |i|
203
- if bit_order == :lsb0
204
- bit_num = (byte_number * 8) - i - 1
205
- else
206
- bit_num = (byte_index * 8) + i
207
- end
220
+ bit_num = (byte_number * 8) - i - 1
208
221
  if bit_num > size - 1
209
- if bit_order == :msb0 && bit_num == size
210
- line += vert_single_line
211
- line_complete = true
222
+ line << ' ' + ''.center(bit_width) unless line_complete
223
+ else
224
+ if dolsb0
225
+ line << vert_single_line + "#{bit_num}".center(bit_width)
212
226
  else
213
- line << ' ' + ''.center(bit_width) unless line_complete
227
+ line << vert_single_line + "#{size - bit_num - 1}".center(bit_width)
214
228
  end
215
- else
216
- line << vert_single_line + "#{bit_num}".center(bit_width)
217
229
  end
218
230
  end
219
231
  line += vert_single_line unless line_complete
@@ -225,11 +237,9 @@ module Origen
225
237
  line_complete = false
226
238
  named_bits include_spacers: true do |name, bit, bitcounter|
227
239
  if _bit_in_range?(bit, max_bit, min_bit)
228
- if bit_order == :lsb0
229
- if max_bit > (size - 1) && !first_done
230
- (max_bit - (size - 1)).times do
231
- line << ' ' * (bit_width + 1)
232
- end
240
+ if max_bit > (size - 1) && !first_done
241
+ (max_bit - (size - 1)).times do
242
+ line << ' ' * (bit_width + 1)
233
243
  end
234
244
  end
235
245
 
@@ -237,17 +247,13 @@ module Origen
237
247
 
238
248
  if name
239
249
  if bitcounter.nil?
240
- if bit_order == :lsb0
241
- bit_name = "#{name}[#{_max_bit_in_range(bit, max_bit, min_bit)}:#{_min_bit_in_range(bit, max_bit, min_bit)}]"
242
- else
243
- bit_name = "#{name}[#{_min_bit_in_range(bit, max_bit, min_bit)}:#{_max_bit_in_range(bit, max_bit, min_bit)}]"
244
- end
250
+ bit_name = "#{name}[#{_max_bit_in_range(bit, max_bit, min_bit, options)}:#{_min_bit_in_range(bit, max_bit, min_bit, options)}]"
245
251
  bit_span = _num_bits_in_range(bit, max_bit, min_bit)
246
252
 
247
253
  else
248
- upper = _max_bit_in_range(bit, max_bit, min_bit) + bitcounter - bit.size
249
- lower = _min_bit_in_range(bit, max_bit, min_bit) + bitcounter - bit.size
250
- if bit_order == :lsb0
254
+ upper = _max_bit_in_range(bit, max_bit, min_bit, options) + bitcounter - bit.size
255
+ lower = _min_bit_in_range(bit, max_bit, min_bit, options) + bitcounter - bit.size
256
+ if dolsb0
251
257
  bit_name = "#{name}[#{upper}:#{lower}]"
252
258
  else
253
259
  bit_name = "#{name}[#{upper}:#{lower}]"
@@ -293,11 +299,9 @@ module Origen
293
299
  first_done = false
294
300
  named_bits include_spacers: true do |name, bit, _bitcounter|
295
301
  if _bit_in_range?(bit, max_bit, min_bit)
296
- if bit_order == :lsb0
297
- if max_bit > (size - 1) && !first_done
298
- (max_bit - (size - 1)).times do
299
- line << ' ' * (bit_width + 1)
300
- end
302
+ if max_bit > (size - 1) && !first_done
303
+ (max_bit - (size - 1)).times do
304
+ line << ' ' * (bit_width + 1)
301
305
  end
302
306
  end
303
307
 
@@ -348,12 +352,8 @@ module Origen
348
352
 
349
353
  if size >= 8
350
354
  r = size % 8
351
- if byte_index == 0 && r != 0 && bit_order == :lsb0
355
+ if byte_index == 0 && r != 0
352
356
  desc << (' ' + corner_double_up_left + ((horiz_double_line * bit_width + horiz_double_tee_down) * (8 - r)).chop + horiz_double_cross + (horiz_single_line * (bit_width + 1) * r)).chop + vert_single_tee_left
353
- elsif (byte_index == num_bytes - 1) && r != 0 && bit_order == :msb0
354
- desc << (' ' + corner_single_down_left + ((horiz_single_line * bit_width + horiz_single_tee_up) * r)).chop + corner_single_down_right
355
- elsif (byte_index == num_bytes - 2) && r != 0 && bit_order == :msb0
356
- desc << ' ' + vert_single_tee_right + ((horiz_single_line * bit_width + horiz_single_cross) * r) + ((horiz_single_line * bit_width + horiz_single_tee_up) * (8 - r)).chop + corner_single_down_right
357
357
  else
358
358
  if byte_index == num_bytes - 1
359
359
  desc << (' ' + corner_single_down_left + ((horiz_single_line * bit_width + horiz_single_tee_up) * 8)).chop + corner_single_down_right
@@ -362,11 +362,7 @@ module Origen
362
362
  end
363
363
  end
364
364
  else
365
- if bit_order == :lsb0
366
- desc << (' ' + (' ' * (bit_width + 1) * (8 - size)) + corner_single_down_left + ((horiz_single_line * bit_width + horiz_single_tee_up) * size)).chop + corner_single_down_right
367
- else
368
- desc << (' ' + corner_single_down_left + ((horiz_single_line * bit_width + horiz_single_tee_up) * size)).chop + corner_single_down_right
369
- end
365
+ desc << (' ' + (' ' * (bit_width + 1) * (8 - size)) + corner_single_down_left + ((horiz_single_line * bit_width + horiz_single_tee_up) * size)).chop + corner_single_down_right
370
366
  end
371
367
  end
372
368
  desc.join("\n")
@@ -584,24 +580,13 @@ module Origen
584
580
  @lookup.each { |_k, v| split_bits = true if v.is_a? Array }
585
581
 
586
582
  if split_bits == false
587
- if bit_order == :lsb0
588
- current_pos = size
589
- else
590
- current_pos = 0
591
- end
583
+ current_pos = size
584
+
592
585
  # Sort by position
593
- @lookup.sort_by { |_name, details| bit_order == :lsb0 ? -details[:pos] : details[:pos] }.each do |name, details|
594
- if bit_order == :lsb0
595
- pos = details[:bits] + details[:pos]
596
- else
597
- pos = details[:pos]
598
- end
586
+ @lookup.sort_by { |_name, details| -details[:pos] }.each do |name, details|
587
+ pos = details[:bits] + details[:pos]
599
588
  if options[:include_spacers] && (pos != current_pos)
600
- if bit_order == :lsb0
601
- collection = BitCollection.dummy(self, nil, size: current_pos - pos, pos: pos)
602
- else
603
- collection = BitCollection.dummy(self, nil, size: pos - current_pos, pos: current_pos)
604
- end
589
+ collection = BitCollection.dummy(self, nil, size: current_pos - pos, pos: pos)
605
590
  unless collection.size == 0
606
591
  if block_given?
607
592
  yield nil, collection
@@ -621,19 +606,10 @@ module Origen
621
606
  result << [name, collection]
622
607
  end
623
608
  end
624
- if bit_order == :lsb0
625
- current_pos = details[:pos]
626
- else
627
- current_pos = details[:bits] + details[:pos]
628
- end
609
+ current_pos = details[:pos]
629
610
  end
630
- if options[:include_spacers] && ((bit_order == :lsb0 && current_pos != 0) ||
631
- bit_order == :msb0 && current_pos != size)
632
- if bit_order == :lsb0
633
- collection = BitCollection.dummy(self, nil, size: current_pos, pos: 0)
634
- else
635
- collection = BitCollection.dummy(self, nil, size: size - current_pos, pos: current_pos)
636
- end
611
+ if options[:include_spacers] && (current_pos != 0)
612
+ collection = BitCollection.dummy(self, nil, size: current_pos, pos: 0)
637
613
  unless collection.size == 0
638
614
  if block_given?
639
615
  yield nil, collection
@@ -1061,10 +1037,12 @@ module Origen
1061
1037
  alias_method :delete_bits, :delete_bit
1062
1038
 
1063
1039
  # @api private
1064
- def expand_range(range)
1040
+ def expand_range(range, wbo = :lsb0)
1065
1041
  if range.first > range.last
1066
1042
  range = Range.new(range.last, range.first)
1067
1043
  end
1044
+ range = range.to_a
1045
+ range.reverse! if wbo == :msb0
1068
1046
  range.each do |i|
1069
1047
  yield i
1070
1048
  end
@@ -1086,13 +1064,22 @@ module Origen
1086
1064
  # reg(:control).bit(1) # => Returns a BitCollection containing status bit
1087
1065
  # reg(:control).bit(1,2) # => Returns a BitCollection containing both status bits
1088
1066
  def bit(*args)
1067
+ # allow msb0 bit numbering if requested
1068
+ wbo = :lsb0
1069
+ if args.last.is_a?(Hash)
1070
+ wbo = args.last.delete(:with_bit_order) || :lsb0
1071
+ args.pop if args.last.size == 0
1072
+ end
1073
+
1089
1074
  multi_bit_names = false
1090
1075
  # return get_bits_with_constraint(nil,:default) if args.size == 0
1091
1076
  constraint = extract_feature_params(args)
1092
1077
  if constraint.nil?
1093
1078
  constraint = :default
1094
1079
  end
1095
- collection = BitCollection.new(self, :unknown)
1080
+
1081
+ collection = BitCollection.new(self, :unknown, [], with_bit_order: wbo)
1082
+
1096
1083
  if args.size == 0
1097
1084
  collection.add_name(name)
1098
1085
  @bits.each do |bit|
@@ -1101,13 +1088,14 @@ module Origen
1101
1088
  else
1102
1089
  args.flatten!
1103
1090
  args.sort!
1091
+ args.reverse! if wbo == :msb0
1104
1092
  args.each do |arg_item|
1105
1093
  if arg_item.is_a?(Integer)
1106
- b = get_bits_with_constraint(arg_item, constraint)
1094
+ b = get_bits_with_constraint(arg_item, constraint, with_bit_order: wbo)
1107
1095
  collection << b if b
1108
1096
  elsif arg_item.is_a?(Range)
1109
- expand_range(arg_item) do |bit_number|
1110
- collection << get_bits_with_constraint(bit_number, constraint)
1097
+ expand_range(arg_item, wbo) do |bit_number|
1098
+ collection << get_bits_with_constraint(bit_number, constraint, with_bit_order: wbo)
1111
1099
  end
1112
1100
  else
1113
1101
  multi_bit_names = args.size > 1
@@ -1140,14 +1128,21 @@ module Origen
1140
1128
  else
1141
1129
  if multi_bit_names
1142
1130
  collection.sort_by!(&:position)
1131
+ wbo == :msb0 ? collection.with_msb0 : collection.with_lsb0
1143
1132
  end
1144
- collection
1133
+ wbo == :msb0 ? collection.with_msb0 : collection.with_lsb0
1145
1134
  end
1146
1135
  end
1147
1136
  alias_method :bits, :bit
1148
1137
  alias_method :[], :bit
1149
1138
 
1150
- def get_bits_with_constraint(number, params)
1139
+ def get_bits_with_constraint(number, params, options = {})
1140
+ options = { with_bit_order: :lsb0 }.merge(options)
1141
+ # remap to lsb0 number to grab correct bit
1142
+ if options[:with_bit_order] == :msb0
1143
+ number = size - number - 1
1144
+ end
1145
+
1151
1146
  return nil unless @bits[number]
1152
1147
  if (params == :default || !params) && @bits[number].enabled?
1153
1148
  @bits[number]
@@ -1268,23 +1263,28 @@ module Origen
1268
1263
 
1269
1264
  # All other Reg methods are delegated to BitCollection
1270
1265
  def method_missing(method, *args, &block) # :nodoc:
1266
+ wbo = :lsb0
1267
+ if args.last.is_a?(Hash)
1268
+ wbo = args.last[:with_bit_order] if args.last.key?(:with_bit_order)
1269
+ end
1270
+
1271
1271
  if method.to_sym == :to_ary || method.to_sym == :to_hash
1272
1272
  nil
1273
1273
  elsif meta_data_method?(method)
1274
1274
  extract_meta_data(method, *args)
1275
1275
  else
1276
1276
  if BitCollection.instance_methods.include?(method)
1277
- to_bit_collection.send(method, *args, &block)
1277
+ to_bit_collection(with_bit_order: wbo).send(method, *args, &block)
1278
1278
  elsif has_bits?(method)
1279
- bits(method)
1279
+ bits(method, with_bit_order: wbo)
1280
1280
  else
1281
1281
  super
1282
1282
  end
1283
1283
  end
1284
1284
  end
1285
1285
 
1286
- def to_bit_collection
1287
- BitCollection.new(self, name, @bits)
1286
+ def to_bit_collection(options = {})
1287
+ BitCollection.new(self, name, @bits, options)
1288
1288
  end
1289
1289
 
1290
1290
  # Recognize that Reg responds to all BitCollection methods methods based on
@@ -1555,14 +1555,22 @@ module Origen
1555
1555
  end
1556
1556
  end
1557
1557
 
1558
- def _max_bit_in_range(bits, max, _min)
1558
+ def _max_bit_in_range(bits, max, _min, options = { with_bit_order: false })
1559
1559
  upper = bits.position + bits.size - 1
1560
- [upper, max].min - bits.position
1560
+ if options[:with_bit_order] == :msb0
1561
+ bits.size - ([upper, max].min - bits.position) - 1
1562
+ else
1563
+ [upper, max].min - bits.position
1564
+ end
1561
1565
  end
1562
1566
 
1563
- def _min_bit_in_range(bits, _max, min)
1567
+ def _min_bit_in_range(bits, _max, min, options = { with_bit_order: false })
1564
1568
  lower = bits.position
1565
- [lower, min].max - bits.position
1569
+ if options[:with_bit_order] == :msb0
1570
+ bits.size - ([lower, min].max - lower) - 1
1571
+ else
1572
+ [lower, min].max - bits.position
1573
+ end
1566
1574
  end
1567
1575
 
1568
1576
  # Returns true if some portion of the given bits falls
@@ -69,7 +69,7 @@ module Origen
69
69
  model.add_virtual_pin :relay1
70
70
  model.add_virtual_pin :relay2, packages: { bga: {} }
71
71
 
72
- model.sub_block :block1, file: 'origen/export1/block1.rb', dir: '/scratch/nxa21353/Code/github/origen/vendor/lib/models', lazy: true
72
+ model.sub_block :block1, file: 'origen/export1/block1.rb', dir: '/home/origen/users/pderouen/origen/vendor/lib/models', lazy: true
73
73
 
74
74
  end
75
75
  end
@@ -4,7 +4,7 @@ module Origen
4
4
  module Export1
5
5
  module Block1
6
6
  def self.extended(model)
7
- model.sub_block :x, file: 'origen/export1/block1/x.rb', dir: '/scratch/nxa21353/Code/github/origen/vendor/lib/models', lazy: true, base_address: 0x40000000
7
+ model.sub_block :x, file: 'origen/export1/block1/x.rb', dir: '/home/origen/users/pderouen/origen/vendor/lib/models', lazy: true, base_address: 0x40000000
8
8
 
9
9
  end
10
10
  end
@@ -8,7 +8,7 @@ module Origen
8
8
  # ** Some Control Register **
9
9
  # Blah, blah,
10
10
  # and some more blah
11
- model.add_reg :ctrl, 0x24, size: 16 do |reg|
11
+ model.add_reg :ctrl, 0x24, size: 16 do |reg|
12
12
  reg.bit 7, :coco, access: :ro
13
13
  reg.bit 6, :aien
14
14
  # **Some Diff Bit** - This is a...
@@ -19,6 +19,15 @@ module Origen
19
19
  reg.bit 5, :diff
20
20
  reg.bit 4..0, :adch, reset: 0x1F
21
21
  end
22
+ # ** A MSB0 Test Case **
23
+ # Blah-ba-bi-blah
24
+ # just following the comment pattern above
25
+ model.add_reg :msb0_test, 0x28, size: 16 , bit_order: :msb0 do |reg|
26
+ reg.bit 8, :ale
27
+ reg.bit 9, :xsfg
28
+ reg.bit 10, :yml
29
+ reg.bit 11..15, :field, reset: 0x1F
30
+ end
22
31
  end
23
32
  end
24
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.40.2
4
+ version: 0.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
@@ -383,6 +383,7 @@ extensions: []
383
383
  extra_rdoc_files: []
384
384
  files:
385
385
  - bin/origen
386
+ - bin/origen~
386
387
  - config/application.rb
387
388
  - config/boot.rb
388
389
  - config/commands.rb
@@ -561,6 +562,7 @@ files:
561
562
  - lib/origen/registers/bit_collection.rb
562
563
  - lib/origen/registers/container.rb
563
564
  - lib/origen/registers/domain.rb
565
+ - lib/origen/registers/msb0_delegator.rb
564
566
  - lib/origen/registers/reg.rb
565
567
  - lib/origen/registers/reg_collection.rb
566
568
  - lib/origen/regression_manager.rb