Class: ISE::Symbol

Inherits:
XMLFile show all
Defined in:
lib/ise/symbol.rb

Overview

Class representing an ISE symbol file.

Constant Summary collapse

PIN_NAME_REGEX =
/^([A-Za-z0-9_]+)(\(([0-9]+)\:([0-9]+)\))?$/

Instance Attribute Summary

Attributes inherited from XMLFile

#filename

Instance Method Summary collapse

Methods inherited from XMLFile

#initialize, load, #save

Constructor Details

This class inherits a constructor from ISE::XMLFile

Instance Method Details

#each_attributeObject

Iterates over each attribute present in the given symbol.



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ise/symbol.rb', line 76

def each_attribute
  
  #If we weren't passed a block, return an enumerator referencing this function.
  return enum_for(:each_attribute) unless block_given?

  #Yield each of the known attributes in turn.
  @xml.css("symbol attr").each do |attr|
    yield attr.attribute('name').value, attr.attribute('value').value
  end

end

#each_pin(&block) ⇒ Object

Iterates over all of the I/O pins in the given design.



91
92
93
94
95
96
97
98
99
# File 'lib/ise/symbol.rb', line 91

def each_pin(&block)

  #If no block was provided, return an enumerator.
  return pins.to_enum unless block

  #Otherwise, iterate over the pins.
  pins.each(&block)

end

#each_pin_with_nameObject

Iterates over all of the I/O pins in the given design, providing their names as well as their node objects.



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ise/symbol.rb', line 106

def each_pin_with_name

  #If we weren't passed a block, return an enumerator referencing this function.
  return enum_for(:each_pin_with_name) unless block_given?

  #Otherwise, yield each pin with its name.
  each_pin do |pin|
    yield pin, get_pin_name(pin)
  end

end

#get_attribute(name) ⇒ Object Also known as: []

Gets the value of the provided Symbol attribute.



51
52
53
# File 'lib/ise/symbol.rb', line 51

def get_attribute(name)
  attribute_value_object(name).value
end

#get_pin_name(node) ⇒ Object

Returns the name of a given pin, given its node.



131
132
133
# File 'lib/ise/symbol.rb', line 131

def get_pin_name(node)
  node.attribute("name").value
end

#has_attribute?(name) ⇒ Boolean Also known as: include?

Returns a true-like value if the symbol has the given attribute.

Returns:

  • (Boolean)


43
44
45
# File 'lib/ise/symbol.rb', line 43

def has_attribute?(name)
  attribute_value_object(name)
end

#initialize_copy(source) ⇒ Object

Special constructor used for creating deep copies of this object. We use this to clone the inner XML AST.



35
36
37
38
# File 'lib/ise/symbol.rb', line 35

def initialize_copy(source)
  super
  @xml = @xml.clone
end

#nameObject

Get the name of the given schematic symbol; this also indicates which component this symbol is meant to wrap.



19
20
21
# File 'lib/ise/symbol.rb', line 19

def name
  @xml.css('symbol').attribute('name').value
end

#name=(new_name) ⇒ Object

Sets the name of the given schematic symbol; adjusting the name of the



27
28
29
# File 'lib/ise/symbol.rb', line 27

def name=(new_name)
  @xml.css('symbol').attribute('name').value = new_name
end

#pinsObject

Returns an array of I/O pins present on the given symbol.



69
70
71
# File 'lib/ise/symbol.rb', line 69

def pins
  @xml.css("symbol pin")
end

#rename_pins!Object

Renames each of the pins in the design according to a rule.

Requires a block, which should accept a pin name and provide the pin’s new name.



124
125
126
# File 'lib/ise/symbol.rb', line 124

def rename_pins!
  pins.each { set_pin_name(yield get_pin_name(pin)) }
end

#set_attribute(name, new_value) ⇒ Object Also known as: []=

Sets the value of the provided Symbol attribute.



58
59
60
# File 'lib/ise/symbol.rb', line 58

def set_attribute(name, new_value)
  attribute_value_object(name).value = new_value.to_s
end

#set_pin_bounds!(node, left, right) ⇒ Object

Adjusts the “bounds” of the given bus– its maximum and minimum pin numbers– in-place.

node: The node whose value should be adjusted. left: The left bound. This is typically higher than the right bound, but doesn’t have to be. right: The right bound.



163
164
165
166
167
168
169
170
171
# File 'lib/ise/symbol.rb', line 163

def set_pin_bounds!(node, left, right)
   
  #Extract the base name of the pin, removing any existing bounds.
  name, _, _ =  self.class.parse_pin_name(get_pin_name(node))

  #And adjust the pin's name to feature the new bounds.
  set_pin_name(node, "#{name}(#{left}:#{right})")

end

#set_pin_name(node, name) ⇒ Object

Sets name of the pin represented by the given node, updating all values



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/ise/symbol.rb', line 138

def set_pin_name(node, name)

  return unless node.name == "pin"

  #Change the name of any pin-label "text attributes" that reference the given pin.
  original_name = get_pin_name(node)

  #Retrieve a collection of all attributes that match the pin's original name...
  pin_labels = @xml.css("symbol graph attrtext[attrname=\"PinName\"][type=\"pin #{original_name}\"]")

  #And modify them so they now match the new node's name.
  pin_labels.each { |pin| pin.attribute('type').value = "pin #{name}" }

  #Finally, set the name of the node itself.
  node.attribute("name").value = name
  
end

#set_pin_width!(node, width) ⇒ Object

Adjusts the “bounds” of the given bus so the bus is of the provided width by modifying the bus’s upper bound. If the node is not a bus, it will be made into a bus whose right bound is 0.

node: The node to be modified. width: The width to apply.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/ise/symbol.rb', line 181

def set_pin_width!(node, width)

  #Get the components of the given bus' name.
  _, left, right = self.class.parse_pin_name(get_pin_name(node))

  #If the pin wasn't initially a bus, make it one.
  left  ||= 0
  right ||= 0

  #If our right bound is greater than our left one, adjust it.
  if right > left
    right = left + width - 1
  #Otherwise, adjust the left width.
  else
    left = right + width - 1
  end

  #Set the pin's bounds.
  set_pin_bounds!(node, left, right)

end