origen 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/lib/origen/pins.rb CHANGED
@@ -170,7 +170,6 @@ module Origen
170
170
  # about dealing with a single pin vs. a collection.
171
171
  module Pins
172
172
  autoload :Pin, 'origen/pins/pin'
173
- autoload :Port, 'origen/pins/port'
174
173
  autoload :PinCollection, 'origen/pins/pin_collection'
175
174
  autoload :PinBank, 'origen/pins/pin_bank'
176
175
  autoload :PinCommon, 'origen/pins/pin_common'
@@ -313,11 +312,6 @@ module Origen
313
312
  Origen.app.pin_pattern_exclude << options unless options.empty?
314
313
  end
315
314
 
316
- # API v2, deprecated
317
- def add_port(id, options = {})
318
- add_pins(id, options)
319
- end
320
-
321
315
  def add_pin_alias(new_name, original_name, options = {})
322
316
  if pin_groups.include?(original_name) # this is a pin group
323
317
  if options[:pin] # alias single pin from a pin group
@@ -331,7 +325,6 @@ module Origen
331
325
  end
332
326
  alias_method :pin_alias, :add_pin_alias
333
327
  alias_method :alias_pin, :add_pin_alias
334
- alias_method :add_port_alias, :add_pin_alias
335
328
 
336
329
  def add_pin_group_alias(new_name, original_name, options = {})
337
330
  group = Origen.pin_bank.find_or_create_pin_group(new_name, self, options)
@@ -592,8 +585,6 @@ If you meant to define the pin then use the add_pin method instead.
592
585
  end
593
586
  end
594
587
  alias_method :pin, :pins
595
- alias_method :port, :pins
596
- alias_method :ports, :pins
597
588
 
598
589
  # Equivalent to the pins method but considers power pins rather than regular pins
599
590
  def power_pins(id = nil, options = {}, &block)
@@ -630,67 +621,5 @@ If you meant to define the pin then use the add_pin method instead.
630
621
  fail "Error: the object #{id} you tried to delete is not a pin or pingroup"
631
622
  end
632
623
  end
633
-
634
- # @api private
635
- #
636
- # If the pin is a port it will select the target pin from it based on the options
637
- #
638
- # API v2, deprecated
639
- def resolve_pin(obj, options)
640
- if obj.is_a?(Port)
641
- pins = options[:pin] || options[:pins]
642
- if pins
643
- pins = clean_pin_arg(pins)
644
- if pins.size == 1
645
- obj[pins.first]
646
- else
647
- port = Port.new("subset_of_#{obj.id}", obj.owner, add_pins: false, size: pins.size)
648
- pins.each do |pin|
649
- port.add_pin_object(obj[pin])
650
- end
651
- port
652
- end
653
- else
654
- obj
655
- end
656
- else
657
- obj
658
- end
659
- end
660
-
661
- # @api private
662
- #
663
- # Returns an array of ids, regardless if the input is a single number, an array,
664
- # a range, or an array contaning a range
665
- #
666
- # API v2, deprecated
667
- def clean_pin_arg(pin)
668
- pin = [pin].flatten
669
- pin.map { |obj| range_to_array(obj) }.flatten.sort
670
- end
671
-
672
- # @api private
673
- #
674
- # API v2, deprecated
675
- def range_to_array(range)
676
- if range.is_a?(Range)
677
- a = range.first
678
- b = range.last
679
- if a > b
680
- (b..a).to_a
681
- else
682
- (a..b).to_a
683
- end
684
- else
685
- range
686
- end
687
- end
688
-
689
- # API v2, deprecated
690
- # @api private
691
- def add_pin_object(pin)
692
- @pins ||= {}
693
- @pins[@pins.size] = pin
694
- end
695
624
  end
696
625
  end
@@ -22,8 +22,6 @@ module Origen
22
22
  attr_accessor :repeat_previous
23
23
  attr_reader :owner
24
24
  attr_reader :size
25
- # If the pin belongs to a port then this will return the port object
26
- attr_accessor :port
27
25
  # Returns a hash containing the aliases associated with the given pin
28
26
  attr_reader :aliases
29
27
  # Returns a hash containing the functions associated with the given pin
@@ -273,7 +271,6 @@ module Origen
273
271
  group.include?(self)
274
272
  end
275
273
  end
276
- alias_method :ports, :groups
277
274
  alias_method :pin_groups, :groups
278
275
 
279
276
  def invalidate_group_cache
@@ -453,18 +450,17 @@ module Origen
453
450
  end
454
451
  end
455
452
 
456
- # Returns true if the pin belongs to a port.
453
+ # Returns true if the pin belongs to a pin group.
457
454
  #
458
- # add_port :jtag, :size => 6
455
+ # add_pins :jtag, size: 6
459
456
  # add_pin :done
460
- # add_pin_alias :fail, :jtag, :pin => 4
457
+ # add_pin_alias :fail, :jtag, pin: 4
461
458
  #
462
- # pin(:done).belongs_to_a_port? # => false
463
- # pin(:fail).belongs_to_a_port? # => true
464
- def belongs_to_a_port?
459
+ # pin(:done).belongs_to_a_pin_group? # => false
460
+ # pin(:fail).belongs_to_a_pin_group? # => true
461
+ def belongs_to_a_pin_group?
465
462
  !groups.empty?
466
463
  end
467
- alias_method :belongs_to_a_pin_group?, :belongs_to_a_port?
468
464
 
469
465
  def value
470
466
  @value
@@ -402,7 +402,7 @@ module Origen
402
402
  all?(&:repeat_previous?)
403
403
  end
404
404
 
405
- # Returns true if the (data) from the port is marked to be captured
405
+ # Returns true if the (data) from the pin collection is marked to be captured
406
406
  def to_be_captured?
407
407
  all?(&:to_be_captured?)
408
408
  end
@@ -0,0 +1,66 @@
1
+ module Origen
2
+ module Ports
3
+ autoload :Port, 'origen/ports/port'
4
+ autoload :Section, 'origen/ports/section'
5
+ autoload :BitCollection, 'origen/ports/bit_collection'
6
+ autoload :PortCollection, 'origen/ports/port_collection'
7
+
8
+ def add_port(name, options = {})
9
+ p = Port.new(self, name, options)
10
+ if block_given?
11
+ p.send(:defining) do
12
+ yield p
13
+ end
14
+ end
15
+ _ports.add(name.to_s.symbolize, p)
16
+ p
17
+ end
18
+
19
+ def port(*args, &block)
20
+ if block_given?
21
+ add_port(*args, &block)
22
+ else
23
+ if args.first
24
+ if has_port?(args.first)
25
+ _ports[args.first.to_s.symbolize]
26
+ else
27
+ if initialized?
28
+ puts "Model #{self.class} does not have a port named #{args.first}, the available ports are:"
29
+ puts _ports.keys
30
+ puts
31
+ fail 'Missing port error'
32
+ else
33
+ # Assume this is a pin definition while the model is still initializing
34
+ add_port(*args)
35
+ end
36
+ end
37
+ else
38
+ _ports
39
+ end
40
+ end
41
+ end
42
+ alias_method :ports, :port
43
+
44
+ def has_port?(name)
45
+ _ports.key?(name.to_s.symbolize)
46
+ end
47
+
48
+ def method_missing(method, *args, &block)
49
+ if _ports.key?(method.to_s.symbolize)
50
+ _ports[method.to_s.symbolize]
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def respond_to?(sym)
57
+ has_port?(sym) || super(sym)
58
+ end
59
+
60
+ private
61
+
62
+ def _ports
63
+ @_ports ||= PortCollection.new
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,6 @@
1
+ module Origen
2
+ module Ports
3
+ class BitCollection < Registers::BitCollection
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,129 @@
1
+ module Origen
2
+ module Ports
3
+ class Port
4
+ include Netlist::Connectable
5
+
6
+ attr_reader :size
7
+ attr_reader :parent
8
+ attr_reader :id
9
+ attr_reader :type
10
+
11
+ alias_method :name, :id
12
+ alias_method :owner, :parent
13
+
14
+ def initialize(parent, id, options = {})
15
+ @size = options[:size] || 1
16
+ @parent = parent
17
+ @id = id
18
+ @type = options[:type]
19
+ @bit_names = {}.with_indifferent_access
20
+ end
21
+
22
+ def inspect
23
+ "<#{self.class}:#{object_id} id:#{id} path:#{path}>"
24
+ end
25
+
26
+ def describe(options = {})
27
+ desc = ['********************']
28
+ desc << "Port id: #{id}"
29
+ desc << "Port path: #{path}"
30
+ desc << ''
31
+ desc << 'Connections'
32
+ desc << '-----------'
33
+ desc << ''
34
+ table = netlist.table
35
+ ((size - 1)..0).to_a.each do |i|
36
+ if table[path]
37
+ c = [table[path]['*'], table[path][i]].flatten.compact.map { |n| n.is_a?(Proc) ? 'Proc' : n }
38
+ desc << "#{i} - #{c.shift}"
39
+ c.each do |n|
40
+ desc << " - #{n}"
41
+ end
42
+ else
43
+ desc << "#{i} - none"
44
+ end
45
+ end
46
+ desc << ''
47
+
48
+ if options[:return]
49
+ desc
50
+ else
51
+ puts desc.join("\n")
52
+ end
53
+ end
54
+
55
+ def path
56
+ if parent.path.empty?
57
+ id.to_s
58
+ else
59
+ "#{parent.path}.#{id}"
60
+ end
61
+ end
62
+
63
+ def bits(index, name, options = {})
64
+ if @defining
65
+ @bit_names[name] = index
66
+ else
67
+ fail 'Cannot add additional port bits once the port definition is complete'
68
+ end
69
+ end
70
+
71
+ def drive(value = nil, options = {})
72
+ value, options = nil, value if value.is_a?(Hash)
73
+ if options[:index]
74
+ if options[:index].is_a?(Fixnum)
75
+ drive_values[options[:index]] = value ? value[0] : nil
76
+ else
77
+ options[:index].to_a.each do |i|
78
+ drive_values[i] = value ? value[i] : nil
79
+ end
80
+ end
81
+ else
82
+ size.times do |i|
83
+ drive_values[i] = value ? value[i] : nil
84
+ end
85
+ end
86
+ @drive_value = value
87
+ end
88
+
89
+ def drive_values
90
+ @drive_values ||= Array.new(size)
91
+ end
92
+
93
+ def to_section
94
+ Section.new(self, (size - 1)..0)
95
+ end
96
+
97
+ def method_missing(method, *args, &block)
98
+ if @bit_names.key?(method)
99
+ Section.new(self, @bit_names[method])
100
+ elsif BitCollection.instance_methods.include?(method)
101
+ to_bc.send(method, *args, &block)
102
+ else
103
+ super
104
+ end
105
+ end
106
+
107
+ def respond_to?(*args)
108
+ @bit_names.key?(args.first) || super(*args) ||
109
+ BitCollection.instance_methods.include?(args.first)
110
+ end
111
+
112
+ def [](val)
113
+ Section.new(self, val)
114
+ end
115
+
116
+ def to_bc
117
+ to_section.to_bc
118
+ end
119
+
120
+ private
121
+
122
+ def defining
123
+ @defining = true
124
+ yield
125
+ @defining = false
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,19 @@
1
+ module Origen
2
+ module Ports
3
+ class PortCollection < ::Hash
4
+ def add(name, port)
5
+ self[name] = port
6
+ by_type[port.type] ||= []
7
+ by_type[port.type] << port
8
+ end
9
+
10
+ def by_type
11
+ @by_type ||= {}.with_indifferent_access
12
+ end
13
+
14
+ def inspect
15
+ map { |k, _v| k }.inspect
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,116 @@
1
+ module Origen
2
+ module Ports
3
+ class Section
4
+ include Netlist::Connectable
5
+
6
+ attr_reader :port
7
+ attr_reader :index
8
+
9
+ def initialize(port, index)
10
+ @port = port
11
+ @index = index
12
+ end
13
+
14
+ def size
15
+ size_of(index)
16
+ end
17
+
18
+ def path
19
+ if index.is_a?(Range)
20
+ port.path + "[#{index.first}:#{index.last}]"
21
+ else
22
+ port.path + "[#{index}]"
23
+ end
24
+ end
25
+
26
+ def parent
27
+ port.parent
28
+ end
29
+ alias_method :owner, :parent
30
+
31
+ def id
32
+ port.id
33
+ end
34
+
35
+ def drive(value = nil)
36
+ port.drive(value, index: index)
37
+ end
38
+
39
+ def drive_value
40
+ if size == 1
41
+ port.drive_values[index]
42
+ else
43
+ fail 'drive_value is only supported for a single bit port section'
44
+ end
45
+ end
46
+
47
+ def [](index)
48
+ Section.new(port, align_to_port(index))
49
+ end
50
+
51
+ def respond_to?(*args)
52
+ super(*args) || BitCollection.instance_methods.include?(args.first)
53
+ end
54
+
55
+ def method_missing(method, *args, &block)
56
+ if BitCollection.instance_methods.include?(method)
57
+ to_bc.send(method, *args, &block)
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ def to_bc
64
+ b = BitCollection.new(port, port.id)
65
+ indexes = index.respond_to?(:to_a) ? index.to_a : [index]
66
+ indexes.reverse_each do |i|
67
+ b << netlist.data_bit(port.path, i)
68
+ end
69
+ b
70
+ end
71
+
72
+ private
73
+
74
+ def size_of(index)
75
+ if index.is_a?(Range)
76
+ (index.first - index.last).abs + 1
77
+ else
78
+ 1
79
+ end
80
+ end
81
+
82
+ def align_to_port(val)
83
+ if val.is_a?(Range)
84
+ nlsb = lsb + val.last
85
+ nmsb = nlsb + size_of(val) - 1
86
+ out_of_range(val) if nmsb > msb
87
+ i = nmsb..nlsb
88
+ else
89
+ i = lsb + val
90
+ out_of_range(val) if i > msb
91
+ end
92
+ i
93
+ end
94
+
95
+ def out_of_range(val)
96
+ fail "Requested section index (#{val}) is out of range for a port section of size #{size}"
97
+ end
98
+
99
+ def msb
100
+ if index.is_a?(Range)
101
+ index.first
102
+ else
103
+ index
104
+ end
105
+ end
106
+
107
+ def lsb
108
+ if index.is_a?(Range)
109
+ index.last
110
+ else
111
+ index
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end