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

Instance Method Summary collapse

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

#owner=, #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

Returns:

  • (Boolean)


40
41
42
# File 'lib/origen/sub_blocks.rb', line 40

def self.lazy?
  @lazy || false
end

Instance Method Details

#all_sub_blocksObject

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



250
251
252
253
254
# File 'lib/origen/sub_blocks.rb', line 250

def all_sub_blocks
  @all_sub_blocks ||= begin
    (sub_blocks_array + sub_blocks_array.map(&:all_sub_blocks)).flatten
  end
end

#custom_attrsObject

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_blocksObject

Delete all sub_blocks by emptying the Hash



236
237
238
# File 'lib/origen/sub_blocks.rb', line 236

def delete_sub_blocks
  @sub_blocks = {}
end

#has_fuses?Boolean

Returns:

  • (Boolean)


266
267
268
# File 'lib/origen/sub_blocks.rb', line 266

def has_fuses?
  fuses.empty? ? false : true
end

#has_tests?Boolean

Returns:

  • (Boolean)


270
271
272
# File 'lib/origen/sub_blocks.rb', line 270

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)
  options = args.find { |a| a.is_a?(Hash) }
  @custom_attrs = (options ? options.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 options
    # 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 = options.delete(:reg_base_address) ||
                        options.delete(:base_address) || options.delete(:base) || 0
    if options[:_instance]                # to be deprecated as part of multi-instance removal below
      if @reg_base_address.is_a?(Array)
        @reg_base_address = @reg_base_address[options[:_instance]]
      elsif options[:base_address_step]
        @reg_base_address = @reg_base_address + (options[:_instance] * options[:base_address_step])
      end
    end
    @domain_names = [options.delete(:domain) || options.delete(:domains)].flatten.compact
    @domain_specified = !@domain_names.empty?
    @path = options.delete(:path)
    @abs_path = options.delete(:abs_path) || options.delete(:absolute_path)
  end
  if is_a?(SubBlock)
    options.each do |k, v|
      send("#{k}=", v)
    end
  end
end

#namespaceObject



382
383
384
# File 'lib/origen/sub_blocks.rb', line 382

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

Returns:

  • (Boolean)


257
258
259
260
261
262
263
# File 'lib/origen/sub_blocks.rb', line 257

def owns_registers?
  if regs
    regs.is_a?(Origen::Registers::RegCollection) && !regs.empty?
  else
    false
  end
end

#sub_block(name = nil, options = {}) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
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
# File 'lib/origen/sub_blocks.rb', line 274

def sub_block(name = nil, options = {})
  name, options = 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 = options.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 = options.dup
          o[:_instance] = j
          sub_block("#{name}#{j}", o)
        end
      end
    end
  else
    block = Placeholder.new(self, name, options)
    # 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.
    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
    if respond_to?(name)
      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
      get_sub_block(name)
    end
    if sub_blocks[name] && sub_blocks[name].is_a?(Placeholder)
      sub_blocks[name].add_attributes(options)
    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 options.key?(:lazy)
      lazy = options[:lazy]
    else
      lazy = Origen::SubBlocks.lazy?
    end
    lazy ? block : block.materialize
  end
end

#sub_block_group(id, options = {}) ⇒ Object Also known as: sub_block_groups, sub_blocks_groups, 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



357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/origen/sub_blocks.rb', line 357

def sub_block_group(id, options = {})
  @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_singleton_method "#{id}" do
    if options[:class_name]
      b = Object.const_get(options[:class_name]).new
    else
      b = []
    end
    my_group.each do |group_id|
      b << send(group_id)
    end
    b                         # return array inside new singleton method
  end
  @current_group = nil   # close group
end

#sub_blocks(*args) ⇒ Object Also known as: children

Returns a hash containing all immediate children of the given sub-block



226
227
228
229
230
231
232
# File 'lib/origen/sub_blocks.rb', line 226

def sub_blocks(*args)
  if args.empty?
    @sub_blocks ||= {}.with_indifferent_access
  else
    sub_block(*args)
  end
end

#sub_blocks_arrayObject Also known as: children_array



240
241
242
# File 'lib/origen/sub_blocks.rb', line 240

def sub_blocks_array
  sub_blocks.map { |_name, sub_block| sub_block }
end