origen 0.5.7 → 0.5.8
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 +4 -4
- data/config/version.rb +1 -1
- data/helpers/guides.rb +1 -0
- data/lib/origen.rb +4 -0
- data/lib/origen/commands.rb +5 -0
- data/lib/origen/core_ext/numeric.rb +4 -0
- data/lib/origen/core_ext/range.rb +9 -0
- data/lib/origen/core_ext/string.rb +2 -1
- data/lib/origen/global_methods.rb +4 -0
- data/lib/origen/model.rb +28 -0
- data/lib/origen/model_initializer.rb +4 -0
- data/lib/origen/models.rb +6 -0
- data/lib/origen/models/mux.rb +26 -0
- data/lib/origen/models/scan_register.rb +74 -0
- data/lib/origen/netlist.rb +24 -0
- data/lib/origen/netlist/connectable.rb +18 -0
- data/lib/origen/netlist/list.rb +152 -0
- data/lib/origen/pins.rb +0 -71
- data/lib/origen/pins/pin.rb +6 -10
- data/lib/origen/pins/pin_collection.rb +1 -1
- data/lib/origen/ports.rb +66 -0
- data/lib/origen/ports/bit_collection.rb +6 -0
- data/lib/origen/ports/port.rb +129 -0
- data/lib/origen/ports/port_collection.rb +19 -0
- data/lib/origen/ports/section.rb +116 -0
- data/lib/origen/registers.rb +7 -1
- data/lib/origen/registers/bit.rb +8 -3
- data/lib/origen/registers/bit_collection.rb +57 -2
- data/lib/origen/registers/reg.rb +2 -2
- data/lib/origen/revision_control/design_sync.rb +47 -3
- data/lib/origen/sub_blocks.rb +12 -3
- data/lib/origen/undefined.rb +13 -0
- data/templates/nanoc/layouts/bootstrap.html.erb +8 -0
- metadata +16 -5
- data/lib/origen/pins/port.rb +0 -268
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
|
data/lib/origen/pins/pin.rb
CHANGED
@@ -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
|
453
|
+
# Returns true if the pin belongs to a pin group.
|
457
454
|
#
|
458
|
-
#
|
455
|
+
# add_pins :jtag, size: 6
|
459
456
|
# add_pin :done
|
460
|
-
# add_pin_alias :fail, :jtag, :
|
457
|
+
# add_pin_alias :fail, :jtag, pin: 4
|
461
458
|
#
|
462
|
-
# pin(:done).
|
463
|
-
# pin(:fail).
|
464
|
-
def
|
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
|
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
|
data/lib/origen/ports.rb
ADDED
@@ -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,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
|