origen 0.40.2 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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