Module: Origen::SubBlocks
- Includes:
- Domains, Parent, Path, RegBaseAddress
- Defined in:
- lib/origen/sub_blocks.rb
Defined Under Namespace
Modules: Domains, Parent, Path, RegBaseAddress Classes: Placeholder
Class Method Summary collapse
- .lazy=(value) ⇒ Object
-
.lazy? ⇒ Boolean
Returns the default.
Instance Method Summary collapse
-
#all_sub_blocks ⇒ Object
Returns an array containing all descendant child objects of the given sub-block, i.e.
-
#custom_attrs ⇒ Object
Returns a hash containing all options that were passed to the sub_block definition.
-
#delete_sub_blocks ⇒ Object
Delete all sub_blocks by emptying the Hash.
- #has_fuses? ⇒ Boolean
- #has_tests? ⇒ Boolean
-
#init_sub_blocks(*args) ⇒ Object
private
This will be called whenever an object that includes this module is instantiated.
- #namespace ⇒ Object
-
#owns_registers? ⇒ Boolean
(also: #has_regs?)
Returns true if the given sub block owns at least one register.
- #sub_block(name = nil, options = {}) ⇒ Object
-
#sub_block_group(id, options = {}) ⇒ Object
(also: #sub_blocks_group)
Create a group of associated sub_blocks under a group name permits each sub_block to be of a different class e.g.
-
#sub_block_groups(*args, &block) ⇒ Object
Returns a hash containing all sub block groups thus far added if no arguments given.
-
#sub_blocks(*args) ⇒ Object
(also: #children)
Returns a hash containing all immediate children of the given sub-block.
- #sub_blocks_array ⇒ Object (also: #children_array)
Methods included from Path
#abs_path, #abs_path=, #path, #path=, #path_var
Methods included from RegBaseAddress
#base_address, #reg_base_address, #reg_base_address_for_domain
Methods included from Parent
Methods included from Domains
#domain, #domain_specified?, #domains
Class Method Details
.lazy=(value) ⇒ Object
44 45 46 |
# File 'lib/origen/sub_blocks.rb', line 44 def self.lazy=(value) @lazy = value end |
.lazy? ⇒ Boolean
Returns the default
40 41 42 |
# File 'lib/origen/sub_blocks.rb', line 40 def self.lazy? @lazy || false end |
Instance Method Details
#all_sub_blocks ⇒ Object
Returns an array containing all descendant child objects of the given sub-block, i.e. this returns an array containing children's children as well
Note that this returns an array instead of a hash since there could be naming collisions in the hash keys
267 268 269 |
# File 'lib/origen/sub_blocks.rb', line 267 def all_sub_blocks @all_sub_blocks ||= (sub_blocks_array + sub_blocks_array.map(&:all_sub_blocks)).flatten end |
#custom_attrs ⇒ Object
Returns a hash containing all options that were passed to the sub_block definition
49 50 51 |
# File 'lib/origen/sub_blocks.rb', line 49 def custom_attrs @custom_attrs end |
#delete_sub_blocks ⇒ Object
Delete all sub_blocks by emptying the Hash
253 254 255 |
# File 'lib/origen/sub_blocks.rb', line 253 def delete_sub_blocks @sub_blocks = {} end |
#has_fuses? ⇒ Boolean
281 282 283 |
# File 'lib/origen/sub_blocks.rb', line 281 def has_fuses? fuses.empty? ? false : true end |
#has_tests? ⇒ Boolean
285 286 287 |
# File 'lib/origen/sub_blocks.rb', line 285 def has_tests? tests.empty? ? false : true end |
#init_sub_blocks(*args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This will be called whenever an object that includes this module is instantiated
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/origen/sub_blocks.rb', line 7 def init_sub_blocks(*args) = args.find { |a| a.is_a?(Hash) } @custom_attrs = ( ? .dup : {}).with_indifferent_access # Delete these keys which are either meta data added by Origen or are already covered by # dedicated methods %w(parent name base_address reg_base_address base).each do |key| @custom_attrs.delete(key) end if # Using reg_base_address for storage to avoid class with the original Origen base # address API, but will accept any of these @reg_base_address = .delete(:reg_base_address) || .delete(:base_address) || .delete(:base) || 0 if [:_instance] # to be deprecated as part of multi-instance removal below if @reg_base_address.is_a?(Array) @reg_base_address = @reg_base_address[[:_instance]] elsif [:base_address_step] @reg_base_address = @reg_base_address + ([:_instance] * [:base_address_step]) end end @domain_names = [.delete(:domain) || .delete(:domains)].flatten.compact @domain_specified = !@domain_names.empty? @path = .delete(:path) @abs_path = .delete(:abs_path) || .delete(:absolute_path) end if is_a?(SubBlock) .each do |k, v| send("#{k}=", v) end end end |
#namespace ⇒ Object
427 428 429 |
# File 'lib/origen/sub_blocks.rb', line 427 def namespace self.class.to_s.sub(/::[^:]*$/, '') end |
#owns_registers? ⇒ Boolean Also known as: has_regs?
Returns true if the given sub block owns at least one register
272 273 274 275 276 277 278 |
# File 'lib/origen/sub_blocks.rb', line 272 def owns_registers? if regs regs.is_a?(Origen::Registers::RegCollection) && !regs.empty? else false end end |
#sub_block(name = nil, options = {}) ⇒ Object
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/origen/sub_blocks.rb', line 289 def sub_block(name = nil, = {}) name, = nil, name if name.is_a?(Hash) return sub_blocks unless name if name.is_a?(Class) return sub_blocks.select { |n, s| s.is_a?(name) } elsif name.origen_sub_block? return sub_block(name.class) end if i = .delete(:instances) # permit creating multiple instances of a particular sub_block class # can pass array for base_address, which will be processed above Origen.deprecate 'instances: option to sub_block is deprecated, use sub_block_groups instead' group_name = name =~ /s$/ ? name : "#{name}s" # take care if name already with 's' is passed unless respond_to?(group_name) sub_block_groups group_name do i.times do |j| o = .dup o[:_instance] = j sub_block("#{name}#{j}", o) end end end else block = Placeholder.new(self, name, ) # Allow additional attributes to be added to an existing sub-block if it hasn't # been instantiated yet. This is not supported yet for instantiated sub-blocks since # there are probably a lot more corner-cases to consider, and hopefully no one will # really need this anyway. # Note that override is to recreate an existing sub-block, not adding additional # attributes to an existing one if [:override] sub_blocks.delete(name.to_s) if [:class_name] constantizable = !![:class_name].safe_constantize # this is to handle the case where a previously instantiated subblock wont allow # the current class name to exist # e.g. NamespaceA::B::C # => NameSpaceX::Y::Z # After requiring the files, constants become sane again: # e.g. NamespaceA::B::C # => NameSpaceA::B::C if constantizable && ([:class_name] != [:class_name].constantize.to_s) block_dir = [:block_file] || _find_block_dir() # files that aren't initializing a new namespace and have special loading shouldn't be required # the code they contain may try to call methods that dont exist yet skip_require_files = [:skip_require_files] || %w(attributes parameters pins registers sub_blocks timesets) Dir.glob("#{block_dir}/*.rb").each do |file| next if skip_require_files.include?(Pathname.new(file).basename('.rb').to_s) require file end end end else if sub_blocks[name] && !sub_blocks[name].is_a?(Placeholder) fail "You have already defined a sub-block named #{name} within class #{self.class}" end end if respond_to?(name) && !(singleton_class.instance_methods.include?(name) && [:override]) callers = Origen.split_caller_line caller[0] Origen.log.warning "The sub_block defined at #{Pathname.new(callers[0]).relative_path_from(Pathname.pwd)}:#{callers[1]} is overriding an existing method called #{name}" end define_singleton_method name do sub_blocks[name] end if sub_blocks[name] && sub_blocks[name].is_a?(Placeholder) sub_blocks[name].add_attributes() else sub_blocks[name] = block end unless @current_group.nil? # a group is currently open, store sub_block id only @current_group << name end if .key?(:lazy) lazy = [:lazy] else lazy = Origen::SubBlocks.lazy? end lazy ? block : block.materialize end end |
#sub_block_group(id, options = {}) ⇒ Object Also known as: sub_blocks_group
Create a group of associated sub_blocks under a group name permits each sub_block to be of a different class e.g. sub_block_group :my_ip_group do
sub_block :ip0, class_name: 'IP0', base_address: 0x000000
sub_block :ip1, class_name: 'IP1', base_address: 0x000200
sub_block :ip2, class_name: 'IP2', base_address: 0x000400
sub_block :ip3, class_name: 'IP3', base_address: 0x000600
end
creates an array referenced by method called 'my_ip_group' which contains the sub_blocks 'ip0', 'ip1', 'ip2', 'ip3'.
Can also indicate a custom class container to hold these. This custom class container MUST support a '<<' method in order to add new sub_blocks to the container instance.
e.g. sub_block_group :my_ip_group, class_name: 'MYGRP' do
sub_block :ip0, class_name: 'IP0', base_address: 0x000000
sub_block :ip1, class_name: 'IP1', base_address: 0x000200
sub_block :ip2, class_name: 'IP2', base_address: 0x000400
sub_block :ip3, class_name: 'IP3', base_address: 0x000600
end
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/origen/sub_blocks.rb', line 399 def sub_block_group(id, = {}) @current_group = [] # open group yield # any sub_block calls within this block will have their ID added to @current_group my_group = @current_group.dup if respond_to?(id) callers = Origen.split_caller_line caller[0] Origen.log.warning "The sub_block_group defined at #{Pathname.new(callers[0]).relative_path_from(Pathname.pwd)}:#{callers[1]} is overriding an existing method called #{id}" end # Define a singleton method which will be called every time the sub_block_group is referenced # This is not called here but later when referenced define_singleton_method "#{id}" do sub_block_groups[id] end # Instantiate group if [:class_name] b = Object.const_get([:class_name]).new else b = [] # Will use Array if no class defined end # Add sub_blocks to group my_group.each do |group_id| b << send(group_id) end sub_block_groups[id] = b @current_group = nil # close group end |
#sub_block_groups(*args, &block) ⇒ Object
Returns a hash containing all sub block groups thus far added if no arguments given. If given a code block, will serve as alias to sub_block_group method. Does not handle arguments, no need at this time.
240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/origen/sub_blocks.rb', line 240 def sub_block_groups(*args, &block) if block_given? sub_block_group(*args, &block) else if args.empty? @sub_block_groups ||= {}.with_indifferent_access else fail 'sub_block_groups not meant to take arguments!' end end end |
#sub_blocks(*args) ⇒ Object Also known as: children
Returns a hash containing all immediate children of the given sub-block
227 228 229 230 231 232 233 |
# File 'lib/origen/sub_blocks.rb', line 227 def sub_blocks(*args) if args.empty? @sub_blocks ||= {}.with_indifferent_access else sub_block(*args) end end |
#sub_blocks_array ⇒ Object Also known as: children_array
257 258 259 |
# File 'lib/origen/sub_blocks.rb', line 257 def sub_blocks_array sub_blocks.map { |_name, sub_block| sub_block } end |